From 80b76e084751c4bf026b53d49aabad83c0644701 Mon Sep 17 00:00:00 2001 From: Karen Carias Date: Thu, 28 May 2015 16:48:12 +0000 Subject: [PATCH 01/51] added info about namespaces --- doc/api/groups.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/api/groups.md b/doc/api/groups.md index c903a850fd..0d493fe819 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -176,3 +176,17 @@ Parameters: - `id` (required) - The ID or path of a user group - `user_id` (required) - The ID of a group member + +## Namespaces in groups + +By default, groups only get 20 namespaces at a time because the API results are paginated. + +To get more (up to 100), pass the following as an argument to the API call +``` +per_page=100 +``` + +And to switch pages add +``` +page=2 +``` From 41469e5c5d4ba2d665be75678d0966b922896bdf Mon Sep 17 00:00:00 2001 From: Karen Carias Date: Thu, 28 May 2015 16:49:08 +0000 Subject: [PATCH 02/51] fixed namespaces info --- doc/api/groups.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/groups.md b/doc/api/groups.md index 0d493fe819..421b067865 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -181,12 +181,12 @@ Parameters: By default, groups only get 20 namespaces at a time because the API results are paginated. -To get more (up to 100), pass the following as an argument to the API call +To get more (up to 100), pass the following as an argument to the API call: ``` per_page=100 ``` -And to switch pages add +And to switch pages add: ``` page=2 -``` +``` \ No newline at end of file From 44458f3ca2d142a7d6088d627382f9dab5698f40 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 5 Jun 2015 14:37:01 +0200 Subject: [PATCH 03/51] Add "Remember me" checkbox to LDAP signin form. --- CHANGELOG | 1 + app/controllers/omniauth_callbacks_controller.rb | 2 +- app/views/devise/sessions/_new_ldap.html.haml | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 08b879a239..0ece39a78b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.12.0 (unreleased) + - Add "Remember me" checkbox to LDAP signin form. - Don't notify users mentioned in code blocks or blockquotes. - Omit link to generate labels if user does not have access to create them (Stan Hu) - Disable changing of the source branch in merge request update API (Stan Hu) diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index a767815b31..765adaf212 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -24,7 +24,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController @user = Gitlab::LDAP::User.new(oauth) @user.save if @user.changed? # will also save new users gl_user = @user.gl_user - gl_user.remember_me = true if @user.persisted? + gl_user.remember_me = params[:remember_me] if @user.persisted? # Do additional LDAP checks for the user filter and EE features if @user.allowed? diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml index 812e22373a..6ec741e488 100644 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ b/app/views/devise/sessions/_new_ldap.html.haml @@ -1,4 +1,9 @@ = form_tag(user_omniauth_callback_path(server['provider_name']), id: 'new_ldap_user' ) do = text_field_tag :username, nil, {class: "form-control top", placeholder: "#{server['label']} Login", autofocus: "autofocus"} = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} + - if devise_mapping.rememberable? + .remember-me.checkbox + %label{for: "remember_me"} + = check_box_tag :remember_me, '1', false, id: 'remember_me' + %span Remember me = button_tag "#{server['label']} Sign in", class: "btn-save btn" From c5555e9b21ff9e100b2cc3385017c38271666a8e Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Mon, 8 Jun 2015 14:45:24 +0200 Subject: [PATCH 04/51] set the release time --- doc/release/monthly.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index eb97f3cd7f..11ed205cab 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -71,7 +71,10 @@ Xth: (1 working day before the 22nd) - [ ] Update GitLab.com with the stable version (#LINK) - [ ] Update ci.gitLab.com with the stable version (#LINK) -22nd: +22nd before 12AM CET: + +Release before 12AM CET / 3AM PST, to make sure the majority of our users +get the new version on the 22nd. - [ ] Release CE, EE and CI (#LINK) From bcde45893b6b32471178febad49a49e2c8c63b49 Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Mon, 8 Jun 2015 16:23:37 +0200 Subject: [PATCH 05/51] update with suggestions --- doc/release/monthly.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index 11ed205cab..57d904ff38 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -74,9 +74,11 @@ Xth: (1 working day before the 22nd) 22nd before 12AM CET: Release before 12AM CET / 3AM PST, to make sure the majority of our users -get the new version on the 22nd. +get the new version on the 22nd and there is sufficient time in the European +workday to quickly fix any issues. - [ ] Release CE, EE and CI (#LINK) +- [ ] Schedule a second tweet of the release announcement at 6PM CET / 9AM PST ``` From b0de6e9ae27a6364819f47d13d827a8aa253c83e Mon Sep 17 00:00:00 2001 From: zenati Date: Tue, 9 Jun 2015 13:28:11 +0200 Subject: [PATCH 06/51] An `in_namespace` scope is already present --- app/controllers/admin/projects_controller.rb | 2 +- app/models/project.rb | 2 +- app/models/user.rb | 8 +++++--- app/services/search/global_service.rb | 2 +- lib/tasks/gitlab/cleanup.rake | 2 +- lib/tasks/gitlab/web_hook.rake | 4 ++-- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index ee449badf5..f616ccf568 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -5,7 +5,7 @@ class Admin::ProjectsController < Admin::ApplicationController def index @projects = Project.all - @projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present? + @projects = @projects.in_namespace(params[:namespace_id]) if params[:namespace_id].present? @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present? @projects = @projects.with_push if params[:with_push].present? @projects = @projects.abandoned if params[:abandoned].present? diff --git a/app/models/project.rb b/app/models/project.rb index 3c9f0dad28..b161cbe86b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -158,7 +158,7 @@ class Project < ActiveRecord::Base scope :without_user, ->(user) { where('projects.id NOT IN (:ids)', ids: user.authorized_projects.map(&:id) ) } scope :without_team, ->(team) { team.projects.present? ? where('projects.id NOT IN (:ids)', ids: team.projects.map(&:id)) : scoped } scope :not_in_group, ->(group) { where('projects.id NOT IN (:ids)', ids: group.project_ids ) } - scope :in_namespace, ->(namespace) { where(namespace_id: namespace.id) } + scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) } scope :in_group_namespace, -> { joins(:group) } scope :personal, ->(user) { where(namespace_id: user.namespace_id) } scope :joined, ->(user) { where('namespace_id != ?', user.namespace_id) } diff --git a/app/models/user.rb b/app/models/user.rb index 596dc7ea33..8be0b62270 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -352,9 +352,11 @@ class User < ActiveRecord::Base end def owned_projects - @owned_projects ||= begin - Project.where(namespace_id: owned_groups.pluck(:id).push(namespace.id)).joins(:namespace) - end + @owned_projects ||= + begin + namespace_ids = owned_groups.pluck(:id).push(namespace.id) + Project.in_namespace(namespace_ids).joins(:namespace) + end end # Team membership in authorized projects diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index 0bcc50c81a..e904cb6c6f 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -9,7 +9,7 @@ module Search def execute group = Group.find_by(id: params[:group_id]) if params[:group_id].present? projects = ProjectsFinder.new.execute(current_user) - projects = projects.where(namespace_id: group.id) if group + projects = projects.in_namespace(group.id) if group project_ids = projects.pluck(:id) Gitlab::SearchResults.new(project_ids, params[:search]) diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake index 3c9802a0be..d49cb6778f 100644 --- a/lib/tasks/gitlab/cleanup.rake +++ b/lib/tasks/gitlab/cleanup.rake @@ -51,7 +51,7 @@ namespace :gitlab do git_base_path = Gitlab.config.gitlab_shell.repos_path all_dirs = Dir.glob(git_base_path + '/*') - global_projects = Project.where(namespace_id: nil).pluck(:path) + global_projects = Project.in_namespace(nil).pluck(:path) puts git_base_path.yellow puts "Looking for global repos to remove... " diff --git a/lib/tasks/gitlab/web_hook.rake b/lib/tasks/gitlab/web_hook.rake index f9f586db93..412bcad122 100644 --- a/lib/tasks/gitlab/web_hook.rake +++ b/lib/tasks/gitlab/web_hook.rake @@ -51,11 +51,11 @@ namespace :gitlab do if namespace_path.blank? Project elsif namespace_path == '/' - Project.where(namespace_id: nil) + Project.in_namespace(nil) else namespace = Namespace.where(path: namespace_path).first if namespace - Project.where(namespace_id: namespace.id) + Project.in_namespace(namespace.id) else puts "Namespace not found: #{namespace_path}".red exit 2 From ebe4963871e4e2aa38b5b359af34d4f7062b7dfb Mon Sep 17 00:00:00 2001 From: Nicolas Date: Tue, 9 Jun 2015 01:12:38 +0200 Subject: [PATCH 07/51] Move Project Members link from Settings to main menu. Addresses #2278. --- .../projects/project_members_controller.rb | 2 -- app/helpers/tab_helper.rb | 2 +- app/views/layouts/nav/_project.html.haml | 7 +++++++ app/views/layouts/nav/_project_settings.html.haml | 5 ----- features/project/active_tab.feature | 12 +++++------- features/steps/shared/paths.rb | 4 ++++ features/steps/shared/project_tab.rb | 4 ++++ 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index b110de1101..b82b6f45d5 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -2,8 +2,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController # Authorize before_action :authorize_admin_project!, except: :leave - layout "project_settings" - def index @project_members = @project.project_members @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project) diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index a1d263d9d3..77727337f0 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -89,7 +89,7 @@ module TabHelper def project_tab_class return "active" if current_page?(controller: "/projects", action: :edit, id: @project) - if ['services', 'hooks', 'deploy_keys', 'project_members', 'protected_branches'].include? controller.controller_name + if ['services', 'hooks', 'deploy_keys', 'protected_branches'].include? controller.controller_name "active" end end diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 172f5197b2..cbcf560d0a 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -56,6 +56,13 @@ Merge Requests %span.count.merge_counter= @project.merge_requests.opened.count + - if project_nav_tab? :settings + = nav_link(controller: [:project_members, :teams]) do + = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab', data: {placement: 'right'} do + = icon('users fw') + %span + Members + - if project_nav_tab? :labels = nav_link(controller: :labels) do = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels', data: {placement: 'right'} do diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index 7dd14449de..1794712e1c 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -13,11 +13,6 @@ = icon('pencil-square-o') %span Project Settings - = nav_link(controller: [:project_members, :teams]) do - = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab', data: {placement: 'right'} do - = icon('users') - %span - Members = nav_link(controller: :deploy_keys) do = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys', data: {placement: 'right'} do = icon('key') diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index 05faad4e64..8661ea98c2 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -35,6 +35,11 @@ Feature: Project Active Tab Then the active main tab should be Merge Requests And no other main tabs should be active + Scenario: On Project Members + Given I visit my project's members page + Then the active main tab should be Members + And no other main tabs should be active + Scenario: On Project Wiki Given I visit my project's wiki page Then the active main tab should be Wiki @@ -49,13 +54,6 @@ Feature: Project Active Tab # Sub Tabs: Settings - Scenario: On Project Settings/Team - Given I visit my project's settings page - And I click the "Team" tab - Then the active sub nav should be Team - And no other sub navs should be active - And the active main tab should be Settings - Scenario: On Project Settings/Edit Given I visit my project's settings page And I click the "Edit" tab diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index d9401bd540..4649387680 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -227,6 +227,10 @@ module SharedPaths visit namespace_project_merge_requests_path(@project.namespace, @project) end + step "I visit my project's members page" do + visit namespace_project_project_members_path(@project.namespace, @project) + end + step "I visit my project's wiki page" do visit namespace_project_wiki_path(@project.namespace, @project, :home) end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index c5aed19331..71fe89f634 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -28,6 +28,10 @@ module SharedProjectTab ensure_active_main_tab('Issues') end + step 'the active main tab should be Members' do + ensure_active_main_tab('Members') + end + step 'the active main tab should be Merge Requests' do ensure_active_main_tab('Merge Requests') end From 25a870a6d40d87d8bb0de6734485fff23fa17c7f Mon Sep 17 00:00:00 2001 From: Jeroen van Baarsen Date: Tue, 9 Jun 2015 15:18:15 +0200 Subject: [PATCH 08/51] Revert "No need to check if `repository_ref` is present" --- lib/gitlab/project_search_results.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb index 581a8c20bd..0dab7bcfa4 100644 --- a/lib/gitlab/project_search_results.rb +++ b/lib/gitlab/project_search_results.rb @@ -4,7 +4,11 @@ module Gitlab def initialize(project_id, query, repository_ref = nil) @project = Project.find(project_id) - @repository_ref = repository_ref + @repository_ref = if repository_ref.present? + repository_ref + else + nil + end @query = Shellwords.shellescape(query) if query.present? end From bf7315cb13eab0cd1427efe29ce110a963b63c34 Mon Sep 17 00:00:00 2001 From: Jeroen Nijhof Date: Tue, 9 Jun 2015 17:56:37 +0200 Subject: [PATCH 09/51] update fog to 1.25.0 and add multipart upload support --- Gemfile | 2 +- Gemfile.lock | 82 +++++++++++++++++++++++++------ config/gitlab.yml.example | 4 ++ config/initializers/1_settings.rb | 1 + lib/backup/manager.rb | 3 +- 5 files changed, 75 insertions(+), 17 deletions(-) diff --git a/Gemfile b/Gemfile index 0c1fff0bc1..6b33d7c6fd 100644 --- a/Gemfile +++ b/Gemfile @@ -81,7 +81,7 @@ gem "carrierwave" gem 'dropzonejs-rails' # for aws storage -gem "fog", "~> 1.14" +gem "fog", "~> 1.25.0" gem "unf" # Authorization diff --git a/Gemfile.lock b/Gemfile.lock index 9d87de7d4e..3bd2d1a835 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + CFPropertyList (2.3.1) RedCloth (4.2.9) ace-rails-ap (2.0.1) actionmailer (4.1.9) @@ -163,7 +164,7 @@ GEM erubis (2.7.0) escape_utils (0.2.4) eventmachine (1.0.4) - excon (0.32.1) + excon (0.45.3) execjs (2.5.2) expression_parser (0.9.0) factory_girl (4.3.0) @@ -178,29 +179,69 @@ GEM fastercsv (1.5.5) ffaker (2.0.0) ffi (1.9.8) - fog (1.21.0) - fog-brightbox - fog-core (~> 1.21, >= 1.21.1) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.25.0) + fog-brightbox (~> 0.4) + fog-core (~> 1.25) fog-json + fog-profitbricks + fog-radosgw (>= 0.0.2) + fog-sakuracloud (>= 0.0.4) + fog-softlayer + fog-terremark + fog-vmfusion + fog-voxel + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) nokogiri (~> 1.5, >= 1.5.11) - fog-brightbox (0.0.1) - fog-core + opennebula + fog-brightbox (0.7.1) + fog-core (~> 1.22) fog-json - fog-core (1.21.1) + inflecto (~> 0.0.2) + fog-core (1.30.0) builder - excon (~> 0.32) - formatador (~> 0.2.0) + excon (~> 0.45) + formatador (~> 0.2) mime-types net-scp (~> 1.1) net-ssh (>= 2.1.3) - fog-json (1.0.0) - multi_json (~> 1.0) + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-profitbricks (0.0.3) + fog-core + fog-xml + nokogiri + fog-radosgw (0.0.4) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-sakuracloud (1.0.1) + fog-core + fog-json + fog-softlayer (0.4.6) + fog-core + fog-json + fog-terremark (0.1.0) + fog-core + fog-xml + fog-vmfusion (0.1.0) + fission + fog-core + fog-voxel (0.1.0) + fog-core + fog-xml + fog-xml (0.1.2) + fog-core + nokogiri (~> 1.5, >= 1.5.11) font-awesome-rails (4.2.0.0) railties (>= 3.2, < 5.0) foreman (0.63.0) dotenv (>= 0.7) thor (>= 0.13.6) - formatador (0.2.4) + formatador (0.2.5) gemnasium-gitlab-service (0.2.6) rugged (~> 0.21) gemojione (2.0.0) @@ -287,6 +328,8 @@ GEM i18n (0.7.0) ice_cube (0.11.1) ice_nine (0.10.0) + inflecto (0.0.2) + ipaddress (0.8.0) jquery-atwho-rails (1.0.1) jquery-rails (3.1.2) railties (>= 3.0, < 5.0) @@ -328,9 +371,9 @@ GEM multipart-post (1.2.0) mysql2 (0.3.16) net-ldap (0.11) - net-scp (1.1.2) + net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (2.8.0) + net-ssh (2.9.2) newrelic_rpm (3.9.4.245) nokogiri (1.6.6.2) mini_portile (~> 0.6.0) @@ -379,6 +422,10 @@ GEM omniauth-twitter (1.0.1) multi_json (~> 1.3) omniauth-oauth (~> 1.0) + opennebula (4.12.1) + json + nokogiri + rbvmomi org-ruby (0.9.12) rubypants (~> 0.2) orm_adapter (0.5.0) @@ -446,6 +493,10 @@ GEM rb-fsevent (0.9.4) rb-inotify (0.9.5) ffi (>= 0.5.0) + rbvmomi (1.8.2) + builder + nokogiri (>= 1.4.1) + trollop rdoc (3.12.2) json (~> 1.4) redcarpet (3.2.3) @@ -621,6 +672,7 @@ GEM multi_json (~> 1.7) twitter-stream (~> 0.1) tins (0.13.1) + trollop (2.1.2) turbolinks (2.5.3) coffee-rails twitter-stream (0.1.16) @@ -704,7 +756,7 @@ DEPENDENCIES enumerize factory_girl_rails ffaker (~> 2.0.0) - fog (~> 1.14) + fog (~> 1.25.0) font-awesome-rails (~> 4.2) foreman gemnasium-gitlab-service (~> 0.2) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 787b3ccfc5..220a898cd6 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -252,6 +252,10 @@ production: &base # aws_secret_access_key: 'secret123' # # The remote 'directory' to store your backups. For S3, this would be the bucket name. # remote_directory: 'my.s3.bucket' + # # Use multipart uploads when file size reaches 100MB, see + # # http://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html + # multipart_chunk_size: 104857600 + ## GitLab Shell settings gitlab_shell: diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 1bd14a3a89..c2c3c5bfde 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -174,6 +174,7 @@ Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'co if Settings.backup['upload']['connection'] Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }] end +Settings.backup['upload']['multipart_chunk_size'] ||= 104857600 # # Git diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index b69aebf9fe..b1596cc51b 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -46,7 +46,8 @@ module Backup connection = ::Fog::Storage.new(connection_settings) directory = connection.directories.get(remote_directory) - if directory.files.create(key: tar_file, body: File.open(tar_file), public: false) + if directory.files.create(key: tar_file, body: File.open(tar_file), public: false, + multipart_chunk_size: GitlabCi.config.backup.upload.multipart_chunk_size) $progress.puts "done".green else puts "uploading backup to #{remote_directory} failed".red From cd522f33092fcdaa155c76231ca70cd32031725d Mon Sep 17 00:00:00 2001 From: Jeroen Nijhof Date: Tue, 9 Jun 2015 17:59:08 +0200 Subject: [PATCH 10/51] remove extra space --- config/gitlab.yml.example | 1 - 1 file changed, 1 deletion(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 220a898cd6..f48c99fd90 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -256,7 +256,6 @@ production: &base # # http://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html # multipart_chunk_size: 104857600 - ## GitLab Shell settings gitlab_shell: path: /home/git/gitlab-shell/ From a7047569db3e04c29ea5cb24e9be2ac515855b90 Mon Sep 17 00:00:00 2001 From: Jeroen Nijhof Date: Tue, 9 Jun 2015 18:30:38 +0200 Subject: [PATCH 11/51] use gitlab not gitlabci --- lib/backup/manager.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index b1596cc51b..6fa2079d1a 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -47,7 +47,7 @@ module Backup directory = connection.directories.get(remote_directory) if directory.files.create(key: tar_file, body: File.open(tar_file), public: false, - multipart_chunk_size: GitlabCi.config.backup.upload.multipart_chunk_size) + multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size) $progress.puts "done".green else puts "uploading backup to #{remote_directory} failed".red From bbb4aa5317a75e5f89b6967a923dfdccfb29b037 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 9 Jun 2015 15:27:40 -0700 Subject: [PATCH 12/51] Update browser gem to version 0.8.0 for IE11 support Closes #1775 --- CHANGELOG | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4857682d02..c04b8f079a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.12.0 (unreleased) + - Update browser gem to version 0.8.0 for IE11 support (Stan Hu) - Fix timeout when rendering file with thousands of lines. - Add "Remember me" checkbox to LDAP signin form. - Don't notify users mentioned in code blocks or blockquotes. diff --git a/Gemfile b/Gemfile index 0c1fff0bc1..0d91de7e66 100644 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,7 @@ gem 'rqrcode-rails3' gem 'attr_encrypted', '1.3.4' # Browser detection -gem "browser" +gem "browser", '~> 0.8.0' # Extracting information from a git repository # Provide access to Gitlab::Git library diff --git a/Gemfile.lock b/Gemfile.lock index 9d87de7d4e..441fe69e8a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,7 +75,7 @@ GEM ruby_parser (~> 3.5.0) sass (~> 3.0) terminal-table (~> 1.4) - browser (0.7.2) + browser (0.8.0) builder (3.2.2) byebug (3.2.0) columnize (~> 0.8) @@ -680,7 +680,7 @@ DEPENDENCIES binding_of_caller bootstrap-sass (~> 3.0) brakeman - browser + browser (~> 0.8.0) byebug cal-heatmap-rails (~> 0.0.1) capybara (~> 2.2.1) From e34c1169a58dcb86cbba3c06ac1831c93a3f6978 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 10 Jun 2015 00:43:07 +0200 Subject: [PATCH 13/51] Fix alignment of Project Settings nav icons. --- app/views/layouts/nav/_project_settings.html.haml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/views/layouts/nav/_project_settings.html.haml b/app/views/layouts/nav/_project_settings.html.haml index 1794712e1c..633c6ae6bf 100644 --- a/app/views/layouts/nav/_project_settings.html.haml +++ b/app/views/layouts/nav/_project_settings.html.haml @@ -10,27 +10,27 @@ %ul.project-settings-nav.sidebar-subnav = nav_link(path: 'projects#edit') do = link_to edit_project_path(@project), title: 'Project', class: 'stat-tab tab', data: {placement: 'right'} do - = icon('pencil-square-o') + = icon('pencil-square-o fw') %span Project Settings = nav_link(controller: :deploy_keys) do = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys', data: {placement: 'right'} do - = icon('key') + = icon('key fw') %span Deploy Keys = nav_link(controller: :hooks) do = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Web Hooks', data: {placement: 'right'} do - = icon('link') + = icon('link fw') %span Web Hooks = nav_link(controller: :services) do = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services', data: {placement: 'right'} do - = icon('cogs') + = icon('cogs fw') %span Services = nav_link(controller: :protected_branches) do = link_to namespace_project_protected_branches_path(@project.namespace, @project), title: 'Protected Branches', data: {placement: 'right'} do - = icon('lock') + = icon('lock fw') %span Protected branches From fd9849ebba65283a9cf7695a83242dea52ff2c6e Mon Sep 17 00:00:00 2001 From: Karen Carias Date: Wed, 10 Jun 2015 03:19:40 +0000 Subject: [PATCH 14/51] fixed links --- doc/workflow/importing/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index 3cab541f95..86a8a62545 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -1,6 +1,6 @@ -# Migrating projects to a GitLab instance - -1. [Bitbucket](doc/workflow/import_projects_from_bitbucket.md) -2. [GitHub](doc/workflow/import_projects_from_github.md) -3. [GitLab.com](doc/workflow/import_projects_from_gitlab_com.md) -4. [SVN](doc/workflow/migrating_from_svn.md) +# Migrating projects to a GitLab instance + +1. [Bitbucket](workflow/import_projects_from_bitbucket.md) +2. [GitHub](workflow/import_projects_from_github.md) +3. [GitLab.com](workflow/import_projects_from_gitlab_com.md) +4. [SVN](workflow/migrating_from_svn.md) \ No newline at end of file From 07215f7f2adc3ab3196ee4b353c9da66de1acc0b Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 18 May 2015 16:39:15 -0400 Subject: [PATCH 15/51] Bump shoulda-matchers and webmock gem versions --- Gemfile | 6 +++--- Gemfile.lock | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Gemfile b/Gemfile index 0c1fff0bc1..c73fab4ed7 100644 --- a/Gemfile +++ b/Gemfile @@ -254,10 +254,10 @@ group :development, :test do end group :test do - gem "simplecov", require: false - gem "shoulda-matchers", "~> 2.7.0" + gem 'simplecov', require: false + gem 'shoulda-matchers', '~> 2.8.0' gem 'email_spec' - gem "webmock" + gem 'webmock', '~> 1.21.0' gem 'test_after_commit' end diff --git a/Gemfile.lock b/Gemfile.lock index 9d87de7d4e..6ba4cd9691 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -35,7 +35,7 @@ GEM tzinfo (~> 1.1) acts-as-taggable-on (3.5.0) activerecord (>= 3.2, < 5) - addressable (2.3.5) + addressable (2.3.8) annotate (2.6.0) activerecord (>= 2.3.0) rake (>= 0.8.7) @@ -118,8 +118,8 @@ GEM simplecov (>= 0.7) term-ansicolor thor - crack (0.4.1) - safe_yaml (~> 0.9.0) + crack (0.4.2) + safe_yaml (~> 1.0.0) creole (0.3.8) d3_rails (3.5.5) railties (>= 3.1.0) @@ -513,7 +513,7 @@ GEM rubypants (0.2.0) rugged (0.22.2) rugments (1.0.0.beta7) - safe_yaml (0.9.7) + safe_yaml (1.0.4) sanitize (2.1.0) nokogiri (>= 1.4.4) sass (3.2.19) @@ -535,7 +535,7 @@ GEM thor (~> 0.14) settingslogic (2.0.9) sexp_processor (4.4.5) - shoulda-matchers (2.7.0) + shoulda-matchers (2.8.0) activesupport (>= 3.0.0) sidekiq (3.3.0) celluloid (>= 0.16.0) @@ -652,8 +652,8 @@ GEM equalizer (~> 0.0.7) warden (1.2.3) rack (>= 1.0) - webmock (1.16.0) - addressable (>= 2.2.7) + webmock (1.21.0) + addressable (>= 2.3.6) crack (>= 0.3.2) websocket-driver (0.3.3) wikicloth (0.8.1) @@ -772,7 +772,7 @@ DEPENDENCIES seed-fu select2-rails settingslogic - shoulda-matchers (~> 2.7.0) + shoulda-matchers (~> 2.8.0) sidekiq (~> 3.3) sidetiq (= 0.6.3) simplecov @@ -801,5 +801,5 @@ DEPENDENCIES unicorn-worker-killer version_sorter virtus - webmock + webmock (~> 1.21.0) wikicloth (= 0.8.1) From 47251b85e06c84e9303ddbd06098ecc06c05d269 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 18 May 2015 16:40:10 -0400 Subject: [PATCH 16/51] ensure_length_of -> validate_length_of --- spec/models/concerns/issuable_spec.rb | 2 +- spec/models/key_spec.rb | 4 ++-- spec/models/project_spec.rb | 8 ++++---- spec/models/snippet_spec.rb | 4 ++-- spec/models/user_spec.rb | 2 +- spec/support/matchers.rb | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index 557c71b4d2..86c395a8e8 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -16,7 +16,7 @@ describe Issue, "Issuable" do it { is_expected.to validate_presence_of(:iid) } it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_at_least(0).is_at_most(255) } + it { is_expected.to validate_length_of(:title).is_at_least(0).is_at_most(255) } end describe "Scope" do diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 6eb1208a7f..fbb9e16295 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -26,8 +26,8 @@ describe Key do describe "Validation" do it { is_expected.to validate_presence_of(:title) } it { is_expected.to validate_presence_of(:key) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } - it { is_expected.to ensure_length_of(:key).is_within(0..5000) } + it { is_expected.to validate_length_of(:title).is_within(0..255) } + it { is_expected.to validate_length_of(:key).is_within(0..5000) } end describe "Methods" do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 48568e2a3f..87c67fa32c 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -69,14 +69,14 @@ describe Project do it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:name).is_within(0..255) } + it { is_expected.to validate_length_of(:name).is_within(0..255) } it { is_expected.to validate_presence_of(:path) } it { is_expected.to validate_uniqueness_of(:path).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:path).is_within(0..255) } - it { is_expected.to ensure_length_of(:description).is_within(0..2000) } + it { is_expected.to validate_length_of(:path).is_within(0..255) } + it { is_expected.to validate_length_of(:description).is_within(0..2000) } it { is_expected.to validate_presence_of(:creator) } - it { is_expected.to ensure_length_of(:issues_tracker_id).is_within(0..255) } + it { is_expected.to validate_length_of(:issues_tracker_id).is_within(0..255) } it { is_expected.to validate_presence_of(:namespace) } it 'should not allow new projects beyond user limits' do diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index c81dd36ef4..c786d0bf10 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -38,10 +38,10 @@ describe Snippet do it { is_expected.to validate_presence_of(:author) } it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } + it { is_expected.to validate_length_of(:title).is_within(0..255) } it { is_expected.to validate_presence_of(:file_name) } - it { is_expected.to ensure_length_of(:file_name).is_within(0..255) } + it { is_expected.to validate_length_of(:file_name).is_within(0..255) } it { is_expected.to validate_presence_of(:content) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index be0b70395d..f1b8afa585 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -96,7 +96,7 @@ describe User do it { is_expected.to allow_value(0).for(:projects_limit) } it { is_expected.not_to allow_value(-1).for(:projects_limit) } - it { is_expected.to ensure_length_of(:bio).is_within(0..255) } + it { is_expected.to validate_length_of(:bio).is_within(0..255) } describe 'email' do it 'accepts info@example.com' do diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 52b11bd632..f8cce2ea5a 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -70,7 +70,7 @@ end # Extend shoulda-matchers module Shoulda::Matchers::ActiveModel - class EnsureLengthOfMatcher + class ValidateLengthOfMatcher # Shortcut for is_at_least and is_at_most def is_within(range) is_at_least(range.min) && is_at_most(range.max) From 1c4604bff67f612d8c74be499891b04f51a7821a Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 18 May 2015 16:40:32 -0400 Subject: [PATCH 17/51] "expect { }.not_to raise_error" no longer takes a specific class --- spec/models/deploy_keys_project_spec.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb index 7032b77714..705ef257d8 100644 --- a/spec/models/deploy_keys_project_spec.rb +++ b/spec/models/deploy_keys_project_spec.rb @@ -36,9 +36,7 @@ describe DeployKeysProject do it "doesn't destroy the deploy key" do subject.destroy - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) + expect { deploy_key.reload }.not_to raise_error end end @@ -63,9 +61,7 @@ describe DeployKeysProject do it "doesn't destroy the deploy key" do subject.destroy - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) + expect { deploy_key.reload }.not_to raise_error end end end From 2f3ab0ab858f3343807716d5ef033f7a90112d51 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 21 May 2015 17:34:12 -0400 Subject: [PATCH 18/51] Define GITORIOUS_HOST only once --- lib/gitlab/gitorious_import.rb | 5 +++++ lib/gitlab/gitorious_import/client.rb | 2 -- lib/gitlab/gitorious_import/repository.rb | 2 -- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 lib/gitlab/gitorious_import.rb diff --git a/lib/gitlab/gitorious_import.rb b/lib/gitlab/gitorious_import.rb new file mode 100644 index 0000000000..8d0132a744 --- /dev/null +++ b/lib/gitlab/gitorious_import.rb @@ -0,0 +1,5 @@ +module Gitlab + module GitoriousImport + GITORIOUS_HOST = "https://gitorious.org" + end +end diff --git a/lib/gitlab/gitorious_import/client.rb b/lib/gitlab/gitorious_import/client.rb index 1fa89dba44..99fe5bdebf 100644 --- a/lib/gitlab/gitorious_import/client.rb +++ b/lib/gitlab/gitorious_import/client.rb @@ -1,7 +1,5 @@ module Gitlab module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - class Client attr_reader :repo_list diff --git a/lib/gitlab/gitorious_import/repository.rb b/lib/gitlab/gitorious_import/repository.rb index f702797dc6..c88f1ae358 100644 --- a/lib/gitlab/gitorious_import/repository.rb +++ b/lib/gitlab/gitorious_import/repository.rb @@ -1,7 +1,5 @@ module Gitlab module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - Repository = Struct.new(:full_name) do def id Digest::SHA1.hexdigest(full_name) From 57830201a9152b56ccf65a98275601617f44653d Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 21 May 2015 18:24:46 -0400 Subject: [PATCH 19/51] Add spec/support files for WebMock and test coverage --- spec/spec_helper.rb | 12 ------------ spec/support/coverage.rb | 8 ++++++++ spec/support/webmock.rb | 4 ++++ 3 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 spec/support/coverage.rb create mode 100644 spec/support/webmock.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8fe51cf4ad..8cd00bdb2f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,16 +1,6 @@ -if ENV['SIMPLECOV'] - require 'simplecov' -end - -if ENV['COVERALLS'] - require 'coveralls' - Coveralls.wear_merged! -end - ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' -require 'webmock/rspec' require 'email_spec' require 'sidekiq/testing/inline' @@ -18,8 +8,6 @@ require 'sidekiq/testing/inline' # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } -WebMock.disable_net_connect!(allow_localhost: true) - RSpec.configure do |config| config.use_transactional_fixtures = false config.use_instantiated_fixtures = false diff --git a/spec/support/coverage.rb b/spec/support/coverage.rb new file mode 100644 index 0000000000..a54bf03380 --- /dev/null +++ b/spec/support/coverage.rb @@ -0,0 +1,8 @@ +if ENV['SIMPLECOV'] + require 'simplecov' +end + +if ENV['COVERALLS'] + require 'coveralls' + Coveralls.wear_merged! +end diff --git a/spec/support/webmock.rb b/spec/support/webmock.rb new file mode 100644 index 0000000000..af2906b756 --- /dev/null +++ b/spec/support/webmock.rb @@ -0,0 +1,4 @@ +require 'webmock' +require 'webmock/rspec' + +WebMock.disable_net_connect!(allow_localhost: true) From 33df3ed384563b1e302e5a4f2186b156c35bafc5 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sat, 23 May 2015 18:38:44 -0400 Subject: [PATCH 20/51] Add `respond_to_missing?` for Commit and Repository As of Ruby 1.9, this is the correct way to handle `respond_to?` for methods implemented by `method_missing`. See https://robots.thoughtbot.com/always-define-respond-to-missing-when-overriding --- app/models/commit.rb | 6 ++---- app/models/repository.rb | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/models/commit.rb b/app/models/commit.rb index f02fe24054..9d72166162 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -172,10 +172,8 @@ class Commit @raw.send(m, *args, &block) end - def respond_to?(method) - return true if @raw.respond_to?(method) - - super + def respond_to_missing?(method, include_private = false) + @raw.respond_to?(method, include_private) || super end # Truncate sha to 8 characters diff --git a/app/models/repository.rb b/app/models/repository.rb index 1ca9701763..2c6347222a 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -163,10 +163,8 @@ class Repository end end - def respond_to?(method) - return true if raw_repository.respond_to?(method) - - super + def respond_to_missing?(method, include_private = false) + raw_repository.respond_to?(method, include_private) || super end def blob_at(sha, path) From 1f9a2ab7c9faf9b3a5fcc2a8ea695efee2314196 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 31 May 2015 23:03:19 -0400 Subject: [PATCH 21/51] Memoize result of JSON.parse in json_response This might see a minor speedup in test cases that call this method many times. --- spec/support/api_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb index ec9a326a1e..f63322776d 100644 --- a/spec/support/api_helpers.rb +++ b/spec/support/api_helpers.rb @@ -29,6 +29,6 @@ module ApiHelpers end def json_response - JSON.parse(response.body) + @_json_response ||= JSON.parse(response.body) end end From 700d4387ce3d57330ed76e6b8545f27996d99c5f Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 31 May 2015 23:38:07 -0400 Subject: [PATCH 22/51] Use stub_const to stub constants instead of redefining them They're called constants for a reason, after all. --- features/steps/project/commits/commits.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index c888e82e20..30d53333b7 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -69,14 +69,13 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I visit big commit page' do - Commit::DIFF_SAFE_FILES = 20 + stub_const('Commit::DIFF_SAFE_FILES', 20) visit namespace_project_commit_path(@project.namespace, @project, sample_big_commit.id) end step 'I see big commit warning' do page.should have_content sample_big_commit.message page.should have_content "Too many changes" - Commit::DIFF_SAFE_FILES = 100 end step 'I visit a commit with an image that changed' do From 11c611bc620519badeb4ce4a6bbb5d53ac96c207 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 10 Jun 2015 01:38:36 -0400 Subject: [PATCH 23/51] Fix shoulda-matchers require --- Gemfile | 2 +- spec/spec_helper.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index c73fab4ed7..642df54c17 100644 --- a/Gemfile +++ b/Gemfile @@ -255,7 +255,7 @@ end group :test do gem 'simplecov', require: false - gem 'shoulda-matchers', '~> 2.8.0' + gem 'shoulda-matchers', '~> 2.8.0', require: false gem 'email_spec' gem 'webmock', '~> 1.21.0' gem 'test_after_commit' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8cd00bdb2f..9c8004ab55 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,7 @@ ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' +require 'shoulda/matchers' require 'email_spec' require 'sidekiq/testing/inline' From 94cbf0091f44e879c02066aab7ec0a44eaeb14c3 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 10 Jun 2015 01:38:45 -0400 Subject: [PATCH 24/51] Fix taskable require --- app/models/concerns/taskable.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb index 33b4814d7e..660e58b876 100644 --- a/app/models/concerns/taskable.rb +++ b/app/models/concerns/taskable.rb @@ -1,4 +1,5 @@ require 'task_list' +require 'task_list/filter' # Contains functionality for objects that can have task lists in their # descriptions. Task list items can be added with Markdown like "* [x] Fix From 3620849018c64455d3f4aba478ec66e0a05d67ed Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 10 Jun 2015 17:01:06 +0200 Subject: [PATCH 25/51] Improve project edit form Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/edit.html.haml | 42 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index c09d794ef7..2765f63c6b 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -6,7 +6,7 @@ Project settings %hr .panel-body - = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f| + = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f| %fieldset .form-group.project_name_holder @@ -41,32 +41,40 @@ %legend Features: .form-group - = f.label :issues_enabled, "Issues", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :issues_enabled - %span.descr Lightweight issue tracking system for this project + = f.label :issues_enabled do + = f.check_box :issues_enabled + %strong Issues + %br + %span.descr Lightweight issue tracking system for this project .form-group - = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :merge_requests_enabled - %span.descr Submit changes to be merged upstream. + = f.label :merge_requests_enabled do + = f.check_box :merge_requests_enabled + %strong Merge Requests + %br + %span.descr Submit changes to be merged upstream. .form-group - = f.label :wiki_enabled, "Wiki", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :wiki_enabled - %span.descr Pages for project documentation + = f.label :wiki_enabled do + = f.check_box :wiki_enabled + %strong Wiki + %br + %span.descr Pages for project documentation .form-group - = f.label :snippets_enabled, "Snippets", class: 'control-label' - .col-sm-10 + .col-sm-offset-2.col-sm-10 .checkbox - = f.check_box :snippets_enabled - %span.descr Share code pastes with others out of git repository + = f.label :snippets_enabled do + = f.check_box :snippets_enabled + %strong Snippets + %br + %span.descr Share code pastes with others out of git repository %fieldset.features %legend From 41a21912c6dad7d376f19171edd34029626f20b5 Mon Sep 17 00:00:00 2001 From: Karen Carias Date: Wed, 10 Jun 2015 17:07:55 +0000 Subject: [PATCH 26/51] added links to API calls --- doc/api/groups.md | 382 +++++++++++++++++++++++----------------------- 1 file changed, 191 insertions(+), 191 deletions(-) diff --git a/doc/api/groups.md b/doc/api/groups.md index 421b067865..0b9f6406d8 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -1,192 +1,192 @@ -# Groups - -## List project groups - -Get a list of groups. (As user: my groups, as admin: all groups) - -``` -GET /groups -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -You can search for groups by name or path, see below. - -## Details of a group - -Get all details of a group. - -``` -GET /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a group - -## New group - -Creates a new project group. Available only for users who can create groups. - -``` -POST /groups -``` - -Parameters: - -- `name` (required) - The name of the group -- `path` (required) - The path of the group -- `description` (optional) - The group's description - -## Transfer project to group - -Transfer a project to the Group namespace. Available only for admin - -``` -POST /groups/:id/projects/:project_id -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `project_id` (required) - The ID of a project - -## Remove group - -Removes group with all projects inside. - -``` -DELETE /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group - -## Search for group - -Get all groups that match your string in their name or path. - -``` -GET /groups?search=foobar -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -## Group members - -**Group access levels** - -The group access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized: - -``` -GUEST = 10 -REPORTER = 20 -DEVELOPER = 30 -MASTER = 40 -OWNER = 50 -``` - -### List group members - -Get a list of group members viewable by the authenticated user. - -``` -GET /groups/:id/members -``` - -```json -[ - { - "id": 1, - "username": "raymond_smith", - "email": "ray@smith.org", - "name": "Raymond Smith", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - }, - { - "id": 2, - "username": "john_doe", - "email": "joh@doe.org", - "name": "John Doe", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - } -] -``` - -### Add group member - -Adds a user to the list of group members. - -``` -POST /groups/:id/members -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `user_id` (required) - The ID of a user to add -- `access_level` (required) - Project access level - -### Edit group team member - -Updates a group team member to a specified access level. - -``` -PUT /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID of a group -- `user_id` (required) - The ID of a group member -- `access_level` (required) - Project access level - -### Remove user team member - -Removes user from user team. - -``` -DELETE /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group -- `user_id` (required) - The ID of a group member - -## Namespaces in groups - -By default, groups only get 20 namespaces at a time because the API results are paginated. - -To get more (up to 100), pass the following as an argument to the API call: -``` -per_page=100 -``` - -And to switch pages add: -``` -page=2 +# Groups + +## List project groups + +Get a list of groups. (As user: my groups, as admin: all groups) + +``` +GET /groups +``` + +```json +[ + { + "id": 1, + "name": "Foobar Group", + "path": "foo-bar", + "description": "An interesting group" + } +] +``` + +You can search for groups by name or path, see below. + +## Details of a group + +Get all details of a group. + +``` +GET /groups/:id +``` + +Parameters: + +- `id` (required) - The ID or path of a group + +## New group + +Creates a new project group. Available only for users who can create groups. + +``` +POST /groups +``` + +Parameters: + +- `name` (required) - The name of the group +- `path` (required) - The path of the group +- `description` (optional) - The group's description + +## Transfer project to group + +Transfer a project to the Group namespace. Available only for admin + +``` +POST /groups/:id/projects/:project_id +``` + +Parameters: + +- `id` (required) - The ID or path of a group +- `project_id` (required) - The ID of a project + +## Remove group + +Removes group with all projects inside. + +``` +DELETE /groups/:id +``` + +Parameters: + +- `id` (required) - The ID or path of a user group + +## Search for group + +Get all groups that match your string in their name or path. + +``` +GET /groups?search=foobar +``` + +```json +[ + { + "id": 1, + "name": "Foobar Group", + "path": "foo-bar", + "description": "An interesting group" + } +] +``` + +## Group members + +**Group access levels** + +The group access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized: + +``` +GUEST = 10 +REPORTER = 20 +DEVELOPER = 30 +MASTER = 40 +OWNER = 50 +``` + +### List group members + +Get a list of group members viewable by the authenticated user. + +``` +GET /groups/:id/members +``` + +```json +[ + { + "id": 1, + "username": "raymond_smith", + "email": "ray@smith.org", + "name": "Raymond Smith", + "state": "active", + "created_at": "2012-10-22T14:13:35Z", + "access_level": 30 + }, + { + "id": 2, + "username": "john_doe", + "email": "joh@doe.org", + "name": "John Doe", + "state": "active", + "created_at": "2012-10-22T14:13:35Z", + "access_level": 30 + } +] +``` + +### Add group member + +Adds a user to the list of group members. + +``` +POST /groups/:id/members +``` + +Parameters: + +- `id` (required) - The ID or path of a group +- `user_id` (required) - The ID of a user to add +- `access_level` (required) - Project access level + +### Edit group team member + +Updates a group team member to a specified access level. + +``` +PUT /groups/:id/members/:user_id +``` + +Parameters: + +- `id` (required) - The ID of a group +- `user_id` (required) - The ID of a group member +- `access_level` (required) - Project access level + +### Remove user team member + +Removes user from user team. + +``` +DELETE /groups/:id/members/:user_id +``` + +Parameters: + +- `id` (required) - The ID or path of a user group +- `user_id` (required) - The ID of a group member + +## Namespaces in groups + +By default, groups only get 20 namespaces at a time because the API results are paginated. + +To get more (up to 100), pass the following as an argument to the API call: +``` +/groups?per_page=100 +``` + +And to switch pages add: +``` +/groups?per_page=100&page=2 ``` \ No newline at end of file From e26eb1e162007a3297f4b58d6166c971c6c5bbd3 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 10 Jun 2015 16:31:06 -0400 Subject: [PATCH 27/51] Update grids for 2FA details Also adds a link to the documentation. --- app/views/profiles/two_factor_auths/new.html.haml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/views/profiles/two_factor_auths/new.html.haml b/app/views/profiles/two_factor_auths/new.html.haml index b9f3e2380f..74268c9bde 100644 --- a/app/views/profiles/two_factor_auths/new.html.haml +++ b/app/views/profiles/two_factor_auths/new.html.haml @@ -2,8 +2,10 @@ %h2.page-title Two-Factor Authentication (2FA) %p - Download the Google Authenticator application from App Store for iOS or - Google Play for Android and scan this code. + Download the Google Authenticator application from App Store for iOS or Google + Play for Android and scan this code. + + More information is available in the #{link_to('documentation', help_page_path('workflow', 'two_factor_authentication'))}. %hr @@ -12,10 +14,9 @@ .alert.alert-danger = @error .form-group - .col-sm-2 - .col-sm-2 + .col-lg-2.col-lg-offset-2 = raw @qr_code - .col-sm-8.manual-instructions + .col-lg-7.col-lg-offset-1.manual-instructions %h3 Can't scan the code? %p @@ -33,7 +34,7 @@ %dd Yes .form-group = label_tag :pin_code, nil, class: "control-label" - .col-sm-10 + .col-lg-10 = text_field_tag :pin_code, nil, class: "form-control", required: true, autofocus: true .form-actions = submit_tag 'Submit', class: 'btn btn-success' From 42ca87ebf72a08e3877cbc7c1e670f603f2d68fe Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 10 Jun 2015 16:34:51 -0400 Subject: [PATCH 28/51] Add negative tabindex to Markdown Write and Preview tabs Closes #1757 --- app/views/projects/_md_preview.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index a831481cf8..b7bca6dae0 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -2,10 +2,10 @@ .md-header.clearfix %ul.nav.nav-tabs %li.active - = link_to '#md-write-holder', class: 'js-md-write-button' do + = link_to '#md-write-holder', class: 'js-md-write-button', tabindex: '-1' do Write %li - = link_to '#md-preview-holder', class: 'js-md-preview-button' do + = link_to '#md-preview-holder', class: 'js-md-preview-button', tabindex: '-1' do Preview - if defined?(referenced_users) && referenced_users From fbdcaebcd1e0c2915676b8e2580bd9ef8eed9155 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 10 Jun 2015 17:11:04 -0400 Subject: [PATCH 29/51] Fix "Acount" typo in 2FA docs [ci skip] --- doc/workflow/two_factor_authentication.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/workflow/two_factor_authentication.md b/doc/workflow/two_factor_authentication.md index 7c45d23c99..fb215c8b26 100644 --- a/doc/workflow/two_factor_authentication.md +++ b/doc/workflow/two_factor_authentication.md @@ -45,7 +45,7 @@ storage in a safe place. **Each code can be used only once** to log in to your account. If you lose the recovery codes or just want to generate new ones, you can do so -from the **Profile Settings** > **Acount** page where you first enabled 2FA. +from the **Profile Settings** > **Account** page where you first enabled 2FA. ## Logging in with 2FA Enabled @@ -60,8 +60,8 @@ your phone's application or a recovery code to log in. 1. Log in to your GitLab account. 1. Go to your **Profile Settings**. -1. Go to **Acount**. +1. Go to **Account**. 1. Click **Disable Two-factor Authentication**. [Google Authenticator]: https://support.google.com/accounts/answer/1066447?hl=en -[FreeOTP]: https://fedorahosted.org/freeotp/ \ No newline at end of file +[FreeOTP]: https://fedorahosted.org/freeotp/ From a37ff6de8879ccbd7eec95654753f0458a3f465f Mon Sep 17 00:00:00 2001 From: Max Borghino Date: Wed, 10 Jun 2015 23:22:05 -0700 Subject: [PATCH 30/51] Update oauth button logos for Twitter and Google Both new buttons are 64x64 renders of the recommended assets from each company. Refs for those are: - https://about.twitter.com/press/twitter-brand-policy - https://developers.google.com/identity/branding-guidelines Addresses issue #544 --- CHANGELOG | 1 + app/assets/images/authbuttons/google_64.png | Bin 3169 -> 5281 bytes app/assets/images/authbuttons/twitter_64.png | Bin 3054 -> 4835 bytes 3 files changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index c04b8f079a..9d558b15ab 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 7.12.0 (unreleased) + - Update oauth button logos for Twitter and Google to recommended assets - Update browser gem to version 0.8.0 for IE11 support (Stan Hu) - Fix timeout when rendering file with thousands of lines. - Add "Remember me" checkbox to LDAP signin form. diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/authbuttons/google_64.png index 94a0e089c6efe07dcb50af341d51c2d13b689639..fb64f8bee686894a662e34162df0495800376404 100644 GIT binary patch literal 5281 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 nq}tt5QT00000NkvXXu0mjf`N+)T delta 3165 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 Dy8Q8B diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/authbuttons/twitter_64.png index 5c9f14cb0771005efaa2ed050560298aa03131b3..e3bd9169a343c5c005978060836ae98b9280e6bc 100644 GIT binary patch literal 4835 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 Date: Thu, 11 Jun 2015 09:40:26 +0200 Subject: [PATCH 31/51] Refactor accept merge request widget Signed-off-by: Dmitriy Zaporozhets --- app/models/merge_request.rb | 8 ++ .../projects/merge_requests/_show.html.haml | 2 +- .../merge_requests/show/_mr_accept.html.haml | 89 ------------------- .../merge_requests/show/_mr_ci.html.haml | 34 ------- .../show/_remove_source_branch.html.haml | 17 ---- .../show/_state_widget.html.haml | 50 ----------- .../merge_requests/widget/_closed.html.haml | 9 ++ .../merge_requests/widget/_heading.html.haml | 34 +++++++ .../merge_requests/widget/_locked.html.haml | 8 ++ .../merge_requests/widget/_merged.html.haml | 26 ++++++ .../widget/_mr_accept.html.haml | 20 +++++ .../merge_requests/widget/_open.html.haml | 29 ++++++ .../merge_requests/widget/_show.html.haml | 8 ++ .../widget/open/_accept.html.haml | 24 +++++ .../widget/open/_archived.html.haml | 2 + .../widget/open/_check.html.haml | 4 + .../widget/open/_conflict.html.haml | 5 ++ .../merge_requests/widget/open/_mip.html.haml | 5 ++ .../open/_missing_branch.html.haml} | 0 .../widget/open/_no_satellite.html.haml | 3 + .../widget/open/_not_allowed.html.haml | 9 ++ .../widget/open/_nothing.html.haml | 8 ++ .../merge_requests/widget/open/_wip.html.haml | 9 ++ 23 files changed, 212 insertions(+), 191 deletions(-) delete mode 100644 app/views/projects/merge_requests/show/_mr_accept.html.haml delete mode 100644 app/views/projects/merge_requests/show/_mr_ci.html.haml delete mode 100644 app/views/projects/merge_requests/show/_remove_source_branch.html.haml delete mode 100644 app/views/projects/merge_requests/show/_state_widget.html.haml create mode 100644 app/views/projects/merge_requests/widget/_closed.html.haml create mode 100644 app/views/projects/merge_requests/widget/_heading.html.haml create mode 100644 app/views/projects/merge_requests/widget/_locked.html.haml create mode 100644 app/views/projects/merge_requests/widget/_merged.html.haml create mode 100644 app/views/projects/merge_requests/widget/_mr_accept.html.haml create mode 100644 app/views/projects/merge_requests/widget/_open.html.haml create mode 100644 app/views/projects/merge_requests/widget/_show.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_accept.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_archived.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_check.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_conflict.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_mip.html.haml rename app/views/projects/merge_requests/{show/_no_accept.html.haml => widget/open/_missing_branch.html.haml} (100%) create mode 100644 app/views/projects/merge_requests/widget/open/_no_satellite.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_not_allowed.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_nothing.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_wip.html.haml diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index f1f9f23b12..665f88a364 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -405,4 +405,12 @@ class MergeRequest < ActiveRecord::Base locked_at.nil? || locked_at < (Time.now - 1.day) end + + def has_ci? + source_project.ci_service && commits.any? + end + + def branch_missing? + !source_branch_exists? || !target_branch_exists? + end end diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 74f8b9950c..02a9a53d9c 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -32,7 +32,7 @@ %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff) = render "projects/merge_requests/show/how_to_merge" - = render "projects/merge_requests/show/state_widget" + = render "projects/merge_requests/widget/show.html.haml" - if @commits.present? %ul.nav.nav-tabs.merge-request-tabs diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml deleted file mode 100644 index bfd4ab6f3d..0000000000 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ /dev/null @@ -1,89 +0,0 @@ -- unless @allowed_to_merge - - if @project.archived? - %p - %strong Archived projects do not provide commit access. - - else - .automerge_widget.cannot_be_merged.hide - %strong This merge request contains merge conflicts that must be resolved. - Only those with write access to this repository can merge merge requests. - .automerge_widget.work_in_progress.hide - %strong This merge request is marked as Work In Progress. - Only those with write access to this repository can merge merge requests. - .automerge_widget.can_be_merged.hide - %strong This request can be merged automatically. - Only those with write access to this repository can merge merge requests. - - -- if @show_merge_controls - .automerge_widget.can_be_merged.hide - .clearfix - = form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post do |f| - .accept-merge-holder.clearfix.js-toggle-container - .accept-action - = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" - - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? - .accept-control.checkbox - = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do - = check_box_tag :should_remove_source_branch - Remove source-branch - .accept-control - = link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do - %i.fa.fa-edit - Modify commit message - .js-toggle-content.hide.prepend-top-20 - = render 'shared/commit_message_container', params: params, - text: @merge_request.merge_commit_message, - rows: 14, hint: true - - %br - .light - If you want to merge this request manually, you can use the - %strong - = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - - - .automerge_widget.no_satellite.hide - %p - %span - %strong This repository does not have a satellite. Please ask an administrator to fix this issue! - - .automerge_widget.cannot_be_merged.hide - %h4 - This merge request contains merge conflicts that must be resolved. - You can try it manually on the - %strong - = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - - %p - %button.btn.disabled{:type => 'button'} - %i.fa.fa-warning - Accept Merge Request -   - This happens when Git is not able to automatically resolve conflicts between branches. - - .automerge_widget.work_in_progress.hide - %h4 - This merge request cannot be accepted because it is marked as Work In Progress. - - %p - %button.btn.disabled{:type => 'button'} - %i.fa.fa-warning - Accept Merge Request -   - When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted. - - .automerge_widget.unchecked - %p - %strong - %i.fa.fa-spinner.fa-spin - Checking automatic merge… - - .automerge_widget.already_cannot_be_merged.hide - %p - %strong This merge request cannot be merged. Try to reload the page. - - .merge-in-progress.hide - %p - %i.fa.fa-spinner.fa-spin -   - Merge is in progress. Please wait… Page will be reloaded automatically.   diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml deleted file mode 100644 index 3b1cd53df3..0000000000 --- a/app/views/projects/merge_requests/show/_mr_ci.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -- if @commits.any? - .ci_widget.ci-success{style: "display:none"} - = icon("check") - %span CI build passed - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - - .ci_widget.ci-failed{style: "display:none"} - = icon("times") - %span CI build failed - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - - [:running, :pending].each do |status| - .ci_widget{class: "ci-#{status}", style: "display:none"} - = icon("clock-o") - %span CI build #{status} - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - .ci_widget - = icon("spinner spin") - Checking for CI status for #{@merge_request.last_commit_short_sha} - - .ci_widget.ci-canceled{style: "display:none"} - = icon("times") - %span CI build canceled - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - .ci_widget.ci-error{style: "display:none"} - = icon("times") - %span Cannot connect to the CI server. Please check your settings and try again. diff --git a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml b/app/views/projects/merge_requests/show/_remove_source_branch.html.haml deleted file mode 100644 index 59cb85edfc..0000000000 --- a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- if @source_branch.blank? - Source branch has been removed - -- elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged? - .remove_source_branch_widget - %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now - = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do - %i.fa.fa-times - Remove Source Branch - - .remove_source_branch_widget.failed.hide - Failed to remove source branch '#{@merge_request.source_branch}' - - .remove_source_branch_in_progress.hide - %i.fa.fa-spinner.fa-spin -   - Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded.   diff --git a/app/views/projects/merge_requests/show/_state_widget.html.haml b/app/views/projects/merge_requests/show/_state_widget.html.haml deleted file mode 100644 index 6396232db2..0000000000 --- a/app/views/projects/merge_requests/show/_state_widget.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -.mr-state-widget - - if @merge_request.source_project.ci_service && @commits.any? - .mr-widget-heading - = render "projects/merge_requests/show/mr_ci" - .mr-widget-body - - if @merge_request.open? - - if @merge_request.source_branch_exists? && @merge_request.target_branch_exists? - = render "projects/merge_requests/show/mr_accept" - - else - = render "projects/merge_requests/show/no_accept" - - - if @merge_request.closed? - %h4 - Rejected - - if @merge_request.closed_event - by #{link_to_member(@project, @merge_request.closed_event.author, avatar: true)} - #{time_ago_with_tooltip(@merge_request.closed_event.created_at)} - %p Changes were not merged into target branch - - - if @merge_request.merged? - %h4 - Accepted - - if @merge_request.merge_event - by #{link_to_member(@project, @merge_request.merge_event.author, avatar: true)} - #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} - = render "projects/merge_requests/show/remove_source_branch" - - - if @merge_request.locked? - %h4 - Merge in progress... - %p - Merging is in progress. While merging this request is locked and cannot be closed. - - - unless @commits.any? - %h4 Nothing to merge - %p - Nothing to merge from - %span.label-branch #{@merge_request.source_branch} - to - %span.label-branch #{@merge_request.target_branch} - %br - Try to use different branches or push new code. - - - if @closes_issues.present? && @merge_request.open? - .mr-widget-footer - %span - %i.fa.fa-check - Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'} - = succeed '.' do - != gfm(issues_sentence(@closes_issues)) diff --git a/app/views/projects/merge_requests/widget/_closed.html.haml b/app/views/projects/merge_requests/widget/_closed.html.haml new file mode 100644 index 0000000000..3561eae032 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_closed.html.haml @@ -0,0 +1,9 @@ +.mr-state-widget + = render 'heading' + .mr-widget-body + %h4 + Rejected + - if @merge_request.closed_event + by #{link_to_member(@project, @merge_request.closed_event.author, avatar: true)} + #{time_ago_with_tooltip(@merge_request.closed_event.created_at)} + %p Changes were not merged into target branch diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml new file mode 100644 index 0000000000..a170782133 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -0,0 +1,34 @@ +- if @merge_request.has_ci? + .mr-widget-heading + .ci_widget.ci-success{style: "display:none"} + = icon("check") + %span CI build passed + for #{@merge_request.last_commit_short_sha}. + = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + + .ci_widget.ci-failed{style: "display:none"} + = icon("times") + %span CI build failed + for #{@merge_request.last_commit_short_sha}. + = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + + - [:running, :pending].each do |status| + .ci_widget{class: "ci-#{status}", style: "display:none"} + = icon("clock-o") + %span CI build #{status} + for #{@merge_request.last_commit_short_sha}. + = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + + .ci_widget + = icon("spinner spin") + Checking for CI status for #{@merge_request.last_commit_short_sha} + + .ci_widget.ci-canceled{style: "display:none"} + = icon("times") + %span CI build canceled + for #{@merge_request.last_commit_short_sha}. + = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" + + .ci_widget.ci-error{style: "display:none"} + = icon("times") + %span Cannot connect to the CI server. Please check your settings and try again. diff --git a/app/views/projects/merge_requests/widget/_locked.html.haml b/app/views/projects/merge_requests/widget/_locked.html.haml new file mode 100644 index 0000000000..67f841db52 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_locked.html.haml @@ -0,0 +1,8 @@ +.mr-state-widget + = render 'heading' + .mr-widget-body + %h4 + Merge in progress... + %p + Merging is in progress. While merging this request is locked and cannot be closed. + diff --git a/app/views/projects/merge_requests/widget/_merged.html.haml b/app/views/projects/merge_requests/widget/_merged.html.haml new file mode 100644 index 0000000000..bd1bc660b9 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_merged.html.haml @@ -0,0 +1,26 @@ +.mr-state-widget + = render 'heading' + .mr-widget-body + %h4 + Accepted + - if @merge_request.merge_event + by #{link_to_member(@project, @merge_request.merge_event.author, avatar: true)} + #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} + %div + - if @source_branch.blank? + Source branch has been removed + + - elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged? + .remove_source_branch_widget + %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now + = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do + %i.fa.fa-times + Remove Source Branch + + .remove_source_branch_widget.failed.hide + Failed to remove source branch '#{@merge_request.source_branch}' + + .remove_source_branch_in_progress.hide + %i.fa.fa-spinner.fa-spin +   + Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded.   diff --git a/app/views/projects/merge_requests/widget/_mr_accept.html.haml b/app/views/projects/merge_requests/widget/_mr_accept.html.haml new file mode 100644 index 0000000000..d3f7a09144 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_mr_accept.html.haml @@ -0,0 +1,20 @@ +- if @show_merge_controls + .automerge_widget.can_be_merged.hide + .clearfix + + .automerge_widget.cannot_be_merged.hide + + %p + %button.btn.disabled{:type => 'button'} + %i.fa.fa-warning + Accept Merge Request +   + This happens when Git is not able to automatically resolve conflicts between branches. + + + .automerge_widget.unchecked + + .automerge_widget.already_cannot_be_merged.hide + %p + %strong This merge request cannot be merged. Try to reload the page. + diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml new file mode 100644 index 0000000000..645ad6e9e4 --- /dev/null +++ b/app/views/projects/merge_requests/widget/_open.html.haml @@ -0,0 +1,29 @@ +.mr-state-widget + = render 'projects/merge_requests/widget/heading' + .mr-widget-body + - if @project.archived? + = render 'projects/merge_requests/widget/open/archived' + - elsif !@project.satellite.exists? + = render 'projects/merge_requests/widget/open/no_satellite' + - elsif @commits.blank? + = render 'projects/merge_requests/widget/open/nothing' + - elsif @merge_request.branch_missing? + = render 'projects/merge_requests/widget/open/missing_branch' + - elsif @merge_request.unchecked? + = render 'projects/merge_requests/widget/open/check' + - elsif @merge_request.cannot_be_merged? + = render 'projects/merge_requests/widget/open/conflicts' + - elsif @merge_request.work_in_progress? + = render 'projects/merge_requests/widget/open/wip' + - elsif !@allowed_to_merge + = render 'projects/merge_requests/widget/open/not_allowed' + - elsif @merge_request.can_be_merged? + = render 'projects/merge_requests/widget/open/accept' + + - if @closes_issues.present? + .mr-widget-footer + %span + %i.fa.fa-check + Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'} + = succeed '.' do + != gfm(issues_sentence(@closes_issues)) diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml new file mode 100644 index 0000000000..da936a54aa --- /dev/null +++ b/app/views/projects/merge_requests/widget/_show.html.haml @@ -0,0 +1,8 @@ +- if @merge_request.open? + = render 'projects/merge_requests/widget/open' +- elsif @merge_request.merged? + = render 'projects/merge_requests/widget/merged' +- elsif @merge_request.closed? + = render 'projects/merge_requests/widget/closed' +- elsif @merge_request.locked? + = render 'projects/merge_requests/widget/locked' diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml new file mode 100644 index 0000000000..aa14b0cf21 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -0,0 +1,24 @@ += form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post do |f| + .accept-merge-holder.clearfix.js-toggle-container + .accept-action + = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" + - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? + .accept-control.checkbox + = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do + = check_box_tag :should_remove_source_branch + Remove source-branch + .accept-control + = link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do + %i.fa.fa-edit + Modify commit message + .js-toggle-content.hide.prepend-top-20 + = render 'shared/commit_message_container', params: params, + text: @merge_request.merge_commit_message, + rows: 14, hint: true + + %br + .light + If you want to merge this request manually, you can use the + %strong + = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" + diff --git a/app/views/projects/merge_requests/widget/open/_archived.html.haml b/app/views/projects/merge_requests/widget/open/_archived.html.haml new file mode 100644 index 0000000000..eaf113ee56 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_archived.html.haml @@ -0,0 +1,2 @@ +%p + %strong Archived projects do not provide commit access. diff --git a/app/views/projects/merge_requests/widget/open/_check.html.haml b/app/views/projects/merge_requests/widget/open/_check.html.haml new file mode 100644 index 0000000000..95a5bcd03c --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_check.html.haml @@ -0,0 +1,4 @@ +%p + %strong + %i.fa.fa-spinner.fa-spin + Checking automatic merge… diff --git a/app/views/projects/merge_requests/widget/open/_conflict.html.haml b/app/views/projects/merge_requests/widget/open/_conflict.html.haml new file mode 100644 index 0000000000..3fc294bc0b --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_conflict.html.haml @@ -0,0 +1,5 @@ +%h4 + This merge request contains merge conflicts that must be resolved. + You can try it manually on the + %strong + = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" diff --git a/app/views/projects/merge_requests/widget/open/_mip.html.haml b/app/views/projects/merge_requests/widget/open/_mip.html.haml new file mode 100644 index 0000000000..d86aaff350 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_mip.html.haml @@ -0,0 +1,5 @@ +.merge-in-progress + %p + %i.fa.fa-spinner.fa-spin +   + Merge is in progress. Please wait… Page will be reloaded automatically.   diff --git a/app/views/projects/merge_requests/show/_no_accept.html.haml b/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml similarity index 100% rename from app/views/projects/merge_requests/show/_no_accept.html.haml rename to app/views/projects/merge_requests/widget/open/_missing_branch.html.haml diff --git a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml b/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml new file mode 100644 index 0000000000..3718cfd833 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml @@ -0,0 +1,3 @@ +%p + %span + %strong This repository does not have a satellite. Please ask an administrator to fix this issue! diff --git a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml new file mode 100644 index 0000000000..3989009c36 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml @@ -0,0 +1,9 @@ +.automerge_widget.cannot_be_merged.hide + %strong This merge request contains merge conflicts that must be resolved. + Only those with write access to this repository can merge merge requests. +.automerge_widget.work_in_progress.hide + %strong This merge request is marked as Work In Progress. + Only those with write access to this repository can merge merge requests. +.automerge_widget.can_be_merged.hide + %strong This request can be merged automatically. + Only those with write access to this repository can merge merge requests. diff --git a/app/views/projects/merge_requests/widget/open/_nothing.html.haml b/app/views/projects/merge_requests/widget/open/_nothing.html.haml new file mode 100644 index 0000000000..4d526576bc --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_nothing.html.haml @@ -0,0 +1,8 @@ +%h4 Nothing to merge +%p + Nothing to merge from + %span.label-branch #{@merge_request.source_branch} + to + %span.label-branch #{@merge_request.target_branch} + %br + Try to use different branches or push new code. diff --git a/app/views/projects/merge_requests/widget/open/_wip.html.haml b/app/views/projects/merge_requests/widget/open/_wip.html.haml new file mode 100644 index 0000000000..9268d68ba3 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_wip.html.haml @@ -0,0 +1,9 @@ +%h4 + This merge request cannot be accepted because it is marked as Work In Progress. + +%p + %button.btn.disabled{:type => 'button'} + %i.fa.fa-warning + Accept Merge Request +   + When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted. From 9a4886f0a0cde067dcc33bb4aa11ebbdd78cfeba Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Thu, 11 Jun 2015 14:45:48 +0200 Subject: [PATCH 32/51] move and fix links importing docs --- doc/workflow/importing/README.md | 8 ++++---- .../bitbucket_import_grant_access.jpg | Bin .../bitbucket_import_new_project.jpg | Bin .../bitbucket_import_select_bitbucket.jpg | Bin .../bitbucket_import_select_project.png | Bin .../{ => importing}/github_importer/importer.png | Bin .../github_importer/new_project_page.png | Bin .../{ => importing}/gitlab_importer/importer.png | Bin .../gitlab_importer/new_project_page.png | Bin .../import_projects_from_bitbucket.md | 0 .../{ => importing}/import_projects_from_github.md | 0 .../import_projects_from_gitlab_com.md | 0 doc/workflow/{ => importing}/migrating_from_svn.md | 0 13 files changed, 4 insertions(+), 4 deletions(-) rename doc/workflow/{ => importing}/bitbucket_importer/bitbucket_import_grant_access.jpg (100%) rename doc/workflow/{ => importing}/bitbucket_importer/bitbucket_import_new_project.jpg (100%) rename doc/workflow/{ => importing}/bitbucket_importer/bitbucket_import_select_bitbucket.jpg (100%) rename doc/workflow/{ => importing}/bitbucket_importer/bitbucket_import_select_project.png (100%) rename doc/workflow/{ => importing}/github_importer/importer.png (100%) rename doc/workflow/{ => importing}/github_importer/new_project_page.png (100%) rename doc/workflow/{ => importing}/gitlab_importer/importer.png (100%) rename doc/workflow/{ => importing}/gitlab_importer/new_project_page.png (100%) rename doc/workflow/{ => importing}/import_projects_from_bitbucket.md (100%) rename doc/workflow/{ => importing}/import_projects_from_github.md (100%) rename doc/workflow/{ => importing}/import_projects_from_gitlab_com.md (100%) rename doc/workflow/{ => importing}/migrating_from_svn.md (100%) diff --git a/doc/workflow/importing/README.md b/doc/workflow/importing/README.md index 86a8a62545..2b2e903742 100644 --- a/doc/workflow/importing/README.md +++ b/doc/workflow/importing/README.md @@ -1,6 +1,6 @@ # Migrating projects to a GitLab instance -1. [Bitbucket](workflow/import_projects_from_bitbucket.md) -2. [GitHub](workflow/import_projects_from_github.md) -3. [GitLab.com](workflow/import_projects_from_gitlab_com.md) -4. [SVN](workflow/migrating_from_svn.md) \ No newline at end of file +1. [Bitbucket](import_projects_from_bitbucket.md) +2. [GitHub](import_projects_from_github.md) +3. [GitLab.com](import_projects_from_gitlab_com.md) +4. [SVN](migrating_from_svn.md) diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_grant_access.jpg b/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.jpg similarity index 100% rename from doc/workflow/bitbucket_importer/bitbucket_import_grant_access.jpg rename to doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.jpg diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_new_project.jpg b/doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.jpg similarity index 100% rename from doc/workflow/bitbucket_importer/bitbucket_import_new_project.jpg rename to doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.jpg diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_select_bitbucket.jpg b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.jpg similarity index 100% rename from doc/workflow/bitbucket_importer/bitbucket_import_select_bitbucket.jpg rename to doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.jpg diff --git a/doc/workflow/bitbucket_importer/bitbucket_import_select_project.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png similarity index 100% rename from doc/workflow/bitbucket_importer/bitbucket_import_select_project.png rename to doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png diff --git a/doc/workflow/github_importer/importer.png b/doc/workflow/importing/github_importer/importer.png similarity index 100% rename from doc/workflow/github_importer/importer.png rename to doc/workflow/importing/github_importer/importer.png diff --git a/doc/workflow/github_importer/new_project_page.png b/doc/workflow/importing/github_importer/new_project_page.png similarity index 100% rename from doc/workflow/github_importer/new_project_page.png rename to doc/workflow/importing/github_importer/new_project_page.png diff --git a/doc/workflow/gitlab_importer/importer.png b/doc/workflow/importing/gitlab_importer/importer.png similarity index 100% rename from doc/workflow/gitlab_importer/importer.png rename to doc/workflow/importing/gitlab_importer/importer.png diff --git a/doc/workflow/gitlab_importer/new_project_page.png b/doc/workflow/importing/gitlab_importer/new_project_page.png similarity index 100% rename from doc/workflow/gitlab_importer/new_project_page.png rename to doc/workflow/importing/gitlab_importer/new_project_page.png diff --git a/doc/workflow/import_projects_from_bitbucket.md b/doc/workflow/importing/import_projects_from_bitbucket.md similarity index 100% rename from doc/workflow/import_projects_from_bitbucket.md rename to doc/workflow/importing/import_projects_from_bitbucket.md diff --git a/doc/workflow/import_projects_from_github.md b/doc/workflow/importing/import_projects_from_github.md similarity index 100% rename from doc/workflow/import_projects_from_github.md rename to doc/workflow/importing/import_projects_from_github.md diff --git a/doc/workflow/import_projects_from_gitlab_com.md b/doc/workflow/importing/import_projects_from_gitlab_com.md similarity index 100% rename from doc/workflow/import_projects_from_gitlab_com.md rename to doc/workflow/importing/import_projects_from_gitlab_com.md diff --git a/doc/workflow/migrating_from_svn.md b/doc/workflow/importing/migrating_from_svn.md similarity index 100% rename from doc/workflow/migrating_from_svn.md rename to doc/workflow/importing/migrating_from_svn.md From df346e9507a057ccb72d4edad53674ac014333a0 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 11 Jun 2015 15:11:37 +0200 Subject: [PATCH 33/51] Add a note that changing example configuration files requires changing omnibus-gitlab. --- config/aws.yml.example | 3 +++ config/gitlab.yml.example | 8 ++++++-- config/initializers/rack_attack.rb.example | 1 + config/initializers/smtp_settings.rb.sample | 1 + config/resque.yml.example | 3 +++ config/unicorn.rb.example | 3 +++ lib/support/nginx/gitlab | 8 +++++++- lib/support/nginx/gitlab-ssl | 8 +++++++- 8 files changed, 31 insertions(+), 4 deletions(-) diff --git a/config/aws.yml.example b/config/aws.yml.example index 29d029b078..bb10c3cec7 100644 --- a/config/aws.yml.example +++ b/config/aws.yml.example @@ -1,5 +1,8 @@ # See https://github.com/jnicklas/carrierwave#using-amazon-s3 # for more options +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# production: access_key_id: AKIA1111111111111UA secret_access_key: secret diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index f48c99fd90..96b6ed01f4 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -4,9 +4,13 @@ # ########################### NOTE ##################################### # This file should not receive new settings. All configuration options # -# are being moved to ApplicationSetting model! # +# that do not require application restart are being moved to # +# ApplicationSetting model! # +# If you change this file in a Merge Request, please also create # +# a MR on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests # ######################################################################## # +# # How to use: # 1. Copy file as gitlab.yml # 2. Update gitlab -> host with your fully qualified domain name @@ -149,7 +153,7 @@ production: &base allow_username_or_email_login: false # To maintain tight control over the number of active users on your GitLab installation, - # enable this setting to keep new users blocked until they have been cleared by the admin + # enable this setting to keep new users blocked until they have been cleared by the admin # (default: false). block_auto_created_users: false diff --git a/config/initializers/rack_attack.rb.example b/config/initializers/rack_attack.rb.example index 332865d288..b1bbcca1d6 100644 --- a/config/initializers/rack_attack.rb.example +++ b/config/initializers/rack_attack.rb.example @@ -1,6 +1,7 @@ # 1. Rename this file to rack_attack.rb # 2. Review the paths_to_be_protected and add any other path you need protecting # +# If you change this file in a Merge Request, please also create a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests paths_to_be_protected = [ "#{Rails.application.config.relative_url_root}/users/password", diff --git a/config/initializers/smtp_settings.rb.sample b/config/initializers/smtp_settings.rb.sample index f0fe2fdfa4..25ec247a09 100644 --- a/config/initializers/smtp_settings.rb.sample +++ b/config/initializers/smtp_settings.rb.sample @@ -5,6 +5,7 @@ # # For full list of options and their values see http://api.rubyonrails.org/classes/ActionMailer/Base.html # +# If you change this file in a Merge Request, please also create a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests if Rails.env.production? Gitlab::Application.config.action_mailer.delivery_method = :smtp diff --git a/config/resque.yml.example b/config/resque.yml.example index 347f3599b2..d98f43f71b 100644 --- a/config/resque.yml.example +++ b/config/resque.yml.example @@ -1,3 +1,6 @@ +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# development: redis://localhost:6379 test: redis://localhost:6379 production: unix:/var/run/redis/redis.sock diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example index 86a5512e76..b937b09278 100644 --- a/config/unicorn.rb.example +++ b/config/unicorn.rb.example @@ -8,6 +8,9 @@ # See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete # documentation. +# Note: If you change this file in a Merge Request, please also create a +# Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# # WARNING: See config/application.rb under "Relative url support" for the list of # other files that need to be changed for relative url support # diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index 62a4276536..4688a527eb 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -1,10 +1,16 @@ ## GitLab -## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller, DouweM ## ## Lines starting with two hashes (##) are comments with information. ## Lines starting with one hash (#) are configuration parameters that can be uncommented. ## ################################## +## CONTRIBUTING ## +################################## +## +## If you change this file in a Merge Request, please also create +## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +## +################################## ## CHUNKED TRANSFER ## ################################## ## diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 2aefc94469..187a27e93b 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -1,5 +1,4 @@ ## GitLab -## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller, DouweM ## ## Modified from nginx http version ## Modified from http://blog.phusion.nl/2012/04/21/tutorial-setting-up-gitlab-on-debian-6/ @@ -9,6 +8,13 @@ ## Lines starting with one hash (#) are configuration parameters that can be uncommented. ## ################################## +## CONTRIBUTING ## +################################## +## +## If you change this file in a Merge Request, please also create +## a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +## +################################## ## CHUNKED TRANSFER ## ################################## ## From 7872c7ff626186cab305d2b8449a587638c36baa Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Thu, 11 Jun 2015 15:12:47 +0200 Subject: [PATCH 34/51] fix and minify images --- .../bitbucket_import_grant_access.jpg | Bin 68856 -> 0 bytes .../bitbucket_import_grant_access.png | Bin 0 -> 30083 bytes .../bitbucket_import_new_project.jpg | Bin 24581 -> 0 bytes .../bitbucket_import_new_project.png | Bin 0 -> 16502 bytes .../bitbucket_import_select_bitbucket.jpg | Bin 90035 -> 0 bytes .../bitbucket_import_select_bitbucket.png | Bin 0 -> 46606 bytes .../bitbucket_import_select_project.png | Bin 62463 -> 16121 bytes .../import_projects_from_bitbucket.md | 8 ++++---- 8 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.jpg create mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png delete mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.jpg create mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_new_project.png delete mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.jpg create mode 100644 doc/workflow/importing/bitbucket_importer/bitbucket_import_select_bitbucket.png diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.jpg b/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.jpg deleted file mode 100644 index f3432e923c4a36640848615daec2b017b5f24ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68856 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≷u=ZH<& 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 z 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 diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_grant_access.png new file mode 100644 index 0000000000000000000000000000000000000000..df55a081803b646c89a09205c4fd16bf141788bd GIT binary patch literal 30083 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�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 NKSJGnCdZ!^{y!2G@CEMrkFan?Y%iF6r*>8fM;{ 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 E0sRnX_5c6? literal 0 HcmV?d00001 diff --git a/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png b/doc/workflow/importing/bitbucket_importer/bitbucket_import_select_project.png index 8312825eb18dedf77b33df4f1835050b7902328b..0e08703f4219067ceeee1510c47e03ddca0b1c3c 100644 GIT binary patch literal 16121 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 ersF5Yz4B{n*`&ChE~Ww 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 diff --git a/doc/workflow/importing/import_projects_from_bitbucket.md b/doc/workflow/importing/import_projects_from_bitbucket.md index 20d65f1925..1e9825e2e1 100644 --- a/doc/workflow/importing/import_projects_from_bitbucket.md +++ b/doc/workflow/importing/import_projects_from_bitbucket.md @@ -6,15 +6,15 @@ It takes just a few steps to import your existing Bitbucket projects to GitLab. * Click on "New project" -![New project in GitLab](bitbucket_importer/bitbucket_import_new_project.jpg) +![New project in GitLab](bitbucket_importer/bitbucket_import_new_project.png) * Click on the "Bitbucket" button -![Bitbucket](bitbucket_importer/bitbucket_import_select_bitbucket.jpg) +![Bitbucket](bitbucket_importer/bitbucket_import_select_bitbucket.png) * Grant GitLab access to your Bitbucket account -![Grant access](bitbucket_importer/bitbucket_import_grant_access.jpg) +![Grant access](bitbucket_importer/bitbucket_import_grant_access.png) * Click on the projects that you'd like to import or "Import all projects" @@ -23,4 +23,4 @@ It takes just a few steps to import your existing Bitbucket projects to GitLab. A new GitLab project will be created with your imported data. ### Note -Milestones and wiki pages are not imported from Bitbucket. \ No newline at end of file +Milestones and wiki pages are not imported from Bitbucket. From d2d8037b1abdbcc9bd6c23745479be60ebb57151 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 15:14:50 +0200 Subject: [PATCH 35/51] Refactor merge request widget step 2 Signed-off-by: Dmitriy Zaporozhets --- .../javascripts/merge_request.js.coffee | 27 +++---------------- .../stylesheets/pages/merge_requests.scss | 2 +- .../projects/merge_requests_controller.rb | 10 ++++++- .../projects/merge_requests/automerge.js.haml | 8 +++--- .../merge_requests/widget/_closed.html.haml | 2 +- .../merge_requests/widget/_heading.html.haml | 4 +++ .../merge_requests/widget/_locked.html.haml | 2 +- .../merge_requests/widget/_merged.html.haml | 2 +- .../widget/_mr_accept.html.haml | 20 -------------- .../merge_requests/widget/_open.html.haml | 2 +- .../widget/open/_accept.html.haml | 6 +++++ .../widget/open/_check.html.haml | 4 +++ .../widget/open/_conflict.html.haml | 5 ---- .../widget/open/_conflicts.html.haml | 9 +++++++ .../widget/open/_not_allowed.html.haml | 11 ++------ .../widget/open/_reload.html.haml | 1 + .../merge_requests/widget/open/_wip.html.haml | 20 ++++++++------ 17 files changed, 60 insertions(+), 75 deletions(-) delete mode 100644 app/views/projects/merge_requests/widget/_mr_accept.html.haml delete mode 100644 app/views/projects/merge_requests/widget/open/_conflict.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_conflicts.html.haml create mode 100644 app/views/projects/merge_requests/widget/open/_reload.html.haml diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index b8f916b522..5e440f3b1d 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -27,14 +27,11 @@ class @MergeRequest this.bindEvents() this.activateTabFromPath() - this.initMergeWidget() this.$('.show-all-commits').on 'click', => this.showAllCommits() modal = $('#modal_merge_info').modal(show: false) - disableButtonIfEmptyField '#commit_message', '.accept_merge_request' - # Prevent duplicate event bindings @disableTaskList() @@ -63,14 +60,11 @@ class @MergeRequest $(".context .inline-update").on "change", "#merge_request_assignee_id", -> $(this).submit() - initMergeWidget: -> - this.showState( @opts.current_status ) - - if this.$('.automerge_widget').length and @opts.check_enable - $.get @opts.url_to_automerge_check, (data) => - this.showState( data.merge_status ) - , 'json' + getMergeStatus: -> + $.get @opts.url_to_automerge_check, (data) -> + $('.mr-state-widget').replaceWith(data) + getCiStatus: -> if @opts.ci_enable $.get @opts.url_to_ci_check, (data) => this.showCiState data.status @@ -92,10 +86,6 @@ class @MergeRequest unless @opts.action == 'new' @setCurrentAction(tab_action) - this.$('.accept_merge_request').on 'click', -> - $('.automerge_widget.can_be_merged').hide() - $('.merge-in-progress').show() - this.$('.remove_source_branch').on 'click', -> $('.remove_source_branch_widget').hide() $('.remove_source_branch_in_progress').show() @@ -157,10 +147,6 @@ class @MergeRequest # See https://github.com/rails/turbolinks/issues/363 history.replaceState {turbolinks: true, url: new_state}, '', new_state - showState: (state) -> - $('.automerge_widget').hide() - $('.automerge_widget.' + state).show() - showCiState: (state) -> $('.ci_widget').hide() allowed_states = ["failed", "canceled", "running", "pending", "success"] @@ -198,11 +184,6 @@ class @MergeRequest this.$('.first-commits').remove() this.$('.all-commits').removeClass 'hide' - alreadyOrCannotBeMerged: -> - this.$('.automerge_widget').hide() - this.$('.merge-in-progress').hide() - this.$('.automerge_widget.already_cannot_be_merged').show() - setMergeButtonClass: (css_class) -> $('.accept_merge_request').removeClass("btn-create").addClass(css_class) diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index f5ac7bd880..6107132097 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -3,7 +3,7 @@ * MR -> show: Automerge widget * */ -.automerge_widget { +.mr-state-widget { form { margin-bottom: 0; .clearfix { diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 71d3051ab8..a7dfedf7f7 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -139,7 +139,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController @merge_request.check_if_can_be_merged end - render json: { merge_status: @merge_request.automerge_status } + @allowed_to_merge = allowed_to_merge? + closes_issues + + render partial: "projects/merge_requests/widget/show.html.haml", + layout: false end def automerge @@ -151,6 +155,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController else @status = false end + + respond_to do |format| + format.js + end end def branch_from diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/automerge.js.haml index a53cbb150a..26db408a57 100644 --- a/app/views/projects/merge_requests/automerge.js.haml +++ b/app/views/projects/merge_requests/automerge.js.haml @@ -1,6 +1,6 @@ --if @status +- if @status :plain - merge_request.mergeInProgress(); --else + merge_request.getMergeStatus(); +- else :plain - merge_request.alreadyOrCannotBeMerged() + $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/reload'))}"); diff --git a/app/views/projects/merge_requests/widget/_closed.html.haml b/app/views/projects/merge_requests/widget/_closed.html.haml index 3561eae032..18164ba771 100644 --- a/app/views/projects/merge_requests/widget/_closed.html.haml +++ b/app/views/projects/merge_requests/widget/_closed.html.haml @@ -1,5 +1,5 @@ .mr-state-widget - = render 'heading' + = render 'projects/merge_requests/widget/heading' .mr-widget-body %h4 Rejected diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index a170782133..0cbd88157c 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -32,3 +32,7 @@ .ci_widget.ci-error{style: "display:none"} = icon("times") %span Cannot connect to the CI server. Please check your settings and try again. + + :coffeescript + $ -> + merge_request.getCiStatus() diff --git a/app/views/projects/merge_requests/widget/_locked.html.haml b/app/views/projects/merge_requests/widget/_locked.html.haml index 67f841db52..13ec278847 100644 --- a/app/views/projects/merge_requests/widget/_locked.html.haml +++ b/app/views/projects/merge_requests/widget/_locked.html.haml @@ -1,5 +1,5 @@ .mr-state-widget - = render 'heading' + = render 'projects/merge_requests/widget/heading' .mr-widget-body %h4 Merge in progress... diff --git a/app/views/projects/merge_requests/widget/_merged.html.haml b/app/views/projects/merge_requests/widget/_merged.html.haml index bd1bc660b9..7fdeb3a96a 100644 --- a/app/views/projects/merge_requests/widget/_merged.html.haml +++ b/app/views/projects/merge_requests/widget/_merged.html.haml @@ -1,5 +1,5 @@ .mr-state-widget - = render 'heading' + = render 'projects/merge_requests/widget/heading' .mr-widget-body %h4 Accepted diff --git a/app/views/projects/merge_requests/widget/_mr_accept.html.haml b/app/views/projects/merge_requests/widget/_mr_accept.html.haml deleted file mode 100644 index d3f7a09144..0000000000 --- a/app/views/projects/merge_requests/widget/_mr_accept.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -- if @show_merge_controls - .automerge_widget.can_be_merged.hide - .clearfix - - .automerge_widget.cannot_be_merged.hide - - %p - %button.btn.disabled{:type => 'button'} - %i.fa.fa-warning - Accept Merge Request -   - This happens when Git is not able to automatically resolve conflicts between branches. - - - .automerge_widget.unchecked - - .automerge_widget.already_cannot_be_merged.hide - %p - %strong This merge request cannot be merged. Try to reload the page. - diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml index 645ad6e9e4..a9d8e3084c 100644 --- a/app/views/projects/merge_requests/widget/_open.html.haml +++ b/app/views/projects/merge_requests/widget/_open.html.haml @@ -5,7 +5,7 @@ = render 'projects/merge_requests/widget/open/archived' - elsif !@project.satellite.exists? = render 'projects/merge_requests/widget/open/no_satellite' - - elsif @commits.blank? + - elsif @merge_request.commits.blank? = render 'projects/merge_requests/widget/open/nothing' - elsif @merge_request.branch_missing? = render 'projects/merge_requests/widget/open/missing_branch' diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index aa14b0cf21..b2ea57126e 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -1,4 +1,5 @@ = form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post do |f| + = hidden_field_tag :authenticity_token, form_authenticity_token .accept-merge-holder.clearfix.js-toggle-container .accept-action = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" @@ -22,3 +23,8 @@ %strong = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" + :coffeescript + disableButtonIfEmptyField '#commit_message', '.accept_merge_request' + + $('.accept_merge_request').on 'click', -> + $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/mip'))}") diff --git a/app/views/projects/merge_requests/widget/open/_check.html.haml b/app/views/projects/merge_requests/widget/open/_check.html.haml index 95a5bcd03c..0ca54f3941 100644 --- a/app/views/projects/merge_requests/widget/open/_check.html.haml +++ b/app/views/projects/merge_requests/widget/open/_check.html.haml @@ -2,3 +2,7 @@ %strong %i.fa.fa-spinner.fa-spin Checking automatic merge… + +:coffeescript + $ -> + merge_request.getMergeStatus() diff --git a/app/views/projects/merge_requests/widget/open/_conflict.html.haml b/app/views/projects/merge_requests/widget/open/_conflict.html.haml deleted file mode 100644 index 3fc294bc0b..0000000000 --- a/app/views/projects/merge_requests/widget/open/_conflict.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%h4 - This merge request contains merge conflicts that must be resolved. - You can try it manually on the - %strong - = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" diff --git a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml new file mode 100644 index 0000000000..9e0c8a9e06 --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml @@ -0,0 +1,9 @@ +- if @allowed_to_merge + %h4 + This merge request contains merge conflicts that must be resolved. + You can try it manually on the + %strong + = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" +- else + %strong This merge request contains merge conflicts that must be resolved. + Only those with write access to this repository can merge merge requests. diff --git a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml index 3989009c36..82f6ffd8fc 100644 --- a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml +++ b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml @@ -1,9 +1,2 @@ -.automerge_widget.cannot_be_merged.hide - %strong This merge request contains merge conflicts that must be resolved. - Only those with write access to this repository can merge merge requests. -.automerge_widget.work_in_progress.hide - %strong This merge request is marked as Work In Progress. - Only those with write access to this repository can merge merge requests. -.automerge_widget.can_be_merged.hide - %strong This request can be merged automatically. - Only those with write access to this repository can merge merge requests. +%strong This request can be merged automatically. +Only those with write access to this repository can merge merge requests. diff --git a/app/views/projects/merge_requests/widget/open/_reload.html.haml b/app/views/projects/merge_requests/widget/open/_reload.html.haml new file mode 100644 index 0000000000..5787f6efea --- /dev/null +++ b/app/views/projects/merge_requests/widget/open/_reload.html.haml @@ -0,0 +1 @@ +This merge request cannot be merged. Try to reload the page. diff --git a/app/views/projects/merge_requests/widget/open/_wip.html.haml b/app/views/projects/merge_requests/widget/open/_wip.html.haml index 9268d68ba3..30482bce75 100644 --- a/app/views/projects/merge_requests/widget/open/_wip.html.haml +++ b/app/views/projects/merge_requests/widget/open/_wip.html.haml @@ -1,9 +1,13 @@ -%h4 - This merge request cannot be accepted because it is marked as Work In Progress. +- if @allowed_to_merge + %h4 + This merge request cannot be accepted because it is marked as Work In Progress. -%p - %button.btn.disabled{:type => 'button'} - %i.fa.fa-warning - Accept Merge Request -   - When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted. + %p + %button.btn.disabled{:type => 'button'} + %i.fa.fa-warning + Accept Merge Request +   + When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted. +- else + %strong This merge request is marked as Work In Progress. + Only those with write access to this repository can merge merge requests. From e77b20872e429439da0716d83e0f692733e4f4d0 Mon Sep 17 00:00:00 2001 From: Stefan Schweter Date: Thu, 11 Jun 2015 17:14:20 +0200 Subject: [PATCH 36/51] [Docker][Documentation] Uses new docker data image from Docker Hub (*sytse/gitlab-data*). Uniform tag name for data image is now *gitlab-data*. --- docker/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/README.md b/docker/README.md index 46b2134836..3edce5ef56 100644 --- a/docker/README.md +++ b/docker/README.md @@ -80,7 +80,7 @@ sudo docker pull sytse/gitlab-app:7.10.1 ```bash sudo docker run --name gitlab-data sytse/gitlab-data /bin/true -sudo docker run --detach --name gitlab_app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data sytse/gitlab-app:7.10.1 +sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab-data sytse/gitlab-app:7.10.1 ``` After this you can login to the web interface as explained above in 'After starting a container'. @@ -130,7 +130,7 @@ It Assumes that you're upgrading from 7.8.1 to 7.10.1 and you're in the updated sudo docker stop gitlab-app sudo docker rm gitlab-app sudo docker build --tag gitlab-app:7.10.1 docker/app/ -sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab-app:7.10.1 +sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab-data gitlab-app:7.10.1 ``` On the first run GitLab will reconfigure and update itself. If everything runs OK don't forget to cleanup the app image: @@ -143,13 +143,13 @@ sudo docker rmi gitlab-app:7.8.1 - Ensure the containers are running - Login to Dockerhub with `sudo docker login` -- Run the following (replace '7.9.2' with the version you're using and 'Sytse Sijbrandij' with your name): +- Run the following (replace '7.10.1' with the version you're using and 'Sytse Sijbrandij' with your name): ```bash sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab-app sytse/gitlab-app:7.10.1 sudo docker push sytse/gitlab-app:7.10.1 -sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab_data sytse/gitlab_data -sudo docker push sytse/gitlab_data +sudo docker commit -m "Initial commit" -a "Sytse Sijbrandij" gitlab-data sytse/gitlab-data +sudo docker push sytse/gitlab-data ``` ## Troubleshooting From e741edc2a482f5648105f4b5839e5824bd0cb565 Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 11 Jun 2015 16:17:30 +0000 Subject: [PATCH 37/51] Self build images require different build commands. --- docker/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 3edce5ef56..fb3bde5016 100644 --- a/docker/README.md +++ b/docker/README.md @@ -94,7 +94,12 @@ sudo docker build --tag gitlab-data docker/data/ sudo docker build --tag gitlab-app:7.10.1 docker/app/ ``` -After this run the images as described in the previous section. +After this run the images: + +```bash +sudo docker run --name gitlab-data gitlab-data /bin/true +sudo docker run --detach --name gitlab-app --publish 8080:80 --publish 2222:22 --volumes-from gitlab-data gitlab-app:7.10.1 +``` We assume using a data volume container, this will simplify migrations and backups. This empty container will exist to persist as volumes the 3 directories used by GitLab, so remember not to delete it. From 00600a592b006024ff102499fc3c9412f26e993e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 18:27:03 +0200 Subject: [PATCH 38/51] Extract merge request widget JS to separate class Signed-off-by: Dmitriy Zaporozhets --- .../javascripts/merge_request.js.coffee | 66 ------------------- .../merge_request_widget.js.coffee | 58 ++++++++++++++++ .../projects/merge_requests_controller.rb | 4 -- .../projects/merge_requests/_show.html.haml | 5 -- .../projects/merge_requests/automerge.js.haml | 2 +- .../merge_requests/widget/_heading.html.haml | 2 +- .../merge_requests/widget/_merged.html.haml | 15 +++++ .../merge_requests/widget/_show.html.haml | 12 ++++ .../widget/open/_accept.html.haml | 12 ++-- .../widget/open/_check.html.haml | 2 +- .../merge_requests/widget/open/_mip.html.haml | 5 -- 11 files changed, 96 insertions(+), 87 deletions(-) create mode 100644 app/assets/javascripts/merge_request_widget.js.coffee delete mode 100644 app/views/projects/merge_requests/widget/open/_mip.html.haml diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index 5e440f3b1d..25a7815dba 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -11,12 +11,6 @@ class @MergeRequest # commits_loaded - Boolean, have commits been pre-rendered server-side? # (default: false) # - # check_enable - Boolean, whether to check automerge status - # url_to_automerge_check - String, URL to use to check automerge status - # current_status - String, current automerge status - # ci_enable - Boolean, whether a CI service is enabled - # url_to_ci_check - String, URL to use to check CI status - # constructor: (@opts) -> @initContextWidget() this.$el = $('.merge-request') @@ -30,8 +24,6 @@ class @MergeRequest this.$('.show-all-commits').on 'click', => this.showAllCommits() - modal = $('#modal_merge_info').modal(show: false) - # Prevent duplicate event bindings @disableTaskList() @@ -60,17 +52,6 @@ class @MergeRequest $(".context .inline-update").on "change", "#merge_request_assignee_id", -> $(this).submit() - getMergeStatus: -> - $.get @opts.url_to_automerge_check, (data) -> - $('.mr-state-widget').replaceWith(data) - - getCiStatus: -> - if @opts.ci_enable - $.get @opts.url_to_ci_check, (data) => - this.showCiState data.status - if data.coverage - this.showCiCoverage data.coverage - , 'json' bindEvents: -> this.$('.merge-request-tabs a[data-toggle="tab"]').on 'shown.bs.tab', (e) => @@ -86,18 +67,6 @@ class @MergeRequest unless @opts.action == 'new' @setCurrentAction(tab_action) - this.$('.remove_source_branch').on 'click', -> - $('.remove_source_branch_widget').hide() - $('.remove_source_branch_in_progress').show() - - this.$(".remove_source_branch").on "ajax:success", (e, data, status, xhr) -> - location.reload() - - this.$(".remove_source_branch").on "ajax:error", (e, data, status, xhr) => - this.$('.remove_source_branch_widget').hide() - this.$('.remove_source_branch_in_progress').hide() - this.$('.remove_source_branch_widget.failed').show() - # Activate a tab based on the current URL path # # If the current action is 'show' or 'new' (i.e., initial page load), @@ -147,26 +116,6 @@ class @MergeRequest # See https://github.com/rails/turbolinks/issues/363 history.replaceState {turbolinks: true, url: new_state}, '', new_state - showCiState: (state) -> - $('.ci_widget').hide() - allowed_states = ["failed", "canceled", "running", "pending", "success"] - if state in allowed_states - $('.ci_widget.ci-' + state).show() - switch state - when "failed", "canceled" - @setMergeButtonClass('btn-danger') - when "running", "pending" - @setMergeButtonClass('btn-warning') - else - $('.ci_widget.ci-error').show() - @setMergeButtonClass('btn-danger') - - showCiCoverage: (coverage) -> - cov_html = $('') - cov_html.addClass('ci-coverage') - cov_html.text('Coverage ' + coverage + '%') - $('.ci_widget:visible').append(cov_html) - loadDiff: (event) -> $.ajax type: 'GET' @@ -184,21 +133,6 @@ class @MergeRequest this.$('.first-commits').remove() this.$('.all-commits').removeClass 'hide' - setMergeButtonClass: (css_class) -> - $('.accept_merge_request').removeClass("btn-create").addClass(css_class) - - mergeInProgress: -> - $.ajax - type: 'GET' - url: $('.merge-request').data('url') - success: (data) => - switch data.state - when 'merged' - location.reload() - else - setTimeout(merge_request.mergeInProgress, 3000) - dataType: 'json' - initTaskList: -> $('.merge-request-details .js-task-list-container').taskList('enable') $(document).on 'tasklist:changed', '.merge-request-details .js-task-list-container', @updateTaskList diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee new file mode 100644 index 0000000000..3ba38766ae --- /dev/null +++ b/app/assets/javascripts/merge_request_widget.js.coffee @@ -0,0 +1,58 @@ +class @MergeRequestWidget + # Initialize MergeRequestWidget behavior + # + # check_enable - Boolean, whether to check automerge status + # url_to_automerge_check - String, URL to use to check automerge status + # current_status - String, current automerge status + # ci_enable - Boolean, whether a CI service is enabled + # url_to_ci_check - String, URL to use to check CI status + # + constructor: (@opts) -> + modal = $('#modal_merge_info').modal(show: false) + + mergeInProgress: -> + $.ajax + type: 'GET' + url: $('.merge-request').data('url') + success: (data) => + switch data.state + when 'merged' + location.reload() + else + setTimeout(merge_request.mergeInProgress, 3000) + dataType: 'json' + + getMergeStatus: -> + $.get @opts.url_to_automerge_check, (data) -> + $('.mr-state-widget').replaceWith(data) + + getCiStatus: -> + if @opts.ci_enable + $.get @opts.url_to_ci_check, (data) => + this.showCiState data.status + if data.coverage + this.showCiCoverage data.coverage + , 'json' + + showCiState: (state) -> + $('.ci_widget').hide() + allowed_states = ["failed", "canceled", "running", "pending", "success"] + if state in allowed_states + $('.ci_widget.ci-' + state).show() + switch state + when "failed", "canceled" + @setMergeButtonClass('btn-danger') + when "running", "pending" + @setMergeButtonClass('btn-warning') + else + $('.ci_widget.ci-error').show() + @setMergeButtonClass('btn-danger') + + showCiCoverage: (coverage) -> + cov_html = $('') + cov_html.addClass('ci-coverage') + cov_html.text('Coverage ' + coverage + '%') + $('.ci_widget:visible').append(cov_html) + + setMergeButtonClass: (css_class) -> + $('.accept_merge_request').removeClass("btn-create").addClass(css_class) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index a7dfedf7f7..277a2ade2e 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -155,10 +155,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController else @status = false end - - respond_to do |format| - format.js - end end def branch_from diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 02a9a53d9c..5d7e73f2b2 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -69,10 +69,5 @@ var merge_request; merge_request = new MergeRequest({ - url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", - check_enable: #{@merge_request.unchecked? ? "true" : "false"}, - url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", - ci_enable: #{@project.ci_service ? "true" : "false"}, - current_status: "#{@merge_request.automerge_status}", action: "#{controller.action_name}" }); diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/automerge.js.haml index 26db408a57..33321651e3 100644 --- a/app/views/projects/merge_requests/automerge.js.haml +++ b/app/views/projects/merge_requests/automerge.js.haml @@ -1,6 +1,6 @@ - if @status :plain - merge_request.getMergeStatus(); + merge_request_widget.mergeInProgress(); - else :plain $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/reload'))}"); diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml index 0cbd88157c..107c61477e 100644 --- a/app/views/projects/merge_requests/widget/_heading.html.haml +++ b/app/views/projects/merge_requests/widget/_heading.html.haml @@ -35,4 +35,4 @@ :coffeescript $ -> - merge_request.getCiStatus() + merge_request_widget.getCiStatus() diff --git a/app/views/projects/merge_requests/widget/_merged.html.haml b/app/views/projects/merge_requests/widget/_merged.html.haml index 7fdeb3a96a..17c3fdacda 100644 --- a/app/views/projects/merge_requests/widget/_merged.html.haml +++ b/app/views/projects/merge_requests/widget/_merged.html.haml @@ -24,3 +24,18 @@ %i.fa.fa-spinner.fa-spin   Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded.   + + :coffeescript + $('.remove_source_branch').on 'click', -> + $('.remove_source_branch_widget').hide() + $('.remove_source_branch_in_progress').show() + + $(".remove_source_branch").on "ajax:success", (e, data, status, xhr) -> + location.reload() + + $(".remove_source_branch").on "ajax:error", (e, data, status, xhr) -> + $('.remove_source_branch_widget').hide() + $('.remove_source_branch_in_progress').hide() + $('.remove_source_branch_widget.failed').show() + + diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml index da936a54aa..263cab7a9e 100644 --- a/app/views/projects/merge_requests/widget/_show.html.haml +++ b/app/views/projects/merge_requests/widget/_show.html.haml @@ -6,3 +6,15 @@ = render 'projects/merge_requests/widget/closed' - elsif @merge_request.locked? = render 'projects/merge_requests/widget/locked' + +:javascript + var merge_request_widget; + + merge_request_widget = new MergeRequestWidget({ + url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", + check_enable: #{@merge_request.unchecked? ? "true" : "false"}, + url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", + ci_enable: #{@project.ci_service ? "true" : "false"}, + current_status: "#{@merge_request.automerge_status}", + }); + diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index b2ea57126e..41aa66dd76 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -1,8 +1,9 @@ -= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post do |f| += form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form' } do |f| = hidden_field_tag :authenticity_token, form_authenticity_token .accept-merge-holder.clearfix.js-toggle-container .accept-action - = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" + = f.button class: "btn btn-create accept_merge_request" do + Accept Merge Request - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? .accept-control.checkbox = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do @@ -26,5 +27,8 @@ :coffeescript disableButtonIfEmptyField '#commit_message', '.accept_merge_request' - $('.accept_merge_request').on 'click', -> - $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/mip'))}") + $('.accept-mr-form').on 'ajax:before', -> + btn = $('.accept_merge_request') + btn.disable() + btn.html(" Merge in progress") + diff --git a/app/views/projects/merge_requests/widget/open/_check.html.haml b/app/views/projects/merge_requests/widget/open/_check.html.haml index 0ca54f3941..5ca2d37a97 100644 --- a/app/views/projects/merge_requests/widget/open/_check.html.haml +++ b/app/views/projects/merge_requests/widget/open/_check.html.haml @@ -5,4 +5,4 @@ :coffeescript $ -> - merge_request.getMergeStatus() + merge_request_widget.getMergeStatus() diff --git a/app/views/projects/merge_requests/widget/open/_mip.html.haml b/app/views/projects/merge_requests/widget/open/_mip.html.haml deleted file mode 100644 index d86aaff350..0000000000 --- a/app/views/projects/merge_requests/widget/open/_mip.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.merge-in-progress - %p - %i.fa.fa-spinner.fa-spin -   - Merge is in progress. Please wait… Page will be reloaded automatically.   From 8893ac4ba407fdbacd85fa1b94d393b150ba5874 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 18:35:43 +0200 Subject: [PATCH 39/51] Fix rubocop Signed-off-by: Dmitriy Zaporozhets --- app/controllers/projects/merge_requests_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 277a2ade2e..3bb16f1b9f 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -142,8 +142,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController @allowed_to_merge = allowed_to_merge? closes_issues - render partial: "projects/merge_requests/widget/show.html.haml", - layout: false + render partial: "projects/merge_requests/widget/show.html.haml", layout: false end def automerge From 946b4ceda37fdb475b4176f466ef32470e6aeb1e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 18:45:12 +0200 Subject: [PATCH 40/51] Improve variables in mr widget Signed-off-by: Dmitriy Zaporozhets --- .../projects/merge_requests_controller.rb | 13 +------------ app/models/merge_request.rb | 4 ++++ .../projects/merge_requests/widget/_open.html.haml | 2 +- .../merge_requests/widget/open/_conflicts.html.haml | 2 +- .../merge_requests/widget/open/_wip.html.haml | 2 +- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 3bb16f1b9f..14069bafe7 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -139,14 +139,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController @merge_request.check_if_can_be_merged end - @allowed_to_merge = allowed_to_merge? closes_issues render partial: "projects/merge_requests/widget/show.html.haml", layout: false end def automerge - return access_denied! unless allowed_to_merge? + return access_denied! unless @merge_request.can_be_merged_by?(current_user) if @merge_request.automergeable? AutoMergeWorker.perform_async(@merge_request.id, current_user.id, params) @@ -255,8 +254,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController @commits = @merge_request.commits @merge_request_diff = @merge_request.merge_request_diff - @allowed_to_merge = allowed_to_merge? - @show_merge_controls = @merge_request.open? && @commits.any? && @allowed_to_merge @source_branch = @merge_request.source_project.repository.find_branch(@merge_request.source_branch).try(:name) if @merge_request.locked_long_ago? @@ -265,19 +262,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController end end - def allowed_to_merge? - allowed_to_push_code?(project, @merge_request.target_branch) - end - def invalid_mr # Render special view for MR with removed source or target branch render 'invalid' end - def allowed_to_push_code?(project, branch) - ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch) - end - def merge_request_params params.require(:merge_request).permit( :title, :assignee_id, :source_project_id, :source_branch, diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 665f88a364..487d62e65b 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -413,4 +413,8 @@ class MergeRequest < ActiveRecord::Base def branch_missing? !source_branch_exists? || !target_branch_exists? end + + def can_be_merged_by?(user) + ::Gitlab::GitAccess.new(user, project).can_push_to_branch?(target_branch) + end end diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml index a9d8e3084c..bb794912f8 100644 --- a/app/views/projects/merge_requests/widget/_open.html.haml +++ b/app/views/projects/merge_requests/widget/_open.html.haml @@ -15,7 +15,7 @@ = render 'projects/merge_requests/widget/open/conflicts' - elsif @merge_request.work_in_progress? = render 'projects/merge_requests/widget/open/wip' - - elsif !@allowed_to_merge + - elsif !@merge_request.can_be_merged_by?(current_user) = render 'projects/merge_requests/widget/open/not_allowed' - elsif @merge_request.can_be_merged? = render 'projects/merge_requests/widget/open/accept' diff --git a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml index 9e0c8a9e06..d1db5fec43 100644 --- a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml +++ b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml @@ -1,4 +1,4 @@ -- if @allowed_to_merge +- if @merge_request.can_be_merged_by?(current_user) %h4 This merge request contains merge conflicts that must be resolved. You can try it manually on the diff --git a/app/views/projects/merge_requests/widget/open/_wip.html.haml b/app/views/projects/merge_requests/widget/open/_wip.html.haml index 30482bce75..4ce3ab3127 100644 --- a/app/views/projects/merge_requests/widget/open/_wip.html.haml +++ b/app/views/projects/merge_requests/widget/open/_wip.html.haml @@ -1,4 +1,4 @@ -- if @allowed_to_merge +- if @merge_request.can_be_merged_by?(current_user) %h4 This merge request cannot be accepted because it is marked as Work In Progress. From 15cfa5ca206534f8ffeb6810768f30a21358a82d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 18:49:34 +0200 Subject: [PATCH 41/51] Fix automerge Signed-off-by: Dmitriy Zaporozhets --- app/assets/javascripts/merge_request_widget.js.coffee | 2 +- .../projects/merge_requests/widget/open/_check.html.haml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee index 3ba38766ae..ca769e06a4 100644 --- a/app/assets/javascripts/merge_request_widget.js.coffee +++ b/app/assets/javascripts/merge_request_widget.js.coffee @@ -19,7 +19,7 @@ class @MergeRequestWidget when 'merged' location.reload() else - setTimeout(merge_request.mergeInProgress, 3000) + setTimeout(merge_request_widget.mergeInProgress, 3000) dataType: 'json' getMergeStatus: -> diff --git a/app/views/projects/merge_requests/widget/open/_check.html.haml b/app/views/projects/merge_requests/widget/open/_check.html.haml index 5ca2d37a97..e775447cb7 100644 --- a/app/views/projects/merge_requests/widget/open/_check.html.haml +++ b/app/views/projects/merge_requests/widget/open/_check.html.haml @@ -1,7 +1,6 @@ -%p - %strong - %i.fa.fa-spinner.fa-spin - Checking automatic merge… +%strong + %i.fa.fa-spinner.fa-spin + Checking automatic merge… :coffeescript $ -> From a35aec7adb12d970a6b2dc40e5a47529e2bac63a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 22:27:26 +0200 Subject: [PATCH 42/51] Fix merge request test Signed-off-by: Dmitriy Zaporozhets --- features/steps/project/merge_requests.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 4ca7cf5e5f..d49e264ad1 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -198,7 +198,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps merge!: true, ) - within '.can_be_merged' do + within '.mr-state-widget' do click_button "Accept Merge Request" end end From f06f43804432465fc8a86ec628d07b66bda8d9c1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 22:52:21 +0200 Subject: [PATCH 43/51] Make commit calendar size depend on window size Signed-off-by: Dmitriy Zaporozhets --- app/assets/javascripts/calendar.js.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee index 44d75bd694..4c4bc3d66e 100644 --- a/app/assets/javascripts/calendar.js.coffee +++ b/app/assets/javascripts/calendar.js.coffee @@ -25,6 +25,7 @@ class @Calendar 30 ] legendCellPadding: 3 + cellSize: $('.user-calendar').width() / 80 onClick: (date, count) -> formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() $.ajax From aa38dfe9383bfa2bd3a55e18a2ec48b860daf26c Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 11 Jun 2015 23:00:38 +0200 Subject: [PATCH 44/51] Fix graph width on different screen sizes Signed-off-by: Dmitriy Zaporozhets --- .../javascripts/stat_graph_contributors_graph.js.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/stat_graph_contributors_graph.js.coffee index 0e6fbdef3b..b7a0e07376 100644 --- a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee +++ b/app/assets/javascripts/stat_graph_contributors_graph.js.coffee @@ -50,7 +50,7 @@ class @ContributorsGraph class @ContributorsMasterGraph extends ContributorsGraph constructor: (@data) -> - @width = $('.container').width() - 345 + @width = $('.content').width() - 70 @height = 200 @x = null @y = null @@ -123,7 +123,7 @@ class @ContributorsMasterGraph extends ContributorsGraph class @ContributorsAuthorGraph extends ContributorsGraph constructor: (@data) -> - @width = $('.container').width()/2 - 225 + @width = $('.content').width()/2 - 100 @height = 200 @x = null @y = null From 11bf5b693b6d1985b7bd2dd33b8f0df047aa4ec3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 12 Jun 2015 09:29:27 +0200 Subject: [PATCH 45/51] Fix test for accept merge request Signed-off-by: Dmitriy Zaporozhets --- features/steps/project/merge_requests.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index d49e264ad1..f6cfa7ef9e 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -190,6 +190,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'merge request "Bug NS-05" is mergeable' do + merge_request.project.satellite.create merge_request.mark_as_mergeable end From 69bbc413fec7aa4168d9ff12df5421674db90032 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 12 Jun 2015 00:44:13 -0400 Subject: [PATCH 46/51] Update all `should`-style syntax to `expect` in features --- features/steps/admin/applications.rb | 20 ++-- features/steps/admin/broadcast_messages.rb | 10 +- features/steps/admin/deploy_keys.rb | 6 +- features/steps/admin/groups.rb | 14 +-- features/steps/admin/logs.rb | 6 +- features/steps/admin/projects.rb | 12 +- features/steps/admin/settings.rb | 16 +-- features/steps/admin/users.rb | 26 ++--- features/steps/dashboard/archived_projects.rb | 6 +- features/steps/dashboard/dashboard.rb | 26 ++--- features/steps/dashboard/event_filters.rb | 12 +- features/steps/dashboard/group.rb | 20 ++-- features/steps/dashboard/help.rb | 2 +- features/steps/dashboard/issues.rb | 4 +- features/steps/dashboard/merge_requests.rb | 4 +- features/steps/dashboard/new_project.rb | 8 +- features/steps/dashboard/starred_projects.rb | 2 +- features/steps/explore/groups.rb | 12 +- features/steps/explore/projects.rb | 42 +++---- features/steps/groups.rb | 62 +++++----- features/steps/profile/emails.rb | 14 +-- features/steps/profile/notifications.rb | 2 +- features/steps/profile/profile.rb | 66 +++++------ features/steps/profile/ssh_keys.rb | 10 +- features/steps/project/archived.rb | 4 +- features/steps/project/commits/branches.rb | 18 +-- features/steps/project/commits/commits.rb | 50 ++++----- features/steps/project/commits/tags.rb | 16 +-- features/steps/project/commits/user_lookup.rb | 6 +- features/steps/project/create.rb | 20 ++-- features/steps/project/deploy_keys.rb | 12 +- features/steps/project/fork.rb | 8 +- .../steps/project/forked_merge_requests.rb | 82 +++++++------- features/steps/project/graph.rb | 6 +- features/steps/project/hooks.rb | 14 +-- .../steps/project/issues/filter_labels.rb | 8 +- features/steps/project/issues/issues.rb | 44 ++++---- features/steps/project/issues/labels.rb | 16 +-- features/steps/project/issues/milestones.rb | 14 +-- features/steps/project/merge_requests.rb | 64 +++++------ features/steps/project/network_graph.rb | 20 ++-- features/steps/project/project.rb | 32 +++--- features/steps/project/redirects.rb | 10 +- features/steps/project/services.rb | 66 +++++------ features/steps/project/snippets.rb | 14 +-- features/steps/project/source/browse_files.rb | 50 ++++----- features/steps/project/source/git_blame.rb | 6 +- .../steps/project/source/markdown_render.rb | 106 +++++++++--------- .../steps/project/source/multiselect_blob.rb | 4 +- features/steps/project/source/search_code.rb | 6 +- features/steps/project/star.rb | 4 +- features/steps/project/team_management.rb | 24 ++-- features/steps/project/wiki.rb | 50 ++++----- features/steps/search.rb | 10 +- features/steps/shared/active_tab.rb | 12 +- features/steps/shared/authentication.rb | 2 +- features/steps/shared/diff_note.rb | 18 +-- features/steps/shared/group.rb | 4 +- features/steps/shared/markdown.rb | 4 +- features/steps/shared/note.rb | 14 +-- features/steps/shared/paths.rb | 8 +- features/steps/shared/project.rb | 20 ++-- features/steps/shared/project_tab.rb | 2 +- features/steps/snippet_search.rb | 18 +-- features/steps/snippets/discover.rb | 6 +- features/steps/snippets/public_snippets.rb | 4 +- features/steps/snippets/snippets.rb | 10 +- features/steps/snippets/user.rb | 12 +- features/steps/user.rb | 4 +- 69 files changed, 662 insertions(+), 662 deletions(-) diff --git a/features/steps/admin/applications.rb b/features/steps/admin/applications.rb index d59088fa3c..e092a4b36c 100644 --- a/features/steps/admin/applications.rb +++ b/features/steps/admin/applications.rb @@ -8,7 +8,7 @@ class Spinach::Features::AdminApplications < Spinach::FeatureSteps end step 'I should see application form' do - page.should have_content "New application" + expect(page).to have_content "New application" end step 'I fill application form out and submit' do @@ -18,9 +18,9 @@ class Spinach::Features::AdminApplications < Spinach::FeatureSteps end step 'I see application' do - page.should have_content "Application: test" - page.should have_content "Application Id" - page.should have_content "Secret" + expect(page).to have_content "Application: test" + expect(page).to have_content "Application Id" + expect(page).to have_content "Secret" end step 'I click edit' do @@ -28,19 +28,19 @@ class Spinach::Features::AdminApplications < Spinach::FeatureSteps end step 'I see edit application form' do - page.should have_content "Edit application" + expect(page).to have_content "Edit application" end step 'I change name of application and submit' do - page.should have_content "Edit application" + expect(page).to have_content "Edit application" fill_in :doorkeeper_application_name, with: 'test_changed' click_on "Submit" end step 'I see that application was changed' do - page.should have_content "test_changed" - page.should have_content "Application Id" - page.should have_content "Secret" + expect(page).to have_content "test_changed" + expect(page).to have_content "Application Id" + expect(page).to have_content "Secret" end step 'I click to remove application' do @@ -50,6 +50,6 @@ class Spinach::Features::AdminApplications < Spinach::FeatureSteps end step "I see that application is removed" do - page.find(".oauth-applications").should_not have_content "test_changed" + expect(page.find(".oauth-applications")).not_to have_content "test_changed" end end diff --git a/features/steps/admin/broadcast_messages.rb b/features/steps/admin/broadcast_messages.rb index a35fa34a3a..2ecb6f0191 100644 --- a/features/steps/admin/broadcast_messages.rb +++ b/features/steps/admin/broadcast_messages.rb @@ -8,7 +8,7 @@ class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps end step 'I should be all broadcast messages' do - page.should have_content "Migration to new server" + expect(page).to have_content "Migration to new server" end step 'submit form with new broadcast message' do @@ -18,11 +18,11 @@ class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps end step 'I should be redirected to admin messages page' do - current_path.should == admin_broadcast_messages_path + expect(current_path).to eq admin_broadcast_messages_path end step 'I should see newly created broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' + expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST' end step 'submit form with new customized broadcast message' do @@ -35,7 +35,7 @@ class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps end step 'I should see a customized broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' - page.should have_selector %(div[style="background-color:#f2dede;color:#b94a48"]) + expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST' + expect(page).to have_selector %(div[style="background-color:#f2dede;color:#b94a48"]) end end diff --git a/features/steps/admin/deploy_keys.rb b/features/steps/admin/deploy_keys.rb index 844837d177..56787eeb6b 100644 --- a/features/steps/admin/deploy_keys.rb +++ b/features/steps/admin/deploy_keys.rb @@ -10,7 +10,7 @@ class Spinach::Features::AdminDeployKeys < Spinach::FeatureSteps step 'I should see all public deploy keys' do DeployKey.are_public.each do |p| - page.should have_content p.title + expect(page).to have_content p.title end end @@ -33,11 +33,11 @@ class Spinach::Features::AdminDeployKeys < Spinach::FeatureSteps end step 'I should be on admin deploy keys page' do - current_path.should == admin_deploy_keys_path + expect(current_path).to eq admin_deploy_keys_path end step 'I should see newly created deploy key' do - page.should have_content(deploy_key.title) + expect(page).to have_content(deploy_key.title) end def deploy_key diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index 721460b937..743c3ecce8 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -28,12 +28,12 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps end step 'I should see newly created group' do - page.should have_content "Group: gitlab" - page.should have_content "Group description" + expect(page).to have_content "Group: gitlab" + expect(page).to have_content "Group description" end step 'I should be redirected to group page' do - current_path.should == admin_group_path(Group.find_by(path: 'gitlab')) + expect(current_path).to eq admin_group_path(Group.find_by(path: 'gitlab')) end When 'I select user "John Doe" from user list as "Reporter"' do @@ -46,14 +46,14 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps step 'I should see "John Doe" in team list in every project as "Reporter"' do within ".group-users-list" do - page.should have_content "John Doe" - page.should have_content "Reporter" + expect(page).to have_content "John Doe" + expect(page).to have_content "Reporter" end end step 'I should be all groups' do Group.all.each do |group| - page.should have_content group.name + expect(page).to have_content group.name end end @@ -69,7 +69,7 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps step 'I should not see "John Doe" in team list' do within ".group-users-list" do - page.should_not have_content "John Doe" + expect(page).not_to have_content "John Doe" end end diff --git a/features/steps/admin/logs.rb b/features/steps/admin/logs.rb index 904e546865..f9e49588c7 100644 --- a/features/steps/admin/logs.rb +++ b/features/steps/admin/logs.rb @@ -4,8 +4,8 @@ class Spinach::Features::AdminLogs < Spinach::FeatureSteps include SharedAdmin step 'I should see tabs with available logs' do - page.should have_content 'production.log' - page.should have_content 'githost.log' - page.should have_content 'application.log' + expect(page).to have_content 'production.log' + expect(page).to have_content 'githost.log' + expect(page).to have_content 'application.log' end end diff --git a/features/steps/admin/projects.rb b/features/steps/admin/projects.rb index 9be4d39d2d..655f189527 100644 --- a/features/steps/admin/projects.rb +++ b/features/steps/admin/projects.rb @@ -5,7 +5,7 @@ class Spinach::Features::AdminProjects < Spinach::FeatureSteps step 'I should see all projects' do Project.all.each do |p| - page.should have_content p.name_with_namespace + expect(page).to have_content p.name_with_namespace end end @@ -15,9 +15,9 @@ class Spinach::Features::AdminProjects < Spinach::FeatureSteps step 'I should see project details' do project = Project.first - current_path.should == admin_namespace_project_path(project.namespace, project) - page.should have_content(project.name_with_namespace) - page.should have_content(project.creator.name) + expect(current_path).to eq admin_namespace_project_path(project.namespace, project) + expect(page).to have_content(project.name_with_namespace) + expect(page).to have_content(project.creator.name) end step 'I visit admin project page' do @@ -34,8 +34,8 @@ class Spinach::Features::AdminProjects < Spinach::FeatureSteps end step 'I should see project transfered' do - page.should have_content 'Web / ' + project.name - page.should have_content 'Namespace: Web' + expect(page).to have_content 'Web / ' + project.name + expect(page).to have_content 'Namespace: Web' end def project diff --git a/features/steps/admin/settings.rb b/features/steps/admin/settings.rb index 15ca0d80f1..06616bfbd7 100644 --- a/features/steps/admin/settings.rb +++ b/features/steps/admin/settings.rb @@ -11,9 +11,9 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps end step 'I should see application settings saved' do - current_application_settings.gravatar_enabled.should be_false - current_application_settings.home_page_url.should == 'https://about.gitlab.com/' - page.should have_content 'Application settings saved successfully' + expect(current_application_settings.gravatar_enabled).to be_false + expect(current_application_settings.home_page_url).to eq 'https://about.gitlab.com/' + expect(page).to have_content 'Application settings saved successfully' end step 'I click on "Service Templates"' do @@ -41,18 +41,18 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps end step 'I should see service template settings saved' do - page.should have_content 'Application settings saved successfully' + expect(page).to have_content 'Application settings saved successfully' end step 'I should see all checkboxes checked' do all('input[type=checkbox]').each do |checkbox| - checkbox.should be_checked + expect(checkbox).to be_checked end end step 'I should see Slack settings saved' do - find_field('Webhook').value.should eq 'http://localhost' - find_field('Username').value.should eq 'test_user' - find_field('Channel').value.should eq '#test_channel' + expect(find_field('Webhook').value).to eq 'http://localhost' + expect(find_field('Username').value).to eq 'test_user' + expect(find_field('Channel').value).to eq '#test_channel' end end diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index e138309724..8b6bdf219b 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -5,7 +5,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps step 'I should see all users' do User.all.each do |user| - page.should have_content user.name + expect(page).to have_content user.name end end @@ -24,12 +24,12 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps step 'See username error message' do within "#error_explanation" do - page.should have_content "Username" + expect(page).to have_content "Username" end end step 'Not changed form action url' do - page.should have_selector %(form[action="/admin/users/#{@user.username}"]) + expect(page).to have_selector %(form[action="/admin/users/#{@user.username}"]) end step 'I submit modified user' do @@ -38,7 +38,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I see user attributes changed' do - page.should have_content 'Can create groups: Yes' + expect(page).to have_content 'Can create groups: Yes' end step 'click edit on my user' do @@ -53,7 +53,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I see the secondary email' do - page.should have_content "Secondary email: #{@user_with_secondary_email.emails.last.email}" + expect(page).to have_content "Secondary email: #{@user_with_secondary_email.emails.last.email}" end step 'I click remove secondary email' do @@ -61,7 +61,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I should not see secondary email anymore' do - page.should_not have_content "Secondary email:" + expect(page).not_to have_content "Secondary email:" end step 'user "Mike" with groups and projects' do @@ -79,8 +79,8 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I should see user "Mike" details' do - page.should have_content 'Account' - page.should have_content 'Personal projects limit' + expect(page).to have_content 'Account' + expect(page).to have_content 'Personal projects limit' end step 'user "Pete" with ssh keys' do @@ -94,8 +94,8 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I should see key list' do - page.should have_content 'ssh-rsa Key2' - page.should have_content 'ssh-rsa Key1' + expect(page).to have_content 'ssh-rsa Key2' + expect(page).to have_content 'ssh-rsa Key1' end step 'I click on the key title' do @@ -103,8 +103,8 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I should see key details' do - page.should have_content 'ssh-rsa Key2' - page.should have_content 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2' + expect(page).to have_content 'ssh-rsa Key2' + expect(page).to have_content 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2' end step 'I click on remove key' do @@ -112,6 +112,6 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'I should see the key removed' do - page.should_not have_content 'ssh-rsa Key2' + expect(page).not_to have_content 'ssh-rsa Key2' end end diff --git a/features/steps/dashboard/archived_projects.rb b/features/steps/dashboard/archived_projects.rb index 969baf9228..36e092f50c 100644 --- a/features/steps/dashboard/archived_projects.rb +++ b/features/steps/dashboard/archived_projects.rb @@ -9,14 +9,14 @@ class Spinach::Features::DashboardArchivedProjects < Spinach::FeatureSteps end step 'I should see "Shop" project link' do - page.should have_link "Shop" + expect(page).to have_link "Shop" end step 'I should not see "Forum" project link' do - page.should_not have_link "Forum" + expect(page).not_to have_link "Forum" end step 'I should see "Forum" project link' do - page.should have_link "Forum" + expect(page).to have_link "Forum" end end diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index bb1f2f444f..945bf35ff2 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -4,16 +4,16 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps include SharedProject step 'I should see "New Project" link' do - page.should have_link "New project" + expect(page).to have_link "New project" end step 'I should see "Shop" project link' do - page.should have_link "Shop" + expect(page).to have_link "Shop" end step 'I should see last push widget' do - page.should have_content "You pushed to fix" - page.should have_link "Create Merge Request" + expect(page).to have_content "You pushed to fix" + expect(page).to have_link "Create Merge Request" end step 'I click "Create Merge Request" link' do @@ -21,10 +21,10 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I see prefilled new Merge Request page' do - current_path.should == new_namespace_project_merge_request_path(@project.namespace, @project) - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("input#merge_request_source_branch").value.should == "fix" - find("input#merge_request_target_branch").value.should == "master" + expect(current_path).to eq new_namespace_project_merge_request_path(@project.namespace, @project) + expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s + expect(find("input#merge_request_source_branch").value).to eq "fix" + expect(find("input#merge_request_target_branch").value).to eq "master" end step 'user with name "John Doe" joined project "Shop"' do @@ -38,7 +38,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I should see "John Doe joined project Shop" event' do - page.should have_content "John Doe joined project #{project.name_with_namespace}" + expect(page).to have_content "John Doe joined project #{project.name_with_namespace}" end step 'user with name "John Doe" left project "Shop"' do @@ -51,7 +51,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I should see "John Doe left project Shop" event' do - page.should have_content "John Doe left project #{project.name_with_namespace}" + expect(page).to have_content "John Doe left project #{project.name_with_namespace}" end step 'I have group with projects' do @@ -64,13 +64,13 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps step 'I should see projects list' do @user.authorized_projects.all.each do |project| - page.should have_link project.name_with_namespace + expect(page).to have_link project.name_with_namespace end end step 'I should see groups list' do Group.all.each do |group| - page.should have_link group.name + expect(page).to have_link group.name end end @@ -80,6 +80,6 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps end step 'I should see 1 project at group list' do - find('span.last_activity/span').should have_content('1') + expect(find('span.last_activity/span')).to have_content('1') end end diff --git a/features/steps/dashboard/event_filters.rb b/features/steps/dashboard/event_filters.rb index 3da3d62d0c..834afa439a 100644 --- a/features/steps/dashboard/event_filters.rb +++ b/features/steps/dashboard/event_filters.rb @@ -4,27 +4,27 @@ class Spinach::Features::EventFilters < Spinach::FeatureSteps include SharedProject step 'I should see push event' do - page.should have_selector('span.pushed') + expect(page).to have_selector('span.pushed') end step 'I should not see push event' do - page.should_not have_selector('span.pushed') + expect(page).not_to have_selector('span.pushed') end step 'I should see new member event' do - page.should have_selector('span.joined') + expect(page).to have_selector('span.joined') end step 'I should not see new member event' do - page.should_not have_selector('span.joined') + expect(page).not_to have_selector('span.joined') end step 'I should see merge request event' do - page.should have_selector('span.accepted') + expect(page).to have_selector('span.accepted') end step 'I should not see merge request event' do - page.should_not have_selector('span.accepted') + expect(page).not_to have_selector('span.accepted') end step 'this project has push event' do diff --git a/features/steps/dashboard/group.rb b/features/steps/dashboard/group.rb index aeea49320f..0c6a0ae372 100644 --- a/features/steps/dashboard/group.rb +++ b/features/steps/dashboard/group.rb @@ -17,29 +17,29 @@ class Spinach::Features::DashboardGroup < Spinach::FeatureSteps end step 'I should not see the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").should_not have_selector(:css, 'i.fa.fa-sign-out') + expect(find(:css, 'li', text: "Owner")).not_to have_selector(:css, 'i.fa.fa-sign-out') # poltergeist always confirms popups. end step 'I should not see the "Leave" button for groupr "Guest"' do - find(:css, 'li', text: "Guest").should_not have_selector(:css, 'i.fa.fa-sign-out') + expect(find(:css, 'li', text: "Guest")).not_to have_selector(:css, 'i.fa.fa-sign-out') # poltergeist always confirms popups. end step 'I should see group "Owned" in group list' do - page.should have_content("Owned") + expect(page).to have_content("Owned") end step 'I should not see group "Owned" in group list' do - page.should_not have_content("Owned") + expect(page).not_to have_content("Owned") end step 'I should see group "Guest" in group list' do - page.should have_content("Guest") + expect(page).to have_content("Guest") end step 'I should not see group "Guest" in group list' do - page.should_not have_content("Guest") + expect(page).not_to have_content("Guest") end step 'I click new group link' do @@ -53,15 +53,15 @@ class Spinach::Features::DashboardGroup < Spinach::FeatureSteps end step 'I should be redirected to group "Samurai" page' do - current_path.should == group_path(Group.find_by(name: 'Samurai')) + expect(current_path).to eq group_path(Group.find_by(name: 'Samurai')) end step 'I should see newly created group "Samurai"' do - page.should have_content "Samurai" - page.should have_content "Tokugawa Shogunate" + expect(page).to have_content "Samurai" + expect(page).to have_content "Tokugawa Shogunate" end step 'I should see the "Can not leave message"' do - page.should have_content "You can not leave Owned group because you're the last owner" + expect(page).to have_content "You can not leave Owned group because you're the last owner" end end diff --git a/features/steps/dashboard/help.rb b/features/steps/dashboard/help.rb index ef433c57c6..86ab31a58a 100644 --- a/features/steps/dashboard/help.rb +++ b/features/steps/dashboard/help.rb @@ -12,7 +12,7 @@ class Spinach::Features::DashboardHelp < Spinach::FeatureSteps end step 'I should see "Rake Tasks" page markdown rendered' do - page.should have_content "Gather information about GitLab and the system it runs on" + expect(page).to have_content "Gather information about GitLab and the system it runs on" end step 'Header "Rebuild project satellites" should have correct ids and links' do diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb index 60da36e86d..cbe54e2dc7 100644 --- a/features/steps/dashboard/issues.rb +++ b/features/steps/dashboard/issues.rb @@ -46,11 +46,11 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps end def should_see(issue) - page.should have_content(issue.title[0..10]) + expect(page).to have_content(issue.title[0..10]) end def should_not_see(issue) - page.should_not have_content(issue.title[0..10]) + expect(page).not_to have_content(issue.title[0..10]) end def assigned_issue diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb index 9d92082bb8..cec8d06ade 100644 --- a/features/steps/dashboard/merge_requests.rb +++ b/features/steps/dashboard/merge_requests.rb @@ -50,11 +50,11 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps end def should_see(merge_request) - page.should have_content(merge_request.title[0..10]) + expect(page).to have_content(merge_request.title[0..10]) end def should_not_see(merge_request) - page.should_not have_content(merge_request.title[0..10]) + expect(page).not_to have_content(merge_request.title[0..10]) end def assigned_merge_request diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb index 93456a81ec..07da5f9587 100644 --- a/features/steps/dashboard/new_project.rb +++ b/features/steps/dashboard/new_project.rb @@ -10,7 +10,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps end step 'I see "New project" page' do - page.should have_content("Project path") + expect(page).to have_content("Project path") end step 'I click on "Import project from GitHub"' do @@ -19,11 +19,11 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps step 'I see instructions on how to import from GitHub' do github_modal = first('.modal-body') - github_modal.should be_visible - github_modal.should have_content "To enable importing projects from GitHub" + expect(github_modal).to be_visible + expect(github_modal).to have_content "To enable importing projects from GitHub" all('.modal-body').each do |element| - element.should_not be_visible unless element == github_modal + expect(element).not_to be_visible unless element == github_modal end end end diff --git a/features/steps/dashboard/starred_projects.rb b/features/steps/dashboard/starred_projects.rb index b9ad2f13e2..b098bbc47d 100644 --- a/features/steps/dashboard/starred_projects.rb +++ b/features/steps/dashboard/starred_projects.rb @@ -9,7 +9,7 @@ class Spinach::Features::DashboardStarredProjects < Spinach::FeatureSteps step 'I should not see project "Shop"' do within 'aside' do - page.should_not have_content('Shop') + expect(page).not_to have_content('Shop') end end end diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb index 0c2127d4c4..89b82293ef 100644 --- a/features/steps/explore/groups.rb +++ b/features/steps/explore/groups.rb @@ -39,19 +39,19 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps end step 'I should not see project "Enterprise" items' do - page.should_not have_content "Enterprise" + expect(page).not_to have_content "Enterprise" end step 'I should see project "Internal" items' do - page.should have_content "Internal" + expect(page).to have_content "Internal" end step 'I should not see project "Internal" items' do - page.should_not have_content "Internal" + expect(page).not_to have_content "Internal" end step 'I should see project "Community" items' do - page.should have_content "Community" + expect(page).to have_content "Community" end step 'I change filter to Everyone\'s' do @@ -59,11 +59,11 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps end step 'I should see group member "John Doe"' do - page.should have_content "John Doe" + expect(page).to have_content "John Doe" end step 'I should not see member roles' do - body.should_not match(%r{owner|developer|reporter|guest}i) + expect(body).not_to match(%r{owner|developer|reporter|guest}i) end protected diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 26b71406bd..c722e2ec41 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -4,56 +4,56 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps include SharedProject step 'I should see project "Empty Public Project"' do - page.should have_content "Empty Public Project" + expect(page).to have_content "Empty Public Project" end step 'I should see public project details' do - page.should have_content '32 branches' - page.should have_content '16 tags' + expect(page).to have_content '32 branches' + expect(page).to have_content '16 tags' end step 'I should see project readme' do - page.should have_content 'README.md' + expect(page).to have_content 'README.md' end step 'I should see empty public project details' do - page.should have_content 'Git global setup' + expect(page).to have_content 'Git global setup' end step 'I should see empty public project details with http clone info' do project = Project.find_by(name: 'Empty Public Project') all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.http_url_to_repo) + expect(element.text).to include(project.http_url_to_repo) end end step 'I should see empty public project details with ssh clone info' do project = Project.find_by(name: 'Empty Public Project') all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.url_to_repo) + expect(element.text).to include(project.url_to_repo) end end step 'I should see project "Community" home page' do within '.navbar-gitlab .title' do - page.should have_content 'Community' + expect(page).to have_content 'Community' end end step 'I should see project "Internal" home page' do within '.navbar-gitlab .title' do - page.should have_content 'Internal' + expect(page).to have_content 'Internal' end end step 'I should see an http link to the repository' do project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.http_url_to_repo) + expect(page).to have_field('project_clone', with: project.http_url_to_repo) end step 'I should see an ssh link to the repository' do project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.url_to_repo) + expect(page).to have_field('project_clone', with: project.url_to_repo) end step 'I visit "Community" issues page' do @@ -70,9 +70,9 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps step 'I should see list of issues for "Community" project' do - page.should have_content "Bug" - page.should have_content public_project.name - page.should have_content "New feature" + expect(page).to have_content "Bug" + expect(page).to have_content public_project.name + expect(page).to have_content "New feature" end step 'I visit "Internal" issues page' do @@ -89,9 +89,9 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps step 'I should see list of issues for "Internal" project' do - page.should have_content "Internal Bug" - page.should have_content internal_project.name - page.should have_content "New internal feature" + expect(page).to have_content "Internal Bug" + expect(page).to have_content internal_project.name + expect(page).to have_content "New internal feature" end step 'I visit "Community" merge requests page' do @@ -107,8 +107,8 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I should see list of merge requests for "Community" project' do - page.should have_content public_project.name - page.should have_content public_merge_request.source_project.name + expect(page).to have_content public_project.name + expect(page).to have_content public_merge_request.source_project.name end step 'I visit "Internal" merge requests page' do @@ -124,8 +124,8 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I should see list of merge requests for "Internal" project' do - page.should have_content internal_project.name - page.should have_content internal_merge_request.source_project.name + expect(page).to have_content internal_project.name + expect(page).to have_content internal_merge_request.source_project.name end def internal_project diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 84348d1709..3ea31de882 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -26,8 +26,8 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I should see "Mike" in team list as "Reporter"' do within '.well-list' do - page.should have_content('Mike') - page.should have_content('Reporter') + expect(page).to have_content('Mike') + expect(page).to have_content('Reporter') end end @@ -42,31 +42,31 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do within '.well-list' do - page.should have_content('sjobs@apple.com') - page.should have_content('invited') - page.should have_content('Reporter') + expect(page).to have_content('sjobs@apple.com') + expect(page).to have_content('invited') + expect(page).to have_content('Reporter') end end step 'I should see group "Owned" projects list' do Group.find_by(name: "Owned").projects.each do |project| - page.should have_link project.name + expect(page).to have_link project.name end end step 'I should see projects activity feed' do - page.should have_content 'closed issue' + expect(page).to have_content 'closed issue' end step 'I should see issues from group "Owned" assigned to me' do assigned_to_me(:issues).each do |issue| - page.should have_content issue.title + expect(page).to have_content issue.title end end step 'I should see merge requests from group "Owned" assigned to me' do assigned_to_me(:merge_requests).each do |issue| - page.should have_content issue.title[0..80] + expect(page).to have_content issue.title[0..80] end end @@ -82,22 +82,22 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I should see user "John Doe" in team list' do projects_with_access = find(".panel .well-list") - projects_with_access.should have_content("John Doe") + expect(projects_with_access).to have_content("John Doe") end step 'I should not see user "John Doe" in team list' do projects_with_access = find(".panel .well-list") - projects_with_access.should_not have_content("John Doe") + expect(projects_with_access).not_to have_content("John Doe") end step 'I should see user "Mary Jane" in team list' do projects_with_access = find(".panel .well-list") - projects_with_access.should have_content("Mary Jane") + expect(projects_with_access).to have_content("Mary Jane") end step 'I should not see user "Mary Jane" in team list' do projects_with_access = find(".panel .well-list") - projects_with_access.should_not have_content("Mary Jane") + expect(projects_with_access).not_to have_content("Mary Jane") end step 'project from group "Owned" has issues assigned to me' do @@ -123,7 +123,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I should see new group "Owned" name' do within ".navbar-gitlab" do - page.should have_content "new-name" + expect(page).to have_content "new-name" end end @@ -134,12 +134,12 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see new group "Owned" avatar' do - Group.find_by(name: "Owned").avatar.should be_instance_of AvatarUploader - Group.find_by(name: "Owned").avatar.url.should == "/uploads/group/avatar/#{ Group.find_by(name:"Owned").id }/gitlab_logo.png" + expect(Group.find_by(name: "Owned").avatar).to be_instance_of AvatarUploader + expect(Group.find_by(name: "Owned").avatar.url).to eq "/uploads/group/avatar/#{ Group.find_by(name:"Owned").id }/gitlab_logo.png" end step 'I should see the "Remove avatar" button' do - page.should have_link("Remove avatar") + expect(page).to have_link("Remove avatar") end step 'I have group "Owned" avatar' do @@ -154,11 +154,11 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should not see group "Owned" avatar' do - Group.find_by(name: "Owned").avatar?.should be_false + expect(Group.find_by(name: "Owned").avatar?).to be_false end step 'I should not see the "Remove avatar" button' do - page.should_not have_link("Remove avatar") + expect(page).not_to have_link("Remove avatar") end step 'I click on the "Remove User From Group" button for "John Doe"' do @@ -172,12 +172,12 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should not see the "Remove User From Group" button for "John Doe"' do - find(:css, 'li', text: "John Doe").should_not have_selector(:css, 'a.btn-remove') + expect(find(:css, 'li', text: "John Doe")).not_to have_selector(:css, 'a.btn-remove') # poltergeist always confirms popups. end step 'I should not see the "Remove User From Group" button for "Mary Jane"' do - find(:css, 'li', text: "Mary Jane").should_not have_selector(:css, 'a.btn-remove') + expect(find(:css, 'li', text: "Mary Jane")).not_to have_selector(:css, 'a.btn-remove') # poltergeist always confirms popups. end @@ -193,7 +193,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see group milestones index page has no milestones' do - page.should have_content('No milestones to show') + expect(page).to have_content('No milestones to show') end step 'Group has projects with milestones' do @@ -201,10 +201,10 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see group milestones index page with milestones' do - page.should have_content('Version 7.2') - page.should have_content('GL-113') - page.should have_link('2 Issues', href: issues_group_path("owned", milestone_title: "Version 7.2")) - page.should have_link('3 Merge Requests', href: merge_requests_group_path("owned", milestone_title: "GL-113")) + expect(page).to have_content('Version 7.2') + expect(page).to have_content('GL-113') + expect(page).to have_link('2 Issues', href: issues_group_path("owned", milestone_title: "Version 7.2")) + expect(page).to have_link('3 Merge Requests', href: merge_requests_group_path("owned", milestone_title: "GL-113")) end step 'I click on one group milestone' do @@ -212,14 +212,14 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see group milestone with descriptions and expiry date' do - page.should have_content('expires at Aug 20, 2114') + expect(page).to have_content('expires at Aug 20, 2114') end step 'I should see group milestone with all issues and MRs assigned to that milestone' do - page.should have_content('Milestone GL-113') - page.should have_content('Progress: 0 closed – 4 open') - page.should have_link(@issue1.title, href: namespace_project_issue_path(@project1.namespace, @project1, @issue1)) - page.should have_link(@mr3.title, href: namespace_project_merge_request_path(@project3.namespace, @project3, @mr3)) + expect(page).to have_content('Milestone GL-113') + expect(page).to have_content('Progress: 0 closed – 4 open') + expect(page).to have_link(@issue1.title, href: namespace_project_issue_path(@project1.namespace, @project1, @issue1)) + expect(page).to have_link(@mr3.title, href: namespace_project_merge_request_path(@project3.namespace, @project3, @mr3)) end protected diff --git a/features/steps/profile/emails.rb b/features/steps/profile/emails.rb index 2b6ac37d86..10ebe70536 100644 --- a/features/steps/profile/emails.rb +++ b/features/steps/profile/emails.rb @@ -6,9 +6,9 @@ class Spinach::Features::ProfileEmails < Spinach::FeatureSteps end step 'I should see my emails' do - page.should have_content(@user.email) + expect(page).to have_content(@user.email) @user.emails.each do |email| - page.should have_content(email.email) + expect(page).to have_content(email.email) end end @@ -19,14 +19,14 @@ class Spinach::Features::ProfileEmails < Spinach::FeatureSteps step 'I should see new email "my@email.com"' do email = @user.emails.find_by(email: "my@email.com") - email.should_not be_nil - page.should have_content("my@email.com") + expect(email).not_to be_nil + expect(page).to have_content("my@email.com") end step 'I should not see email "my@email.com"' do email = @user.emails.find_by(email: "my@email.com") - email.should be_nil - page.should_not have_content("my@email.com") + expect(email).to be_nil + expect(page).not_to have_content("my@email.com") end step 'I click link "Remove" for "my@email.com"' do @@ -43,6 +43,6 @@ class Spinach::Features::ProfileEmails < Spinach::FeatureSteps step 'I should not have @user.email added' do email = @user.emails.find_by(email: @user.email) - email.should be_nil + expect(email).to be_nil end end diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb index b6e03b549a..447ea6d9d1 100644 --- a/features/steps/profile/notifications.rb +++ b/features/steps/profile/notifications.rb @@ -7,6 +7,6 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps end step 'I should see global notifications settings' do - page.should have_content "Notifications" + expect(page).to have_content "Notifications" end end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index d16e6bbea5..c35eb593f4 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -3,7 +3,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps include SharedPaths step 'I should see my profile info' do - page.should have_content "This information will appear on your profile" + expect(page).to have_content "This information will appear on your profile" end step 'I change my profile info' do @@ -23,7 +23,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps expect(@user.twitter).to eq 'testtwitter' expect(@user.website_url).to eq 'testurl' expect(@user.bio).to eq 'I <3 GitLab' - find('#user_location').value.should == 'Ukraine' + expect(find('#user_location').value).to eq 'Ukraine' end step 'I change my avatar' do @@ -33,12 +33,12 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see new avatar' do - @user.avatar.should be_instance_of AvatarUploader - @user.avatar.url.should == "/uploads/user/avatar/#{ @user.id }/gitlab_logo.png" + expect(@user.avatar).to be_instance_of AvatarUploader + expect(@user.avatar.url).to eq "/uploads/user/avatar/#{ @user.id }/gitlab_logo.png" end step 'I should see the "Remove avatar" button' do - page.should have_link("Remove avatar") + expect(page).to have_link("Remove avatar") end step 'I have an avatar' do @@ -53,11 +53,11 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see my gravatar' do - @user.avatar?.should be_false + expect(@user.avatar?).to be_false end step 'I should not see the "Remove avatar" button' do - page.should_not have_link("Remove avatar") + expect(page).not_to have_link("Remove avatar") end step 'I try change my password w/o old one' do @@ -87,11 +87,11 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I should see a missing password error message" do - page.should have_content "You must provide a valid current password" + expect(page).to have_content "You must provide a valid current password" end step "I should see a password error message" do - page.should have_content "Password confirmation doesn't match" + expect(page).to have_content "Password confirmation doesn't match" end step 'I reset my token' do @@ -102,8 +102,8 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see new token' do - find("#token").value.should_not == @old_token - find("#token").value.should == @user.reload.private_token + expect(find("#token").value).not_to eq @old_token + expect(find("#token").value).to eq @user.reload.private_token end step 'I have activity' do @@ -111,7 +111,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see my activity' do - page.should have_content "#{current_user.name} closed issue" + expect(page).to have_content "#{current_user.name} closed issue" end step "I change my application theme" do @@ -127,12 +127,12 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I should see the theme change immediately" do - page.should have_selector('body.ui_color') - page.should_not have_selector('body.ui_basic') + expect(page).to have_selector('body.ui_color') + expect(page).not_to have_selector('body.ui_basic') end step "I should receive feedback that the changes were saved" do - page.should have_content("saved") + expect(page).to have_content("saved") end step 'my password is expired' do @@ -141,11 +141,11 @@ class Spinach::Features::Profile < Spinach::FeatureSteps step "I am not an ldap user" do current_user.identities.delete - current_user.ldap_user?.should be_false + expect(current_user.ldap_user?).to be_false end step 'I redirected to expired password page' do - current_path.should == new_profile_password_path + expect(current_path).to eq new_profile_password_path end step 'I submit new password' do @@ -156,15 +156,15 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I redirected to sign in page' do - current_path.should == new_user_session_path + expect(current_path).to eq new_user_session_path end step 'I should be redirected to password page' do - current_path.should == edit_profile_password_path + expect(current_path).to eq edit_profile_password_path end step 'I should be redirected to account page' do - current_path.should == profile_account_path + expect(current_path).to eq profile_account_path end step 'I click on my profile picture' do @@ -172,10 +172,10 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see my user page' do - page.should have_content "User Activity" + expect(page).to have_content "User Activity" within '.navbar-gitlab' do - page.should have_content current_user.name + expect(page).to have_content current_user.name end end @@ -189,7 +189,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see groups I belong to' do - page.should have_css('.profile-groups-avatars', visible: true) + expect(page).to have_css('.profile-groups-avatars', visible: true) end step 'I click on new application button' do @@ -197,7 +197,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I should see application form' do - page.should have_content "New application" + expect(page).to have_content "New application" end step 'I fill application form out and submit' do @@ -207,9 +207,9 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I see application' do - page.should have_content "Application: test" - page.should have_content "Application Id" - page.should have_content "Secret" + expect(page).to have_content "Application: test" + expect(page).to have_content "Application Id" + expect(page).to have_content "Secret" end step 'I click edit' do @@ -217,19 +217,19 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I see edit application form' do - page.should have_content "Edit application" + expect(page).to have_content "Edit application" end step 'I change name of application and submit' do - page.should have_content "Edit application" + expect(page).to have_content "Edit application" fill_in :doorkeeper_application_name, with: 'test_changed' click_on "Submit" end step 'I see that application was changed' do - page.should have_content "test_changed" - page.should have_content "Application Id" - page.should have_content "Secret" + expect(page).to have_content "test_changed" + expect(page).to have_content "Application Id" + expect(page).to have_content "Secret" end step 'I click to remove application' do @@ -239,6 +239,6 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I see that application is removed" do - page.find(".oauth-applications").should_not have_content "test_changed" + expect(page.find(".oauth-applications")).not_to have_content "test_changed" end end diff --git a/features/steps/profile/ssh_keys.rb b/features/steps/profile/ssh_keys.rb index ea912e5b4d..c7f879d247 100644 --- a/features/steps/profile/ssh_keys.rb +++ b/features/steps/profile/ssh_keys.rb @@ -3,7 +3,7 @@ class Spinach::Features::ProfileSshKeys < Spinach::FeatureSteps step 'I should see my ssh keys' do @user.keys.each do |key| - page.should have_content(key.title) + expect(page).to have_content(key.title) end end @@ -19,9 +19,9 @@ class Spinach::Features::ProfileSshKeys < Spinach::FeatureSteps step 'I should see new ssh key "Laptop"' do key = Key.find_by(title: "Laptop") - page.should have_content(key.title) - page.should have_content(key.key) - current_path.should == profile_key_path(key) + expect(page).to have_content(key.title) + expect(page).to have_content(key.key) + expect(current_path).to eq profile_key_path(key) end step 'I click link "Work"' do @@ -37,7 +37,7 @@ class Spinach::Features::ProfileSshKeys < Spinach::FeatureSteps end step 'I should not see "Work" ssh key' do - page.should_not have_content "Work" + expect(page).not_to have_content "Work" end step 'I have ssh key "ssh-rsa Work"' do diff --git a/features/steps/project/archived.rb b/features/steps/project/archived.rb index 37ad0c7765..db1387763d 100644 --- a/features/steps/project/archived.rb +++ b/features/steps/project/archived.rb @@ -19,11 +19,11 @@ class Spinach::Features::ProjectArchived < Spinach::FeatureSteps end step 'I should not see "Archived"' do - page.should_not have_content "Archived" + expect(page).not_to have_content "Archived" end step 'I should see "Archived"' do - page.should have_content "Archived" + expect(page).to have_content "Archived" end When 'I set project archived' do diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index 07f7e5796a..c4da380a71 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -8,8 +8,8 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step 'I should see "Shop" all branches list' do - page.should have_content "Branches" - page.should have_content "master" + expect(page).to have_content "Branches" + expect(page).to have_content "master" end step 'I click link "Protected"' do @@ -18,8 +18,8 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps step 'I should see "Shop" protected branches list' do within ".protected-branches-list" do - page.should have_content "stable" - page.should_not have_content "master" + expect(page).to have_content "stable" + expect(page).not_to have_content "master" end end @@ -57,19 +57,19 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step 'I should see new branch created' do - page.should have_content 'deploy_keys' + expect(page).to have_content 'deploy_keys' end step 'I should see new an error that branch is invalid' do - page.should have_content 'Branch name invalid' + expect(page).to have_content 'Branch name invalid' end step 'I should see new an error that ref is invalid' do - page.should have_content 'Invalid reference name' + expect(page).to have_content 'Invalid reference name' end step 'I should see new an error that branch already exists' do - page.should have_content 'Branch already exists' + expect(page).to have_content 'Branch already exists' end step "I click branch 'improve/awesome' delete link" do @@ -80,6 +80,6 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step "I should not see branch 'improve/awesome'" do - all(visible: true).should_not have_content 'improve/awesome' + expect(all(visible: true)).not_to have_content 'improve/awesome' end end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index 30d53333b7..55adb69541 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -6,9 +6,9 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'I see project commits' do commit = @project.repository.commit - page.should have_content(@project.name) - page.should have_content(commit.message[0..20]) - page.should have_content(commit.short_id) + expect(page).to have_content(@project.name) + expect(page).to have_content(commit.message[0..20]) + expect(page).to have_content(commit.short_id) end step 'I click atom feed link' do @@ -17,10 +17,10 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'I see commits atom feed' do commit = @project.repository.commit - response_headers['Content-Type'].should have_content("application/atom+xml") - body.should have_selector("title", text: "#{@project.name}:master commits") - body.should have_selector("author email", text: commit.author_email) - body.should have_selector("entry summary", text: commit.description[0..10]) + expect(response_headers['Content-Type']).to have_content("application/atom+xml") + expect(body).to have_selector("title", text: "#{@project.name}:master commits") + expect(body).to have_selector("author email", text: commit.author_email) + expect(body).to have_selector("entry summary", text: commit.description[0..10]) end step 'I click on commit link' do @@ -28,8 +28,8 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see commit info' do - page.should have_content sample_commit.message - page.should have_content "Showing #{sample_commit.files_changed_count} changed files" + expect(page).to have_content sample_commit.message + expect(page).to have_content "Showing #{sample_commit.files_changed_count} changed files" end step 'I fill compare fields with refs' do @@ -46,26 +46,26 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'I should see additional file lines' do within @diff.parent do - first('.new_line').text.should_not have_content "..." + expect(first('.new_line').text).not_to have_content "..." end end step 'I see compared refs' do - page.should have_content "Compare View" - page.should have_content "Commits (1)" - page.should have_content "Showing 2 changed files" + expect(page).to have_content "Compare View" + expect(page).to have_content "Commits (1)" + expect(page).to have_content "Showing 2 changed files" end step 'I see breadcrumb links' do - page.should have_selector('ul.breadcrumb') - page.should have_selector('ul.breadcrumb a', count: 4) + expect(page).to have_selector('ul.breadcrumb') + expect(page).to have_selector('ul.breadcrumb a', count: 4) end step 'I see commits stats' do - page.should have_content 'Top 50 Committers' - page.should have_content 'Committers' - page.should have_content 'Total commits' - page.should have_content 'Authors' + expect(page).to have_content 'Top 50 Committers' + expect(page).to have_content 'Committers' + expect(page).to have_content 'Total commits' + expect(page).to have_content 'Authors' end step 'I visit big commit page' do @@ -74,8 +74,8 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see big commit warning' do - page.should have_content sample_big_commit.message - page.should have_content "Too many changes" + expect(page).to have_content sample_big_commit.message + expect(page).to have_content "Too many changes" end step 'I visit a commit with an image that changed' do @@ -84,8 +84,8 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'The diff links to both the previous and current image' do links = all('.two-up span div a') - links[0]['href'].should =~ %r{blob/#{sample_image_commit.old_blob_id}} - links[1]['href'].should =~ %r{blob/#{sample_image_commit.new_blob_id}} + expect(links[0]['href']).to match %r{blob/#{sample_image_commit.old_blob_id}} + expect(links[1]['href']).to match %r{blob/#{sample_image_commit.new_blob_id}} end step 'I click side-by-side diff button' do @@ -93,10 +93,10 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I see side-by-side diff button' do - page.should have_content "Side-by-side" + expect(page).to have_content "Side-by-side" end step 'I see inline diff button' do - page.should have_content "Inline" + expect(page).to have_content "Inline" end end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb index 3465fcbfd0..e87bf799af 100644 --- a/features/steps/project/commits/tags.rb +++ b/features/steps/project/commits/tags.rb @@ -4,8 +4,8 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps include SharedPaths step 'I should see "Shop" all tags list' do - page.should have_content "Tags" - page.should have_content "v1.0.0" + expect(page).to have_content "Tags" + expect(page).to have_content "v1.0.0" end step 'I click new tag link' do @@ -37,19 +37,19 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps end step 'I should see new tag created' do - page.should have_content 'v7.0' + expect(page).to have_content 'v7.0' end step 'I should see new an error that tag is invalid' do - page.should have_content 'Tag name invalid' + expect(page).to have_content 'Tag name invalid' end step 'I should see new an error that tag ref is invalid' do - page.should have_content 'Invalid reference name' + expect(page).to have_content 'Invalid reference name' end step 'I should see new an error that tag already exists' do - page.should have_content 'Tag already exists' + expect(page).to have_content 'Tag already exists' end step "I delete tag 'v1.1.0'" do @@ -61,7 +61,7 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps step "I should not see tag 'v1.1.0'" do within '.tags' do - all(visible: true).should_not have_content 'v1.1.0' + expect(all(visible: true)).not_to have_content 'v1.1.0' end end @@ -76,7 +76,7 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps step 'I should see tags info message' do within '.tags' do - page.should have_content 'Repository has no tags yet.' + expect(page).to have_content 'Repository has no tags yet.' end end end diff --git a/features/steps/project/commits/user_lookup.rb b/features/steps/project/commits/user_lookup.rb index 63ff84c82e..40cada6da4 100644 --- a/features/steps/project/commits/user_lookup.rb +++ b/features/steps/project/commits/user_lookup.rb @@ -29,9 +29,9 @@ class Spinach::Features::ProjectCommitsUserLookup < Spinach::FeatureSteps def check_author_link(email, user) author_link = find('.commit-author-link') - author_link['href'].should == user_path(user) - author_link['data-original-title'].should == email - find('.commit-author-name').text.should == user.name + expect(author_link['href']).to eq user_path(user) + expect(author_link['data-original-title']).to eq email + expect(find('.commit-author-name').text).to eq user.name end def user_primary diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb index 6b85cf74f5..0d39e1997b 100644 --- a/features/steps/project/create.rb +++ b/features/steps/project/create.rb @@ -8,20 +8,20 @@ class Spinach::Features::ProjectCreate < Spinach::FeatureSteps end step 'I should see project page' do - page.should have_content "Empty" - current_path.should == namespace_project_path(Project.last.namespace, Project.last) + expect(page).to have_content "Empty" + expect(current_path).to eq namespace_project_path(Project.last.namespace, Project.last) end step 'I should see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo + expect(page).to have_content "git init" + expect(page).to have_content "git remote" + expect(page).to have_content Project.last.url_to_repo end step 'I see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo + expect(page).to have_content "git init" + expect(page).to have_content "git remote" + expect(page).to have_content Project.last.url_to_repo end step 'I click on HTTP' do @@ -29,7 +29,7 @@ class Spinach::Features::ProjectCreate < Spinach::FeatureSteps end step 'Remote url should update to http link' do - page.should have_content "git remote add origin #{Project.last.http_url_to_repo}" + expect(page).to have_content "git remote add origin #{Project.last.http_url_to_repo}" end step 'If I click on SSH' do @@ -37,6 +37,6 @@ class Spinach::Features::ProjectCreate < Spinach::FeatureSteps end step 'Remote url should update to ssh link' do - page.should have_content "git remote add origin #{Project.last.url_to_repo}" + expect(page).to have_content "git remote add origin #{Project.last.url_to_repo}" end end diff --git a/features/steps/project/deploy_keys.rb b/features/steps/project/deploy_keys.rb index 81d1182cd1..423e20a507 100644 --- a/features/steps/project/deploy_keys.rb +++ b/features/steps/project/deploy_keys.rb @@ -9,19 +9,19 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps step 'I should see project deploy key' do within '.enabled-keys' do - page.should have_content deploy_key.title + expect(page).to have_content deploy_key.title end end step 'I should see other project deploy key' do within '.available-keys' do - page.should have_content other_deploy_key.title + expect(page).to have_content other_deploy_key.title end end step 'I should see public deploy key' do within '.available-keys' do - page.should have_content public_deploy_key.title + expect(page).to have_content public_deploy_key.title end end @@ -36,12 +36,12 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I should be on deploy keys page' do - current_path.should == namespace_project_deploy_keys_path(@project.namespace, @project) + expect(current_path).to eq namespace_project_deploy_keys_path(@project.namespace, @project) end step 'I should see newly created deploy key' do within '.enabled-keys' do - page.should have_content(deploy_key.title) + expect(page).to have_content(deploy_key.title) end end @@ -57,7 +57,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps step 'I should only see the same deploy key once' do within '.available-keys' do - page.should have_selector('ul li', count: 1) + expect(page).to have_selector('ul li', count: 1) end end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 8e58597db2..879b0e8129 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -4,8 +4,8 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps include SharedProject step 'I click link "Fork"' do - page.should have_content "Shop" - page.should have_content "Fork" + expect(page).to have_content "Shop" + expect(page).to have_content "Fork" click_link "Fork" end @@ -15,7 +15,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end step 'I should see the forked project page' do - page.should have_content "Project was successfully forked." + expect(page).to have_content "Project was successfully forked." end step 'I already have a project named "Shop" in my namespace' do @@ -23,7 +23,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end step 'I should see a "Name has already been taken" warning' do - page.should have_content "Name has already been taken" + expect(page).to have_content "Name has already been taken" end step 'I fork to my namespace' do diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb index ebfa102cee..78812c5202 100644 --- a/features/steps/project/forked_merge_requests.rb +++ b/features/steps/project/forked_merge_requests.rb @@ -21,17 +21,17 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I should see merge request "Merge Request On Forked Project"' do - @project.merge_requests.size.should >= 1 + expect(@project.merge_requests.size).to be >= 1 @merge_request = @project.merge_requests.last - current_path.should == namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - @merge_request.title.should == "Merge Request On Forked Project" - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "fix" - @merge_request.target_branch.should == "master" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch + expect(current_path).to eq namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(@merge_request.title).to eq "Merge Request On Forked Project" + expect(@merge_request.source_project).to eq @forked_project + expect(@merge_request.source_branch).to eq "fix" + expect(@merge_request.target_branch).to eq "master" + expect(page).to have_content @forked_project.path_with_namespace + expect(page).to have_content @project.path_with_namespace + expect(page).to have_content @merge_request.source_branch + expect(page).to have_content @merge_request.target_branch end step 'I fill out a "Merge Request On Forked Project" merge request' do @@ -56,7 +56,7 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps step 'I should see the commit under the forked from project' do commit = @project.repository.commit - page.should have_content(commit.message) + expect(page).to have_content(commit.message) end step 'I click "Create Merge Request on fork" link' do @@ -64,12 +64,12 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I see prefilled new Merge Request page for the forked project' do - current_path.should == new_namespace_project_merge_request_path(@forked_project.namespace, @forked_project) - find("#merge_request_source_project_id").value.should == @forked_project.id.to_s - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("#merge_request_source_branch").value.should have_content "new_design" - find("#merge_request_target_branch").value.should have_content "master" - find("#merge_request_title").value.should == "New Design" + expect(current_path).to eq new_namespace_project_merge_request_path(@forked_project.namespace, @forked_project) + expect(find("#merge_request_source_project_id").value).to eq @forked_project.id.to_s + expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s + expect(find("#merge_request_source_branch").value).to have_content "new_design" + expect(find("#merge_request_target_branch").value).to have_content "master" + expect(find("#merge_request_title").value).to eq "New Design" verify_commit_link(".mr_target_commit", @project) verify_commit_link(".mr_source_commit", @forked_project) end @@ -83,22 +83,22 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I should see the edited merge request' do - page.should have_content "An Edited Forked Merge Request" - @project.merge_requests.size.should >= 1 + expect(page).to have_content "An Edited Forked Merge Request" + expect(@project.merge_requests.size).to be >= 1 @merge_request = @project.merge_requests.last - current_path.should == namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "fix" - @merge_request.target_branch.should == "master" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch + expect(current_path).to eq namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(@merge_request.source_project).to eq @forked_project + expect(@merge_request.source_branch).to eq "fix" + expect(@merge_request.target_branch).to eq "master" + expect(page).to have_content @forked_project.path_with_namespace + expect(page).to have_content @project.path_with_namespace + expect(page).to have_content @merge_request.source_branch + expect(page).to have_content @merge_request.target_branch end step 'I should see last push widget' do - page.should have_content "You pushed to new_design" - page.should have_link "Create Merge Request" + expect(page).to have_content "You pushed to new_design" + expect(page).to have_link "Create Merge Request" end step 'I click link edit "Merge Request On Forked Project"' do @@ -106,26 +106,26 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I see the edit page prefilled for "Merge Request On Forked Project"' do - current_path.should == edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - page.should have_content "Edit merge request ##{@merge_request.id}" - find("#merge_request_title").value.should == "Merge Request On Forked Project" + expect(current_path).to eq edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(page).to have_content "Edit merge request ##{@merge_request.id}" + expect(find("#merge_request_title").value).to eq "Merge Request On Forked Project" end step 'I fill out an invalid "Merge Request On Forked Project" merge request' do select "Select branch", from: "merge_request_target_branch" - find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s - find(:select, "merge_request_target_project_id", {}).value.should == @project.id.to_s - find(:select, "merge_request_source_branch", {}).value.should == "" - find(:select, "merge_request_target_branch", {}).value.should == "" + expect(find(:select, "merge_request_source_project_id", {}).value).to eq @forked_project.id.to_s + expect(find(:select, "merge_request_target_project_id", {}).value).to eq @project.id.to_s + expect(find(:select, "merge_request_source_branch", {}).value).to eq "" + expect(find(:select, "merge_request_target_branch", {}).value).to eq "" click_button "Compare branches" end step 'I should see validation errors' do - page.should have_content "You must select source and target branch" + expect(page).to have_content "You must select source and target branch" end step 'the target repository should be the original repository' do - page.should have_select("merge_request_target_project_id", selected: @project.path_with_namespace) + expect(page).to have_select("merge_request_target_project_id", selected: @project.path_with_namespace) end step 'I click "Assign to" dropdown"' do @@ -139,13 +139,13 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps step 'I should see the users from the target project ID' do expect(page).to have_selector('.user-result', visible: true, count: 2) users = page.all('.user-name') - users[0].text.should == 'Unassigned' - users[1].text.should == @project.users.first.name + expect(users[0].text).to eq 'Unassigned' + expect(users[1].text).to eq @project.users.first.name end # Verify a link is generated against the correct project def verify_commit_link(container_div, container_project) # This should force a wait for the javascript to execute - find(:div,container_div).find(".commit_short_id")['href'].should have_content "#{container_project.path_with_namespace}/commit" + expect(find(:div,container_div).find(".commit_short_id")['href']).to have_content "#{container_project.path_with_namespace}/commit" end end diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb index a2807c340f..5e7e573a6a 100644 --- a/features/steps/project/graph.rb +++ b/features/steps/project/graph.rb @@ -3,7 +3,7 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps include SharedProject step 'page should have graphs' do - page.should have_selector ".stat-graph" + expect(page).to have_selector ".stat-graph" end When 'I visit project "Shop" graph page' do @@ -17,7 +17,7 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps end step 'page should have commits graphs' do - page.should have_content "Commit statistics for master" - page.should have_content "Commits per day of month" + expect(page).to have_content "Commit statistics for master" + expect(page).to have_content "Commits per day of month" end end diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb index d06905285f..04e3bf78ed 100644 --- a/features/steps/project/hooks.rb +++ b/features/steps/project/hooks.rb @@ -19,7 +19,7 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps end step 'I should see project hook' do - page.should have_content @hook.url + expect(page).to have_content @hook.url end step 'I submit new hook' do @@ -29,8 +29,8 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps end step 'I should see newly created hook' do - current_path.should == namespace_project_hooks_path(current_project.namespace, current_project) - page.should have_content(@url) + expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project) + expect(page).to have_content(@url) end step 'I click test hook button' do @@ -44,19 +44,19 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps end step 'hook should be triggered' do - current_path.should == namespace_project_hooks_path(current_project.namespace, current_project) - page.should have_selector '.flash-notice', + expect(current_path).to eq namespace_project_hooks_path(current_project.namespace, current_project) + expect(page).to have_selector '.flash-notice', text: 'Hook successfully executed.' end step 'I should see hook error message' do - page.should have_selector '.flash-alert', + expect(page).to have_selector '.flash-alert', text: 'Hook execution failed. '\ 'Ensure the project has commits.' end step 'I should see hook service down error message' do - page.should have_selector '.flash-alert', + expect(page).to have_selector '.flash-alert', text: 'Hook execution failed. '\ 'Ensure hook URL is correct and '\ 'service is up.' diff --git a/features/steps/project/issues/filter_labels.rb b/features/steps/project/issues/filter_labels.rb index 5740bd1283..66a3c1ead6 100644 --- a/features/steps/project/issues/filter_labels.rb +++ b/features/steps/project/issues/filter_labels.rb @@ -6,25 +6,25 @@ class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps step 'I should see "Bugfix1" in issues list' do within ".issues-list" do - page.should have_content "Bugfix1" + expect(page).to have_content "Bugfix1" end end step 'I should see "Bugfix2" in issues list' do within ".issues-list" do - page.should have_content "Bugfix2" + expect(page).to have_content "Bugfix2" end end step 'I should not see "Bugfix2" in issues list' do within ".issues-list" do - page.should_not have_content "Bugfix2" + expect(page).not_to have_content "Bugfix2" end end step 'I should not see "Feature1" in issues list' do within ".issues-list" do - page.should_not have_content "Feature1" + expect(page).not_to have_content "Feature1" end end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index 504f0cff72..87a3d280cd 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -7,24 +7,24 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps include SharedMarkdown step 'I should see "Release 0.4" in issues' do - page.should have_content "Release 0.4" + expect(page).to have_content "Release 0.4" end step 'I should not see "Release 0.3" in issues' do - page.should_not have_content "Release 0.3" + expect(page).not_to have_content "Release 0.3" end step 'I should not see "Tweet control" in issues' do - page.should_not have_content "Tweet control" + expect(page).not_to have_content "Tweet control" end step 'I should see that I am subscribed' do - find(".subscribe-button span").text.should == "Unsubscribe" + expect(find(".subscribe-button span").text).to eq "Unsubscribe" end step 'I should see that I am unsubscribed' do sleep 0.2 - find(".subscribe-button span").text.should == "Subscribe" + expect(find(".subscribe-button span").text).to eq "Subscribe" end step 'I click link "Closed"' do @@ -36,11 +36,11 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I should see "Release 0.3" in issues' do - page.should have_content "Release 0.3" + expect(page).to have_content "Release 0.3" end step 'I should not see "Release 0.4" in issues' do - page.should_not have_content "Release 0.4" + expect(page).not_to have_content "Release 0.4" end step 'I click link "All"' do @@ -52,7 +52,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I should see issue "Release 0.4"' do - page.should have_content "Release 0.4" + expect(page).to have_content "Release 0.4" end step 'I click link "New Issue"' do @@ -66,9 +66,9 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I see current user as the first user' do expect(page).to have_selector('.user-result', visible: true, count: 4) users = page.all('.user-name') - users[0].text.should == 'Any' - users[1].text.should == 'Unassigned' - users[2].text.should == current_user.name + expect(users[0].text).to eq 'Any' + expect(users[1].text).to eq 'Unassigned' + expect(users[2].text).to eq current_user.name end step 'I submit new issue "500 error on profile"' do @@ -88,15 +88,15 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I should see label \'bug\' with issue' do within '.issue-show-labels' do - page.should have_content 'bug' + expect(page).to have_content 'bug' end end step 'I should see issue "500 error on profile"' do issue = Issue.find_by(title: "500 error on profile") - page.should have_content issue.title - page.should have_content issue.author_name - page.should have_content issue.project.name + expect(page).to have_content issue.title + expect(page).to have_content issue.author_name + expect(page).to have_content issue.project.name end step 'I fill in issue search with "Re"' do @@ -139,7 +139,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I should see selected milestone with title "v3.0"' do issues_milestone_selector = "#issue_milestone_id_chzn > a" - find(issues_milestone_selector).should have_content("v3.0") + expect(find(issues_milestone_selector)).to have_content("v3.0") end When 'I select first assignee from "Shop" project' do @@ -152,7 +152,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps issues_assignee_selector = "#issue_assignee_id_chzn > a" assignee_name = project.users.first.name - find(issues_assignee_selector).should have_content(assignee_name) + expect(find(issues_assignee_selector)).to have_content(assignee_name) end step 'project "Shop" have "Release 0.4" open issue' do @@ -191,7 +191,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I see empty project details with ssh clone info' do project = Project.find_by(name: 'Empty Project') all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.url_to_repo) + expect(element.text).to include(project.url_to_repo) end end @@ -215,7 +215,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'The code block should be unchanged' do - page.should have_content("```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```") + expect(page).to have_content("```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```") end step 'project \'Shop\' has issue \'Bugfix1\' with description: \'Description for issue1\'' do @@ -239,15 +239,15 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I should see \'Bugfix1\' in issues' do - page.should have_content 'Bugfix1' + expect(page).to have_content 'Bugfix1' end step 'I should see \'Feature1\' in issues' do - page.should have_content 'Feature1' + expect(page).to have_content 'Feature1' end step 'I should not see \'Bugfix1\' in issues' do - page.should_not have_content 'Bugfix1' + expect(page).not_to have_content 'Bugfix1' end step 'issue \'Release 0.4\' has label \'bug\'' do diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 6ce34c500c..4de8a39672 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -24,7 +24,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I should see labels help message' do within '.labels' do - page.should have_content 'Create first label or generate default set of '\ + expect(page).to have_content 'Create first label or generate default set of '\ 'labels' end end @@ -49,37 +49,37 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I should see label label exist error message' do within '.label-form' do - page.should have_content 'Title has already been taken' + expect(page).to have_content 'Title has already been taken' end end step 'I should see label color error message' do within '.label-form' do - page.should have_content 'Color is invalid' + expect(page).to have_content 'Color is invalid' end end step 'I should see label \'feature\'' do within '.manage-labels-list' do - page.should have_content 'feature' + expect(page).to have_content 'feature' end end step 'I should see label \'bug\'' do within '.manage-labels-list' do - page.should have_content 'bug' + expect(page).to have_content 'bug' end end step 'I should not see label \'bug\'' do within '.manage-labels-list' do - page.should_not have_content 'bug' + expect(page).not_to have_content 'bug' end end step 'I should see label \'support\'' do within '.manage-labels-list' do - page.should have_content 'support' + expect(page).to have_content 'support' end end @@ -91,7 +91,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I should see label \'fix\'' do within '.manage-labels-list' do - page.should have_content 'fix' + expect(page).to have_content 'fix' end end diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb index cce87a6d98..708c524394 100644 --- a/features/steps/project/issues/milestones.rb +++ b/features/steps/project/issues/milestones.rb @@ -6,9 +6,9 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps step 'I should see milestone "v2.2"' do milestone = @project.milestones.find_by(title: "v2.2") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Issues") + expect(page).to have_content(milestone.title[0..10]) + expect(page).to have_content(milestone.expires_at) + expect(page).to have_content("Issues") end step 'I click link "v2.2"' do @@ -26,9 +26,9 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps step 'I should see milestone "v2.3"' do milestone = @project.milestones.find_by(title: "v2.3") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Issues") + expect(page).to have_content(milestone.title[0..10]) + expect(page).to have_content(milestone.expires_at) + expect(page).to have_content("Issues") end step 'project "Shop" has milestone "v2.2"' do @@ -54,6 +54,6 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps end step 'I should see 3 issues' do - page.should have_selector('#tab-issues li.issue-row', count: 4) + expect(page).to have_selector('#tab-issues li.issue-row', count: 4) end end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index f6cfa7ef9e..fe019a0b3a 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -25,43 +25,43 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should see merge request "Wiki Feature"' do within '.merge-request' do - page.should have_content "Wiki Feature" + expect(page).to have_content "Wiki Feature" end end step 'I should see closed merge request "Bug NS-04"' do merge_request = MergeRequest.find_by!(title: "Bug NS-04") - merge_request.closed?.should be_true - page.should have_content "Rejected by" + expect(merge_request.closed?).to be_true + expect(page).to have_content "Rejected by" end step 'I should see merge request "Bug NS-04"' do - page.should have_content "Bug NS-04" + expect(page).to have_content "Bug NS-04" end step 'I should see "Bug NS-04" in merge requests' do - page.should have_content "Bug NS-04" + expect(page).to have_content "Bug NS-04" end step 'I should see "Feature NS-03" in merge requests' do - page.should have_content "Feature NS-03" + expect(page).to have_content "Feature NS-03" end step 'I should not see "Feature NS-03" in merge requests' do - page.should_not have_content "Feature NS-03" + expect(page).not_to have_content "Feature NS-03" end step 'I should not see "Bug NS-04" in merge requests' do - page.should_not have_content "Bug NS-04" + expect(page).not_to have_content "Bug NS-04" end step 'I should see that I am subscribed' do - find(".subscribe-button span").text.should == "Unsubscribe" + expect(find(".subscribe-button span").text).to eq "Unsubscribe" end step 'I should see that I am unsubscribed' do - find(".subscribe-button span").should have_content("Subscribe") + expect(find(".subscribe-button span")).to have_content("Subscribe") end step 'I click button "Unsubscribe"' do @@ -125,7 +125,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps expect(buttons.count).to eq(2) buttons.each do |b| - expect(b['href']).should_not have_content('json') + expect(expect(b['href'])).not_to have_content('json') end end @@ -164,24 +164,24 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see a discussion has started on diff' do - page.should have_content "#{current_user.name} started a discussion" - page.should have_content sample_commit.line_code_path - page.should have_content "Line is wrong" + expect(page).to have_content "#{current_user.name} started a discussion" + expect(page).to have_content sample_commit.line_code_path + expect(page).to have_content "Line is wrong" end step 'I should see a discussion has started on commit diff' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content sample_commit.line_code_path - page.should have_content "Line is wrong" + expect(page).to have_content "#{current_user.name} started a discussion on commit" + expect(page).to have_content sample_commit.line_code_path + expect(page).to have_content "Line is wrong" end step 'I should see a discussion has started on commit' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content "One comment to rule them all" + expect(page).to have_content "#{current_user.name} started a discussion on commit" + expect(page).to have_content "One comment to rule them all" end step 'merge request is mergeable' do - page.should have_button 'Accept Merge Request' + expect(page).to have_button 'Accept Merge Request' end step 'I modify merge commit message' do @@ -206,7 +206,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should see merged request' do within '.issue-box' do - page.should have_content "Accepted" + expect(page).to have_content "Accepted" end end @@ -216,7 +216,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should see reopened merge request "Bug NS-04"' do within '.issue-box' do - page.should have_content "Open" + expect(page).to have_content "Open" end end @@ -234,25 +234,25 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should not see a comment like "Line is wrong" in the second file' do within '.files [id^=diff]:nth-child(2)' do - page.should_not have_visible_content "Line is wrong" + expect(page).not_to have_visible_content "Line is wrong" end end step 'I should see a comment like "Line is wrong" in the second file' do within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do - page.should have_visible_content "Line is wrong" + expect(page).to have_visible_content "Line is wrong" end end step 'I should not see a comment like "Line is wrong here" in the second file' do within '.files [id^=diff]:nth-child(2)' do - page.should_not have_visible_content "Line is wrong here" + expect(page).not_to have_visible_content "Line is wrong here" end end step 'I should see a comment like "Line is wrong here" in the second file' do within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do - page.should have_visible_content "Line is wrong here" + expect(page).to have_visible_content "Line is wrong here" end end @@ -265,7 +265,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end within ".files [id^=diff]:nth-child(1) .note-body > .note-text" do - page.should have_content "Line is correct" + expect(page).to have_content "Line is correct" end end @@ -280,7 +280,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should still see a comment like "Line is correct" in the first file' do within '.files [id^=diff]:nth-child(1) .note-body > .note-text' do - page.should have_visible_content "Line is correct" + expect(page).to have_visible_content "Line is correct" end end @@ -298,7 +298,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I should see comments on the side-by-side diff page' do within '.files [id^=diff]:nth-child(1) .parallel .note-body > .note-text' do - page.should have_visible_content "Line is correct" + expect(page).to have_visible_content "Line is correct" end end @@ -316,8 +316,8 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see new target branch changes' do - page.should have_content 'From fix into feature' - page.should have_content 'Target branch changed from master to feature' + expect(page).to have_content 'From fix into feature' + expect(page).to have_content 'Target branch changed from master to feature' end def merge_request @@ -334,7 +334,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps click_button "Add Comment" end - page.should have_content message + expect(page).to have_content message end def init_diff_note_first_file diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index a15688ace6..14b06917f0 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -4,7 +4,7 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps include SharedProject step 'page should have network graph' do - page.should have_selector ".network-graph" + expect(page).to have_selector ".network-graph" end When 'I visit project "Shop" network page' do @@ -16,16 +16,16 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should select "master" in select box' do - page.should have_selector '.select2-chosen', text: "master" + expect(page).to have_selector '.select2-chosen', text: "master" end step 'page should select "v1.0.0" in select box' do - page.should have_selector '.select2-chosen', text: "v1.0.0" + expect(page).to have_selector '.select2-chosen', text: "v1.0.0" end step 'page should have "master" on graph' do within '.network-graph' do - page.should have_content 'master' + expect(page).to have_content 'master' end end @@ -46,27 +46,27 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps step 'page should have content not containing "v1.0.0"' do within '.network-graph' do - page.should have_content 'Change some files' + expect(page).to have_content 'Change some files' end end step 'page should not have content not containing "v1.0.0"' do within '.network-graph' do - page.should_not have_content 'Change some files' + expect(page).not_to have_content 'Change some files' end end step 'page should select "feature" in select box' do - page.should have_selector '.select2-chosen', text: "feature" + expect(page).to have_selector '.select2-chosen', text: "feature" end step 'page should select "v1.0.0" in select box' do - page.should have_selector '.select2-chosen', text: "v1.0.0" + expect(page).to have_selector '.select2-chosen', text: "v1.0.0" end step 'page should have "feature" on graph' do within '.network-graph' do - page.should have_content 'feature' + expect(page).to have_content 'feature' end end @@ -80,7 +80,7 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps step 'page should have "v1.0.0" on graph' do within '.network-graph' do - page.should have_content 'v1.0.0' + expect(page).to have_content 'v1.0.0' end end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index fcc15aacc2..126c9c0524 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -13,7 +13,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see project with new settings' do - find_field('project_name').value.should == 'NewName' + expect(find_field('project_name').value).to eq 'NewName' end step 'change project path settings' do @@ -22,7 +22,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see project with new path settings' do - project.path.should == 'new-path' + expect(project.path).to eq 'new-path' end step 'I change the project avatar' do @@ -35,13 +35,13 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see new project avatar' do - @project.avatar.should be_instance_of AvatarUploader + expect(@project.avatar).to be_instance_of AvatarUploader url = @project.avatar.url - url.should == "/uploads/project/avatar/#{ @project.id }/gitlab_logo.png" + expect(url).to eq "/uploads/project/avatar/#{ @project.id }/gitlab_logo.png" end step 'I should see the "Remove avatar" button' do - page.should have_link('Remove avatar') + expect(page).to have_link('Remove avatar') end step 'I have an project avatar' do @@ -59,16 +59,16 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see the default project avatar' do - @project.avatar?.should be_false + expect(@project.avatar?).to be_false end step 'I should not see the "Remove avatar" button' do - page.should_not have_link('Remove avatar') + expect(page).not_to have_link('Remove avatar') end step 'I should see project "Shop" version' do within '.project-side' do - page.should have_content '6.7.0.pre' + expect(page).to have_content '6.7.0.pre' end end @@ -78,7 +78,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see project default branch changed' do - find(:css, 'select#project_default_branch').value.should == 'fix' + expect(find(:css, 'select#project_default_branch').value).to eq 'fix' end step 'I select project "Forum" README tab' do @@ -86,13 +86,13 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see project "Forum" README' do - page.should have_link 'README.md' - page.should have_content 'Sample repo for testing gitlab features' + expect(page).to have_link 'README.md' + expect(page).to have_content 'Sample repo for testing gitlab features' end step 'I should see project "Shop" README' do - page.should have_link 'README.md' - page.should have_content 'testme' + expect(page).to have_link 'README.md' + expect(page).to have_content 'testme' end step 'I add project tags' do @@ -104,14 +104,14 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should not see "New Issue" button' do - page.should_not have_link 'New Issue' + expect(page).not_to have_link 'New Issue' end step 'I should not see "New Merge Request" button' do - page.should_not have_link 'New Merge Request' + expect(page).not_to have_link 'New Merge Request' end step 'I should not see "Snippets" button' do - page.should_not have_link 'Snippets' + expect(page).not_to have_link 'Snippets' end end diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb index 57c6e39c80..373f5bb8ad 100644 --- a/features/steps/project/redirects.rb +++ b/features/steps/project/redirects.rb @@ -19,7 +19,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I should see project "Community" home page' do Gitlab.config.gitlab.should_receive(:host).and_return("www.example.com") within '.navbar-gitlab .title' do - page.should have_content 'Community' + expect(page).to have_content 'Community' end end @@ -48,8 +48,8 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I should be redirected to "Community" page' do project = Project.find_by(name: 'Community') - current_path.should == "/#{project.path_with_namespace}" - status_code.should == 200 + expect(current_path).to eq "/#{project.path_with_namespace}" + expect(status_code).to eq 200 end step 'I get redirected to signin page where I sign in' do @@ -63,7 +63,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I should be redirected to "Enterprise" page' do project = Project.find_by(name: 'Enterprise') - current_path.should == "/#{project.path_with_namespace}" - status_code.should == 200 + expect(current_path).to eq "/#{project.path_with_namespace}" + expect(status_code).to eq 200 end end diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb index 4b3d79324a..0327fd6198 100644 --- a/features/steps/project/services.rb +++ b/features/steps/project/services.rb @@ -8,16 +8,16 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see list of available services' do - page.should have_content 'Project services' - page.should have_content 'Campfire' - page.should have_content 'HipChat' - page.should have_content 'GitLab CI' - page.should have_content 'Assembla' - page.should have_content 'Pushover' - page.should have_content 'Atlassian Bamboo' - page.should have_content 'JetBrains TeamCity' - page.should have_content 'Asana' - page.should have_content 'Irker (IRC gateway)' + expect(page).to have_content 'Project services' + expect(page).to have_content 'Campfire' + expect(page).to have_content 'HipChat' + expect(page).to have_content 'GitLab CI' + expect(page).to have_content 'Assembla' + expect(page).to have_content 'Pushover' + expect(page).to have_content 'Atlassian Bamboo' + expect(page).to have_content 'JetBrains TeamCity' + expect(page).to have_content 'Asana' + expect(page).to have_content 'Irker (IRC gateway)' end step 'I click gitlab-ci service link' do @@ -32,7 +32,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see service settings saved' do - find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3' + expect(find_field('Project url').value).to eq 'http://ci.gitlab.org/projects/3' end step 'I click hipchat service link' do @@ -47,7 +47,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see hipchat service settings saved' do - find_field('Room').value.should == 'gitlab' + expect(find_field('Room').value).to eq 'gitlab' end step 'I fill hipchat settings with custom server' do @@ -59,7 +59,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see hipchat service settings with custom server saved' do - find_field('Server').value.should == 'https://chat.example.com' + expect(find_field('Server').value).to eq 'https://chat.example.com' end step 'I click pivotaltracker service link' do @@ -73,7 +73,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see pivotaltracker service settings saved' do - find_field('Token').value.should == 'verySecret' + expect(find_field('Token').value).to eq 'verySecret' end step 'I click Flowdock service link' do @@ -87,7 +87,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Flowdock service settings saved' do - find_field('Token').value.should == 'verySecret' + expect(find_field('Token').value).to eq 'verySecret' end step 'I click Assembla service link' do @@ -101,7 +101,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Assembla service settings saved' do - find_field('Token').value.should == 'verySecret' + expect(find_field('Token').value).to eq 'verySecret' end step 'I click Asana service link' do @@ -116,8 +116,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Asana service settings saved' do - find_field('Api key').value.should == 'verySecret' - find_field('Restrict to branch').value.should == 'master' + expect(find_field('Api key').value).to eq 'verySecret' + expect(find_field('Restrict to branch').value).to eq 'master' end step 'I click email on push service link' do @@ -130,7 +130,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see email on push service settings saved' do - find_field('Recipients').value.should == 'qa@company.name' + expect(find_field('Recipients').value).to eq 'qa@company.name' end step 'I click Irker service link' do @@ -145,8 +145,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Irker service settings saved' do - find_field('Recipients').value.should == 'irc://chat.freenode.net/#commits' - find_field('Colorize messages').value.should == '1' + expect(find_field('Recipients').value).to eq 'irc://chat.freenode.net/#commits' + expect(find_field('Colorize messages').value).to eq '1' end step 'I click Slack service link' do @@ -160,7 +160,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Slack service settings saved' do - find_field('Webhook').value.should == 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' + expect(find_field('Webhook').value).to eq 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' end step 'I click Pushover service link' do @@ -178,11 +178,11 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Pushover service settings saved' do - find_field('Api key').value.should == 'verySecret' - find_field('User key').value.should == 'verySecret' - find_field('Device').value.should == 'myDevice' - find_field('Priority').find('option[selected]').value.should == '1' - find_field('Sound').find('option[selected]').value.should == 'bike' + expect(find_field('Api key').value).to eq 'verySecret' + expect(find_field('User key').value).to eq 'verySecret' + expect(find_field('Device').value).to eq 'myDevice' + expect(find_field('Priority').find('option[selected]').value).to eq '1' + expect(find_field('Sound').find('option[selected]').value).to eq 'bike' end step 'I click Atlassian Bamboo CI service link' do @@ -199,9 +199,9 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see Atlassian Bamboo CI service settings saved' do - find_field('Bamboo url').value.should == 'http://bamboo.example.com' - find_field('Build key').value.should == 'KEY' - find_field('Username').value.should == 'user' + expect(find_field('Bamboo url').value).to eq 'http://bamboo.example.com' + expect(find_field('Build key').value).to eq 'KEY' + expect(find_field('Username').value).to eq 'user' end step 'I click JetBrains TeamCity CI service link' do @@ -218,8 +218,8 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps end step 'I should see JetBrains TeamCity CI service settings saved' do - find_field('Teamcity url').value.should == 'http://teamcity.example.com' - find_field('Build type').value.should == 'GitlabTest_Build' - find_field('Username').value.should == 'user' + expect(find_field('Teamcity url').value).to eq 'http://teamcity.example.com' + expect(find_field('Build type').value).to eq 'GitlabTest_Build' + expect(find_field('Username').value).to eq 'user' end end diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index 343aeb53b1..ff3e14b53b 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -30,15 +30,15 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I should see "Snippet one" in snippets' do - page.should have_content "Snippet one" + expect(page).to have_content "Snippet one" end step 'I should not see "Snippet two" in snippets' do - page.should_not have_content "Snippet two" + expect(page).not_to have_content "Snippet two" end step 'I should not see "Snippet one" in snippets' do - page.should_not have_content "Snippet one" + expect(page).not_to have_content "Snippet one" end step 'I click link "Edit"' do @@ -61,8 +61,8 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I should see snippet "Snippet three"' do - page.should have_content "Snippet three" - page.should have_content "Content of snippet three" + expect(page).to have_content "Snippet three" + expect(page).to have_content "Content of snippet three" end step 'I submit new title "Snippet new title"' do @@ -71,7 +71,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I should see "Snippet new title"' do - page.should have_content "Snippet new title" + expect(page).to have_content "Snippet new title" end step 'I leave a comment like "Good snippet!"' do @@ -82,7 +82,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I should see comment "Good snippet!"' do - page.should have_content "Good snippet!" + expect(page).to have_content "Good snippet!" end step 'I visit snippet page "Snippet one"' do diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index caf6c73ee0..58a6ef4f39 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -5,23 +5,23 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps include RepoHelpers step 'I should see files from repository' do - page.should have_content "VERSION" - page.should have_content ".gitignore" - page.should have_content "LICENSE" + expect(page).to have_content "VERSION" + expect(page).to have_content ".gitignore" + expect(page).to have_content "LICENSE" end step 'I should see files from repository for "6d39438"' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "6d39438") - page.should have_content ".gitignore" - page.should have_content "LICENSE" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "6d39438") + expect(page).to have_content ".gitignore" + expect(page).to have_content "LICENSE" end step 'I see the ".gitignore"' do - page.should have_content '.gitignore' + expect(page).to have_content '.gitignore' end step 'I don\'t see the ".gitignore"' do - page.should_not have_content '.gitignore' + expect(page).not_to have_content '.gitignore' end step 'I click on ".gitignore" file in repo' do @@ -29,11 +29,11 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I should see its content' do - page.should have_content old_gitignore_content + expect(page).to have_content old_gitignore_content end step 'I should see its new content' do - page.should have_content new_gitignore_content + expect(page).to have_content new_gitignore_content end step 'I click link "Raw"' do @@ -41,7 +41,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I should see raw file content' do - source.should == sample_blob.data + expect(source).to eq sample_blob.data end step 'I click button "Edit"' do @@ -49,16 +49,16 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I cannot see the edit button' do - page.should_not have_link 'edit' + expect(page).not_to have_link 'edit' end step 'The edit button is disabled' do - page.should have_css '.disabled', text: 'Edit' + expect(page).to have_css '.disabled', text: 'Edit' end step 'I can edit code' do set_new_content - evaluate_script('blob.editor.getValue()').should == new_gitignore_content + expect(evaluate_script('blob.editor.getValue()')).to eq new_gitignore_content end step 'I edit code' do @@ -98,7 +98,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I see diff' do - page.should have_css '.line_holder.new' + expect(page).to have_css '.line_holder.new' end step 'I click on "new file" link in repo' do @@ -106,8 +106,8 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I can see new file page' do - page.should have_content "New file" - page.should have_content "Commit message" + expect(page).to have_content "New file" + expect(page).to have_content "Commit message" end step 'I click on files directory' do @@ -119,8 +119,8 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I see Browse dir link' do - page.should have_link 'Browse Dir »' - page.should_not have_link 'Browse Code »' + expect(page).to have_link 'Browse Dir »' + expect(page).not_to have_link 'Browse Code »' end step 'I click on readme file' do @@ -130,14 +130,14 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I see Browse file link' do - page.should have_link 'Browse File »' - page.should_not have_link 'Browse Code »' + expect(page).to have_link 'Browse File »' + expect(page).not_to have_link 'Browse Code »' end step 'I see Browse code link' do - page.should have_link 'Browse Code »' - page.should_not have_link 'Browse File »' - page.should_not have_link 'Browse Dir »' + expect(page).to have_link 'Browse Code »' + expect(page).not_to have_link 'Browse File »' + expect(page).not_to have_link 'Browse Dir »' end step 'I click on Permalink' do @@ -145,7 +145,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I am redirected to the files URL' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, 'master') + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, 'master') end step 'I am redirected to the ".gitignore"' do diff --git a/features/steps/project/source/git_blame.rb b/features/steps/project/source/git_blame.rb index e29a816c51..d0a27f47e2 100644 --- a/features/steps/project/source/git_blame.rb +++ b/features/steps/project/source/git_blame.rb @@ -12,8 +12,8 @@ class Spinach::Features::ProjectSourceGitBlame < Spinach::FeatureSteps end step 'I should see git file blame' do - page.should have_content "*.rb" - page.should have_content "Dmitriy Zaporozhets" - page.should have_content "Initial commit" + expect(page).to have_content "*.rb" + expect(page).to have_content "Dmitriy Zaporozhets" + expect(page).to have_content "Initial commit" end end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index 7961fdedad..b6534f757c 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -13,19 +13,19 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see files from repository in markdown' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown") - page.should have_content "README.md" - page.should have_content "CHANGELOG" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown") + expect(page).to have_content "README.md" + expect(page).to have_content "CHANGELOG" end step 'I should see rendered README which contains correct links' do - page.should have_content "Welcome to GitLab GitLab is a free project and repository management application" - page.should have_link "GitLab API doc" - page.should have_link "GitLab API website" - page.should have_link "Rake tasks" - page.should have_link "backup and restore procedure" - page.should have_link "GitLab API doc directory" - page.should have_link "Maintenance" + expect(page).to have_content "Welcome to GitLab GitLab is a free project and repository management application" + expect(page).to have_link "GitLab API doc" + expect(page).to have_link "GitLab API website" + expect(page).to have_link "Rake tasks" + expect(page).to have_link "backup and restore procedure" + expect(page).to have_link "GitLab API doc directory" + expect(page).to have_link "Maintenance" end step 'I click on Gitlab API in README' do @@ -33,8 +33,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct document rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(page).to have_content "All API requests require authentication" end step 'I click on Rake tasks in README' do @@ -42,9 +42,9 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct directory rendered' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") + expect(page).to have_content "backup_restore.md" + expect(page).to have_content "maintenance.md" end step 'I click on GitLab API doc directory in README' do @@ -52,9 +52,9 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct doc/api directory rendered' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - page.should have_content "README.md" - page.should have_content "users.md" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") + expect(page).to have_content "README.md" + expect(page).to have_content "users.md" end step 'I click on Maintenance in README' do @@ -62,8 +62,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct maintenance file rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/raketasks/maintenance.md") - page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/raketasks/maintenance.md") + expect(page).to have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" end step 'I click on link "empty" in the README' do @@ -93,10 +93,10 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see correct file rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(page).to have_content "Contents" + expect(page).to have_link "Users" + expect(page).to have_link "Rake tasks" end step 'I click on users in doc/api/README' do @@ -104,8 +104,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see the correct document file' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(page).to have_content "Get a list of users." end step 'I click on raketasks in doc/api/README' do @@ -131,32 +131,32 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see files from repository in markdown branch' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown") - page.should have_content "README.md" - page.should have_content "CHANGELOG" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown") + expect(page).to have_content "README.md" + expect(page).to have_content "CHANGELOG" end step 'I see correct file rendered in markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(page).to have_content "Contents" + expect(page).to have_link "Users" + expect(page).to have_link "Rake tasks" end step 'I should see correct document rendered for markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(page).to have_content "All API requests require authentication" end step 'I should see correct directory rendered for markdown branch' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") + expect(page).to have_content "backup_restore.md" + expect(page).to have_content "maintenance.md" end step 'I should see the users document file in markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(page).to have_content "Get a list of users." end # Expected link contents @@ -208,7 +208,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'I go to wiki page' do click_link "Wiki" - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") end step 'I add various links to the wiki page' do @@ -218,8 +218,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'Wiki page should have added links' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") - page.should have_content "test GitLab API doc Rake tasks" + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") + expect(page).to have_content "test GitLab API doc Rake tasks" end step 'I add a header to the wiki page' do @@ -237,13 +237,13 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see new wiki page named test' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "test") - page.should have_content "Editing" + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "test") + expect(page).to have_content "Editing" end When 'I go back to wiki page home' do visit namespace_project_wiki_path(@project.namespace, @project, "home") - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") end step 'I click on GitLab API doc link' do @@ -251,8 +251,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see Gitlab API document' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "api") - page.should have_content "Editing" + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "api") + expect(page).to have_content "Editing" end step 'I click on Rake tasks link' do @@ -260,13 +260,13 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see Rake tasks directory' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "raketasks") - page.should have_content "Editing" + expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "raketasks") + expect(page).to have_content "Editing" end step 'I go directory which contains README file' do visit namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") + expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") end step 'I click on a relative link in README' do @@ -274,8 +274,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see the correct markdown' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "List users" + expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(page).to have_content "List users" end step 'Header "Application details" should have correct id and link' do diff --git a/features/steps/project/source/multiselect_blob.rb b/features/steps/project/source/multiselect_blob.rb index b749ba4937..212537fc33 100644 --- a/features/steps/project/source/multiselect_blob.rb +++ b/features/steps/project/source/multiselect_blob.rb @@ -23,7 +23,7 @@ class Spinach::Features::ProjectSourceMultiselectBlob < Spinach::FeatureSteps pluralization = range.kind_of?(Array) ? "s" : "" step "I should see \"#{fragment}\" as URI fragment" do - URI.parse(current_url).fragment.should == fragment + expect(URI.parse(current_url).fragment).to eq fragment end step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do @@ -35,7 +35,7 @@ class Spinach::Features::ProjectSourceMultiselectBlob < Spinach::FeatureSteps extra ||= ids.delete(element[:id]).nil? end - extra.should be_false and ids.should be_empty + expect(extra).to be_false and ids.should be_empty end end end diff --git a/features/steps/project/source/search_code.rb b/features/steps/project/source/search_code.rb index b66c5a4123..feee756d7e 100644 --- a/features/steps/project/source/search_code.rb +++ b/features/steps/project/source/search_code.rb @@ -9,11 +9,11 @@ class Spinach::Features::ProjectSourceSearchCode < Spinach::FeatureSteps end step 'I should see files from repository containing "coffee"' do - page.should have_content 'coffee' - page.should have_content 'CONTRIBUTING.md' + expect(page).to have_content 'coffee' + expect(page).to have_content 'CONTRIBUTING.md' end step 'I should see empty result' do - page.should have_content "We couldn't find any" + expect(page).to have_content "We couldn't find any" end end diff --git a/features/steps/project/star.rb b/features/steps/project/star.rb index 50cdfd73c3..8b50bfcef0 100644 --- a/features/steps/project/star.rb +++ b/features/steps/project/star.rb @@ -5,7 +5,7 @@ class Spinach::Features::ProjectStar < Spinach::FeatureSteps include SharedUser step "The project has no stars" do - page.should_not have_content '.star-buttons' + expect(page).not_to have_content '.star-buttons' end step "The project has 0 stars" do @@ -26,7 +26,7 @@ class Spinach::Features::ProjectStar < Spinach::FeatureSteps end step 'I redirected to sign in page' do - current_path.should == new_user_session_path + expect(current_path).to eq new_user_session_path end protected diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 09e5af3ef4..4f4329359f 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -5,14 +5,14 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps include Select2Helper step 'I should be able to see myself in team' do - page.should have_content(@user.name) - page.should have_content(@user.username) + expect(page).to have_content(@user.name) + expect(page).to have_content(@user.username) end step 'I should see "Dmitriy" in team list' do user = User.find_by(name: "Dmitriy") - page.should have_content(user.name) - page.should have_content(user.username) + expect(page).to have_content(user.name) + expect(page).to have_content(user.username) end step 'I click link "Add members"' do @@ -31,7 +31,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I should see "Mike" in team list as "Reporter"' do within ".access-reporter" do - page.should have_content('Mike') + expect(page).to have_content('Mike') end end @@ -45,15 +45,15 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do within ".access-reporter" do - page.should have_content('sjobs@apple.com') - page.should have_content('invited') - page.should have_content('Reporter') + expect(page).to have_content('sjobs@apple.com') + expect(page).to have_content('invited') + expect(page).to have_content('Reporter') end end step 'I should see "Dmitriy" in team list as "Developer"' do within ".access-developer" do - page.should have_content('Dmitriy') + expect(page).to have_content('Dmitriy') end end @@ -70,7 +70,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I should see "Dmitriy" in team list as "Reporter"' do within ".access-reporter" do - page.should have_content('Dmitriy') + expect(page).to have_content('Dmitriy') end end @@ -80,8 +80,8 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I should not see "Dmitriy" in team list' do user = User.find_by(name: "Dmitriy") - page.should_not have_content(user.name) - page.should_not have_content(user.username) + expect(page).not_to have_content(user.name) + expect(page).not_to have_content(user.username) end step 'gitlab user "Mike"' do diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 58cb0ceb3f..c6062e2f13 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -12,7 +12,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should be redirected back to the Edit Home Wiki page' do - current_path.should == namespace_project_wiki_path(project.namespace, project, :home) + expect(current_path).to eq namespace_project_wiki_path(project.namespace, project, :home) end step 'I create the Wiki Home page' do @@ -21,11 +21,11 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see the newly created wiki page' do - page.should have_content "Home" - page.should have_content "link test" + expect(page).to have_content "Home" + expect(page).to have_content "link test" click_link "link test" - page.should have_content "Editing" + expect(page).to have_content "Editing" end step 'I have an existing Wiki page' do @@ -47,11 +47,11 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see the updated content' do - page.should have_content "Updated Wiki Content" + expect(page).to have_content "Updated Wiki Content" end step 'I should be redirected back to that Wiki page' do - current_path.should == namespace_project_wiki_path(project.namespace, project, @page) + expect(current_path).to eq namespace_project_wiki_path(project.namespace, project, @page) end step 'That page has two revisions' do @@ -63,9 +63,9 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see both revisions' do - page.should have_content current_user.name - page.should have_content "first commit" - page.should have_content "second commit" + expect(page).to have_content current_user.name + expect(page).to have_content "first commit" + expect(page).to have_content "second commit" end step 'I click on the "Delete this page" button' do @@ -73,7 +73,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'The page should be deleted' do - page.should have_content "Page was successfully deleted" + expect(page).to have_content "Page was successfully deleted" end step 'I click on the "Pages" button' do @@ -81,8 +81,8 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see the existing page in the pages list' do - page.should have_content current_user.name - page.should have_content @page.title + expect(page).to have_content current_user.name + expect(page).to have_content @page.title end step 'I have an existing Wiki page with images linked on page' do @@ -98,30 +98,30 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps file = Gollum::File.new(wiki.wiki) Gollum::Wiki.any_instance.stub(:file).with("image.jpg", "master", true).and_return(file) Gollum::File.any_instance.stub(:mime_type).and_return("image/jpeg") - page.should have_link('image', href: "image.jpg") + expect(page).to have_link('image', href: "image.jpg") click_on "image" end step 'I should see the image from wiki repo' do - current_path.should match('wikis/image.jpg') - page.should_not have_xpath('/html') # Page should render the image which means there is no html involved + expect(current_path).to match('wikis/image.jpg') + expect(page).not_to have_xpath('/html') # Page should render the image which means there is no html involved Gollum::Wiki.any_instance.unstub(:file) Gollum::File.any_instance.unstub(:mime_type) end step 'Image should be shown on the page' do - page.should have_xpath("//img[@src=\"image.jpg\"]") + expect(page).to have_xpath("//img[@src=\"image.jpg\"]") end step 'I click on image link' do - page.should have_link('image', href: "image.jpg") + expect(page).to have_link('image', href: "image.jpg") click_on "image" end step 'I should see the new wiki page form' do - current_path.should match('wikis/image.jpg') - page.should have_content('New Wiki Page') - page.should have_content('Editing - image.jpg') + expect(current_path).to match('wikis/image.jpg') + expect(page).to have_content('New Wiki Page') + expect(page).to have_content('Editing - image.jpg') end step 'I create a New page with paths' do @@ -130,7 +130,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps click_on 'Build' fill_in "wiki_content", with: 'wiki content' click_on "Create page" - current_path.should include 'one/two/three' + expect(current_path).to include 'one/two/three' end step 'I create a New page with an invalid name' do @@ -144,7 +144,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see non-escaped link in the pages list' do - page.should have_xpath("//a[@href='/#{project.path_with_namespace}/wikis/one/two/three']") + expect(page).to have_xpath("//a[@href='/#{project.path_with_namespace}/wikis/one/two/three']") end step 'I edit the Wiki page with a path' do @@ -153,11 +153,11 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see a non-escaped path' do - current_path.should include 'one/two/three' + expect(current_path).to include 'one/two/three' end step 'I should see the Editing page' do - page.should have_content('Editing') + expect(page).to have_content('Editing') end step 'I view the page history of a Wiki page that has a path' do @@ -166,7 +166,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should see the page history' do - page.should have_content('History for') + expect(page).to have_content('History for') end step 'I search for Wiki content' do diff --git a/features/steps/search.rb b/features/steps/search.rb index 8197cd410a..3703a7565d 100644 --- a/features/steps/search.rb +++ b/features/steps/search.rb @@ -48,11 +48,11 @@ class Spinach::Features::Search < Spinach::FeatureSteps end step 'I should see "Shop" project link' do - page.should have_link "Shop" + expect(page).to have_link "Shop" end step 'I should see code results for project "Shop"' do - page.should have_content 'Update capybara, rspec-rails, poltergeist to recent versions' + expect(page).to have_content 'Update capybara, rspec-rails, poltergeist to recent versions' end step 'I search for "Contibuting"' do @@ -71,15 +71,15 @@ class Spinach::Features::Search < Spinach::FeatureSteps end step 'I should see "Foo" link in the search results' do - find(:css, '.search-results').should have_link 'Foo' + expect(find(:css, '.search-results')).to have_link 'Foo' end step 'I should not see "Bar" link in the search results' do - find(:css, '.search-results').should_not have_link 'Bar' + expect(find(:css, '.search-results')).not_to have_link 'Bar' end step 'I should see "test_wiki" link in the search results' do - find(:css, '.search-results').should have_link 'test_wiki.md' + expect(find(:css, '.search-results')).to have_link 'test_wiki.md' end step 'project has Wiki content' do diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb index 9beb688bd1..72d873caa5 100644 --- a/features/steps/shared/active_tab.rb +++ b/features/steps/shared/active_tab.rb @@ -2,27 +2,27 @@ module SharedActiveTab include Spinach::DSL def ensure_active_main_tab(content) - find('.nav-sidebar > li.active').should have_content(content) + expect(find('.nav-sidebar > li.active')).to have_content(content) end def ensure_active_sub_tab(content) - find('div.content ul.nav-tabs li.active').should have_content(content) + expect(find('div.content ul.nav-tabs li.active')).to have_content(content) end def ensure_active_sub_nav(content) - find('.sidebar-subnav > li.active').should have_content(content) + expect(find('.sidebar-subnav > li.active')).to have_content(content) end step 'no other main tabs should be active' do - page.should have_selector('.nav-sidebar > li.active', count: 1) + expect(page).to have_selector('.nav-sidebar > li.active', count: 1) end step 'no other sub tabs should be active' do - page.should have_selector('div.content ul.nav-tabs li.active', count: 1) + expect(page).to have_selector('div.content ul.nav-tabs li.active', count: 1) end step 'no other sub navs should be active' do - page.should have_selector('.sidebar-subnav > li.active', count: 1) + expect(page).to have_selector('.sidebar-subnav > li.active', count: 1) end step 'the active main tab should be Home' do diff --git a/features/steps/shared/authentication.rb b/features/steps/shared/authentication.rb index ac8a3df6bb..3c0f2a9406 100644 --- a/features/steps/shared/authentication.rb +++ b/features/steps/shared/authentication.rb @@ -21,7 +21,7 @@ module SharedAuthentication end step 'I should be redirected to sign in page' do - current_path.should == new_user_session_path + expect(current_path).to eq new_user_session_path end step "I logout" do diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index 510e0f0f93..5b75e45e18 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -67,7 +67,7 @@ module SharedDiffNote step 'I should not see the diff comment form' do within(diff_file_selector) do - page.should_not have_css("form.new_note") + expect(page).not_to have_css("form.new_note") end end @@ -86,47 +86,47 @@ module SharedDiffNote step 'I should only see one diff form' do within(diff_file_selector) do - page.should have_css("form.new_note", count: 1) + expect(page).to have_css("form.new_note", count: 1) end end step 'I should see a diff comment form with ":-1: I don\'t like this"' do within(diff_file_selector) do - page.should have_field("note[note]", with: ":-1: I don\'t like this") + expect(page).to have_field("note[note]", with: ":-1: I don\'t like this") end end step 'I should see a diff comment saying "Typo, please fix"' do within("#{diff_file_selector} .note") do - page.should have_content("Typo, please fix") + expect(page).to have_content("Typo, please fix") end end step 'I should see a discussion reply button' do within(diff_file_selector) do - page.should have_button('Reply') + expect(page).to have_button('Reply') end end step 'I should see a temporary diff comment form' do within(diff_file_selector) do - page.should have_css(".js-temp-notes-holder form.new_note") + expect(page).to have_css(".js-temp-notes-holder form.new_note") end end step 'I should see add a diff comment button' do - page.should have_css('.js-add-diff-note-button', visible: true) + expect(page).to have_css('.js-add-diff-note-button', visible: true) end step 'I should see an empty diff comment form' do within(diff_file_selector) do - page.should have_field("note[note]", with: "") + expect(page).to have_field("note[note]", with: "") end end step 'I should see the cancel comment button' do within("#{diff_file_selector} form") do - page.should have_css(".js-close-discussion-note-form", text: "Cancel") + expect(page).to have_css(".js-close-discussion-note-form", text: "Cancel") end end diff --git a/features/steps/shared/group.rb b/features/steps/shared/group.rb index 1b225dd61a..2d17fb34cc 100644 --- a/features/steps/shared/group.rb +++ b/features/steps/shared/group.rb @@ -22,11 +22,11 @@ module SharedGroup end step 'I should see group "TestGroup"' do - page.should have_content "TestGroup" + expect(page).to have_content "TestGroup" end step 'I should not see group "TestGroup"' do - page.should_not have_content "TestGroup" + expect(page).not_to have_content "TestGroup" end protected diff --git a/features/steps/shared/markdown.rb b/features/steps/shared/markdown.rb index 943640007a..34172f5bb5 100644 --- a/features/steps/shared/markdown.rb +++ b/features/steps/shared/markdown.rb @@ -3,11 +3,11 @@ module SharedMarkdown def header_should_have_correct_id_and_link(level, text, id, parent = ".wiki") node = find("#{parent} h#{level} a##{id}") - node[:href].should == "##{id}" + expect(node[:href]).to eq "##{id}" # Work around a weird Capybara behavior where calling `parent` on a node # returns the whole document, not the node's actual parent element - find(:xpath, "#{node.path}/..").text.should == text + expect(find(:xpath, "#{node.path}/..").text).to eq text end step 'Header "Description header" should have correct id and link' do diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index 2f66e61b21..59dca1db70 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -40,7 +40,7 @@ module SharedNote end step 'I should not see a comment saying "XML attached"' do - page.should_not have_css(".note") + expect(page).not_to have_css(".note") end step 'I should not see the cancel comment button' do @@ -70,13 +70,13 @@ module SharedNote step 'I should see a comment saying "XML attached"' do within(".note") do - page.should have_content("XML attached") + expect(page).to have_content("XML attached") end end step 'I should see an empty comment text field' do within(".js-main-target-form") do - page.should have_field("note[note]", with: "") + expect(page).to have_field("note[note]", with: "") end end @@ -101,7 +101,7 @@ module SharedNote step 'I should see comment "XML attached"' do within(".note") do - page.should have_content("XML attached") + expect(page).to have_content("XML attached") end end @@ -117,8 +117,8 @@ module SharedNote step 'The comment with the header should not have an ID' do within(".note-body > .note-text") do - page.should have_content("Comment with a header") - page.should_not have_css("#comment-with-a-header") + expect(page).to have_content("Comment with a header") + expect(page).not_to have_css("#comment-with-a-header") end end @@ -135,7 +135,7 @@ module SharedNote step 'I should see +1 in the description' do within(".note") do - page.should have_content("+1 Awesome!") + expect(page).to have_content("+1 Awesome!") end end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 4649387680..09ae7e3a30 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -92,7 +92,7 @@ module SharedPaths end step 'I should be redirected to the dashboard groups page' do - current_path.should == dashboard_groups_path + expect(current_path).to eq dashboard_groups_path end step 'I visit dashboard starred projects page' do @@ -292,11 +292,11 @@ module SharedPaths end step 'I am on the new file page' do - current_path.should eq(namespace_project_create_blob_path(@project.namespace, @project, root_ref)) + expect(current_path).to eq(namespace_project_create_blob_path(@project.namespace, @project, root_ref)) end step 'I am on the ".gitignore" edit file page' do - current_path.should eq(namespace_project_edit_blob_path( + expect(current_path).to eq(namespace_project_edit_blob_path( @project.namespace, @project, File.join(root_ref, '.gitignore'))) end @@ -459,6 +459,6 @@ module SharedPaths # ---------------------------------------- step 'page status code should be 404' do - status_code.should == 404 + expect(status_code).to eq 404 end end diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index 3059c4ee04..9ee2e5dfbe 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -79,13 +79,13 @@ module SharedProject step 'I should see project "Shop" activity feed' do project = Project.find_by(name: "Shop") - page.should have_content "#{@user.name} pushed new branch fix at #{project.name_with_namespace}" + expect(page).to have_content "#{@user.name} pushed new branch fix at #{project.name_with_namespace}" end step 'I should see project settings' do - current_path.should == edit_namespace_project_path(@project.namespace, @project) - page.should have_content("Project name") - page.should have_content("Features:") + expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project) + expect(page).to have_content("Project name") + expect(page).to have_content("Features:") end def current_project @@ -101,11 +101,11 @@ module SharedProject end step 'I should see project "Enterprise"' do - page.should have_content "Enterprise" + expect(page).to have_content "Enterprise" end step 'I should not see project "Enterprise"' do - page.should_not have_content "Enterprise" + expect(page).not_to have_content "Enterprise" end step 'internal project "Internal"' do @@ -113,11 +113,11 @@ module SharedProject end step 'I should see project "Internal"' do - page.should have_content "Internal" + expect(page).to have_content "Internal" end step 'I should not see project "Internal"' do - page.should_not have_content "Internal" + expect(page).not_to have_content "Internal" end step 'public project "Community"' do @@ -125,11 +125,11 @@ module SharedProject end step 'I should see project "Community"' do - page.should have_content "Community" + expect(page).to have_content "Community" end step 'I should not see project "Community"' do - page.should_not have_content "Community" + expect(page).not_to have_content "Community" end step '"John Doe" owns private project "Enterprise"' do diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index 71fe89f634..ce8cbe80aa 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -46,7 +46,7 @@ module SharedProjectTab step 'the active main tab should be Settings' do within '.nav-sidebar' do - page.should have_content('Back to project') + expect(page).to have_content('Back to project') end end end diff --git a/features/steps/snippet_search.rb b/features/steps/snippet_search.rb index 669c7186c1..cf99987957 100644 --- a/features/steps/snippet_search.rb +++ b/features/steps/snippet_search.rb @@ -18,39 +18,39 @@ class Spinach::Features::SnippetSearch < Spinach::FeatureSteps end step 'I should see "line seven" in results' do - page.should have_content 'line seven' + expect(page).to have_content 'line seven' end step 'I should see "line four" in results' do - page.should have_content 'line four' + expect(page).to have_content 'line four' end step 'I should see "line ten" in results' do - page.should have_content 'line ten' + expect(page).to have_content 'line ten' end step 'I should not see "line eleven" in results' do - page.should_not have_content 'line eleven' + expect(page).not_to have_content 'line eleven' end step 'I should not see "line three" in results' do - page.should_not have_content 'line three' + expect(page).not_to have_content 'line three' end step 'I should see "Personal snippet one" in results' do - page.should have_content 'Personal snippet one' + expect(page).to have_content 'Personal snippet one' end step 'I should see "Personal snippet private" in results' do - page.should have_content 'Personal snippet private' + expect(page).to have_content 'Personal snippet private' end step 'I should not see "Personal snippet one" in results' do - page.should_not have_content 'Personal snippet one' + expect(page).not_to have_content 'Personal snippet one' end step 'I should not see "Personal snippet private" in results' do - page.should_not have_content 'Personal snippet private' + expect(page).not_to have_content 'Personal snippet private' end end diff --git a/features/steps/snippets/discover.rb b/features/steps/snippets/discover.rb index 2667c1e3d4..76379d09d0 100644 --- a/features/steps/snippets/discover.rb +++ b/features/steps/snippets/discover.rb @@ -4,15 +4,15 @@ class Spinach::Features::SnippetsDiscover < Spinach::FeatureSteps include SharedSnippet step 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" + expect(page).to have_content "Personal snippet one" end step 'I should see "Personal snippet internal" in snippets' do - page.should have_content "Personal snippet internal" + expect(page).to have_content "Personal snippet internal" end step 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" + expect(page).not_to have_content "Personal snippet private" end def snippet diff --git a/features/steps/snippets/public_snippets.rb b/features/steps/snippets/public_snippets.rb index 67669dc0a6..2ebdca5ed3 100644 --- a/features/steps/snippets/public_snippets.rb +++ b/features/steps/snippets/public_snippets.rb @@ -4,11 +4,11 @@ class Spinach::Features::PublicSnippets < Spinach::FeatureSteps include SharedSnippet step 'I should see snippet "Personal snippet one"' do - page.should have_no_xpath("//i[@class='public-snippet']") + expect(page).to have_no_xpath("//i[@class='public-snippet']") end step 'I should see raw snippet "Personal snippet one"' do - page.should have_text(snippet.content) + expect(page).to have_text(snippet.content) end step 'I visit snippet page "Personal snippet one"' do diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index de936db85e..0f56fb0306 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -9,7 +9,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I should not see "Personal snippet one" in snippets' do - page.should_not have_content "Personal snippet one" + expect(page).not_to have_content "Personal snippet one" end step 'I click link "Edit"' do @@ -32,8 +32,8 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I should see snippet "Personal snippet three"' do - page.should have_content "Personal snippet three" - page.should have_content "Content of snippet three" + expect(page).to have_content "Personal snippet three" + expect(page).to have_content "Content of snippet three" end step 'I submit new title "Personal snippet new title"' do @@ -42,7 +42,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I should see "Personal snippet new title"' do - page.should have_content "Personal snippet new title" + expect(page).to have_content "Personal snippet new title" end step 'I uncheck "Private" checkbox' do @@ -51,7 +51,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I should see "Personal snippet one" public' do - page.should have_no_xpath("//i[@class='public-snippet']") + expect(page).to have_no_xpath("//i[@class='public-snippet']") end step 'I visit snippet page "Personal snippet one"' do diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index 146cc535d8..e6c6ec27e7 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -8,27 +8,27 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps end step 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" + expect(page).to have_content "Personal snippet one" end step 'I should see "Personal snippet private" in snippets' do - page.should have_content "Personal snippet private" + expect(page).to have_content "Personal snippet private" end step 'I should see "Personal snippet internal" in snippets' do - page.should have_content "Personal snippet internal" + expect(page).to have_content "Personal snippet internal" end step 'I should not see "Personal snippet one" in snippets' do - page.should_not have_content "Personal snippet one" + expect(page).not_to have_content "Personal snippet one" end step 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" + expect(page).not_to have_content "Personal snippet private" end step 'I should not see "Personal snippet internal" in snippets' do - page.should_not have_content "Personal snippet internal" + expect(page).not_to have_content "Personal snippet internal" end step 'I click "Internal" filter' do diff --git a/features/steps/user.rb b/features/steps/user.rb index 10cae692a8..5cbbecc749 100644 --- a/features/steps/user.rb +++ b/features/steps/user.rb @@ -29,12 +29,12 @@ class Spinach::Features::User < Spinach::FeatureSteps step 'I should see contributed projects' do within '.contributed-projects' do - page.should have_content(@contributed_project.name) + expect(page).to have_content(@contributed_project.name) end end step 'I should see contributions calendar' do - page.should have_css('.cal-heatmap-container') + expect(page).to have_css('.cal-heatmap-container') end def contributed_project From 584f8601eff79fe6e400026ba6db086002ce2cba Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Fri, 12 Jun 2015 01:36:00 -0400 Subject: [PATCH 47/51] Change `within` to `page.within` in feature steps --- features/steps/admin/applications.rb | 2 +- features/steps/admin/groups.rb | 8 ++-- features/steps/admin/users.rb | 2 +- features/steps/dashboard/new_project.rb | 2 +- features/steps/dashboard/starred_projects.rb | 2 +- features/steps/explore/projects.rb | 4 +- features/steps/groups.rb | 14 +++---- features/steps/profile/profile.rb | 16 +++---- features/steps/project/active_tab.rb | 2 +- features/steps/project/commits/branches.rb | 4 +- features/steps/project/commits/commits.rb | 2 +- features/steps/project/commits/tags.rb | 8 ++-- features/steps/project/deploy_keys.rb | 12 +++--- features/steps/project/fork.rb | 2 +- .../steps/project/issues/filter_labels.rb | 10 ++--- features/steps/project/issues/issues.rb | 8 ++-- features/steps/project/issues/labels.rb | 20 ++++----- features/steps/project/merge_requests.rb | 38 ++++++++--------- features/steps/project/network_graph.rb | 14 +++---- features/steps/project/project.rb | 2 +- features/steps/project/redirects.rb | 2 +- features/steps/project/snippets.rb | 6 +-- features/steps/project/source/browse_files.rb | 2 +- .../steps/project/source/markdown_render.rb | 10 ++--- features/steps/project/team_management.rb | 16 +++---- features/steps/project/wiki.rb | 2 +- features/steps/search.rb | 8 ++-- features/steps/shared/diff_note.rb | 42 +++++++++---------- features/steps/shared/markdown.rb | 6 +-- features/steps/shared/note.rb | 38 ++++++++--------- features/steps/shared/project_tab.rb | 2 +- features/steps/snippets/snippets.rb | 4 +- features/steps/snippets/user.rb | 6 +-- features/steps/user.rb | 2 +- 34 files changed, 159 insertions(+), 159 deletions(-) diff --git a/features/steps/admin/applications.rb b/features/steps/admin/applications.rb index e092a4b36c..7c12cb9692 100644 --- a/features/steps/admin/applications.rb +++ b/features/steps/admin/applications.rb @@ -44,7 +44,7 @@ class Spinach::Features::AdminApplications < Spinach::FeatureSteps end step 'I click to remove application' do - within '.oauth-applications' do + page.within '.oauth-applications' do click_on "Destroy" end end diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb index 743c3ecce8..9cc74a97c3 100644 --- a/features/steps/admin/groups.rb +++ b/features/steps/admin/groups.rb @@ -38,14 +38,14 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps When 'I select user "John Doe" from user list as "Reporter"' do select2(user_john.id, from: "#user_ids", multiple: true) - within "#new_project_member" do + page.within "#new_project_member" do select "Reporter", from: "access_level" end click_button "Add users to group" end step 'I should see "John Doe" in team list in every project as "Reporter"' do - within ".group-users-list" do + page.within ".group-users-list" do expect(page).to have_content "John Doe" expect(page).to have_content "Reporter" end @@ -62,13 +62,13 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps end step 'I remove user "John Doe" from group' do - within "#user_#{user_john.id}" do + page.within "#user_#{user_john.id}" do click_link 'Remove user from group' end end step 'I should not see "John Doe" in team list' do - within ".group-users-list" do + page.within ".group-users-list" do expect(page).not_to have_content "John Doe" end end diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb index 8b6bdf219b..34a3ed9f61 100644 --- a/features/steps/admin/users.rb +++ b/features/steps/admin/users.rb @@ -23,7 +23,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps end step 'See username error message' do - within "#error_explanation" do + page.within "#error_explanation" do expect(page).to have_content "Username" end end diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb index 07da5f9587..ea89ad215c 100644 --- a/features/steps/dashboard/new_project.rb +++ b/features/steps/dashboard/new_project.rb @@ -4,7 +4,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps include SharedProject step 'I click "New project" link' do - within('.content') do + page.within('.content') do click_link "New project" end end diff --git a/features/steps/dashboard/starred_projects.rb b/features/steps/dashboard/starred_projects.rb index b098bbc47d..59c73fe63f 100644 --- a/features/steps/dashboard/starred_projects.rb +++ b/features/steps/dashboard/starred_projects.rb @@ -8,7 +8,7 @@ class Spinach::Features::DashboardStarredProjects < Spinach::FeatureSteps end step 'I should not see project "Shop"' do - within 'aside' do + page.within 'aside' do expect(page).not_to have_content('Shop') end end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index c722e2ec41..17c16c3fb1 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -35,13 +35,13 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I should see project "Community" home page' do - within '.navbar-gitlab .title' do + page.within '.navbar-gitlab .title' do expect(page).to have_content 'Community' end end step 'I should see project "Internal" home page' do - within '.navbar-gitlab .title' do + page.within '.navbar-gitlab .title' do expect(page).to have_content 'Internal' end end diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 3ea31de882..c6c855a7c2 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -16,7 +16,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I select "Mike" as "Reporter"' do user = User.find_by(name: "Mike") - within ".users-group-form" do + page.within ".users-group-form" do select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end @@ -25,14 +25,14 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see "Mike" in team list as "Reporter"' do - within '.well-list' do + page.within '.well-list' do expect(page).to have_content('Mike') expect(page).to have_content('Reporter') end end step 'I select "sjobs@apple.com" as "Reporter"' do - within ".users-group-form" do + page.within ".users-group-form" do select2("sjobs@apple.com", from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end @@ -41,7 +41,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do - within '.well-list' do + page.within '.well-list' do expect(page).to have_content('sjobs@apple.com') expect(page).to have_content('invited') expect(page).to have_content('Reporter') @@ -73,7 +73,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps step 'I select user "Mary Jane" from list with role "Reporter"' do user = User.find_by(name: "Mary Jane") || create(:user, name: "Mary Jane") click_button 'Add members' - within ".users-group-form" do + page.within ".users-group-form" do select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end @@ -122,7 +122,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I should see new group "Owned" name' do - within ".navbar-gitlab" do + page.within ".navbar-gitlab" do expect(page).to have_content "new-name" end end @@ -182,7 +182,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps end step 'I search for \'Mary\' member' do - within '.member-search-form' do + page.within '.member-search-form' do fill_in 'search', with: 'Mary' click_button 'Search' end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index c35eb593f4..32e6859eff 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -61,7 +61,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I try change my password w/o old one' do - within '.update-password' do + page.within '.update-password' do fill_in "user_password", with: "22233344" fill_in "user_password_confirmation", with: "22233344" click_button "Save" @@ -69,7 +69,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I change my password' do - within '.update-password' do + page.within '.update-password' do fill_in "user_current_password", with: "12345678" fill_in "user_password", with: "22233344" fill_in "user_password_confirmation", with: "22233344" @@ -78,7 +78,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I unsuccessfully change my password' do - within '.update-password' do + page.within '.update-password' do fill_in "user_current_password", with: "12345678" fill_in "user_password", with: "password" fill_in "user_password_confirmation", with: "confirmation" @@ -95,7 +95,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I reset my token' do - within '.update-token' do + page.within '.update-token' do @old_token = @user.private_token click_button "Reset" end @@ -115,13 +115,13 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step "I change my application theme" do - within '.application-theme' do + page.within '.application-theme' do choose "Violet" end end step "I change my code preview theme" do - within '.code-preview-theme' do + page.within '.code-preview-theme' do choose "Solarized dark" end end @@ -174,7 +174,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps step 'I should see my user page' do expect(page).to have_content "User Activity" - within '.navbar-gitlab' do + page.within '.navbar-gitlab' do expect(page).to have_content current_user.name end end @@ -233,7 +233,7 @@ class Spinach::Features::Profile < Spinach::FeatureSteps end step 'I click to remove application' do - within '.oauth-applications' do + page.within '.oauth-applications' do click_on "Destroy" end end diff --git a/features/steps/project/active_tab.rb b/features/steps/project/active_tab.rb index dd3215adb1..fabbc1d3d8 100644 --- a/features/steps/project/active_tab.rb +++ b/features/steps/project/active_tab.rb @@ -20,7 +20,7 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps end step 'I click the "Edit" tab' do - within '.project-settings-nav' do + page.within '.project-settings-nav' do click_link('Project') end end diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index c4da380a71..ff5baf5dda 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -17,7 +17,7 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step 'I should see "Shop" protected branches list' do - within ".protected-branches-list" do + page.within ".protected-branches-list" do expect(page).to have_content "stable" expect(page).not_to have_content "master" end @@ -73,7 +73,7 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step "I click branch 'improve/awesome' delete link" do - within '.js-branch-improve\/awesome' do + page.within '.js-branch-improve\/awesome' do find('.btn-remove').click sleep 0.05 end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index 55adb69541..f0acea1d47 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -45,7 +45,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I should see additional file lines' do - within @diff.parent do + page.within @diff.parent do expect(first('.new_line').text).not_to have_content "..." end end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb index e87bf799af..beecfd3a3c 100644 --- a/features/steps/project/commits/tags.rb +++ b/features/steps/project/commits/tags.rb @@ -53,20 +53,20 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps end step "I delete tag 'v1.1.0'" do - within '.tags' do + page.within '.tags' do first('.btn-remove').click sleep 0.05 end end step "I should not see tag 'v1.1.0'" do - within '.tags' do + page.within '.tags' do expect(all(visible: true)).not_to have_content 'v1.1.0' end end step 'I delete all tags' do - within '.tags' do + page.within '.tags' do all('.btn-remove').each do |remove| remove.click sleep 0.05 @@ -75,7 +75,7 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps end step 'I should see tags info message' do - within '.tags' do + page.within '.tags' do expect(page).to have_content 'Repository has no tags yet.' end end diff --git a/features/steps/project/deploy_keys.rb b/features/steps/project/deploy_keys.rb index 423e20a507..a4d6c9a1b8 100644 --- a/features/steps/project/deploy_keys.rb +++ b/features/steps/project/deploy_keys.rb @@ -8,19 +8,19 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I should see project deploy key' do - within '.enabled-keys' do + page.within '.enabled-keys' do expect(page).to have_content deploy_key.title end end step 'I should see other project deploy key' do - within '.available-keys' do + page.within '.available-keys' do expect(page).to have_content other_deploy_key.title end end step 'I should see public deploy key' do - within '.available-keys' do + page.within '.available-keys' do expect(page).to have_content public_deploy_key.title end end @@ -40,7 +40,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I should see newly created deploy key' do - within '.enabled-keys' do + page.within '.enabled-keys' do expect(page).to have_content(deploy_key.title) end end @@ -56,7 +56,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I should only see the same deploy key once' do - within '.available-keys' do + page.within '.available-keys' do expect(page).to have_selector('ul li', count: 1) end end @@ -66,7 +66,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I click attach deploy key' do - within '.available-keys' do + page.within '.available-keys' do click_link 'Enable' end end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 879b0e8129..0e433781d7 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -27,7 +27,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end step 'I fork to my namespace' do - within '.fork-namespaces' do + page.within '.fork-namespaces' do click_link current_user.name end end diff --git a/features/steps/project/issues/filter_labels.rb b/features/steps/project/issues/filter_labels.rb index 66a3c1ead6..50bb32429b 100644 --- a/features/steps/project/issues/filter_labels.rb +++ b/features/steps/project/issues/filter_labels.rb @@ -5,25 +5,25 @@ class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps include Select2Helper step 'I should see "Bugfix1" in issues list' do - within ".issues-list" do + page.within ".issues-list" do expect(page).to have_content "Bugfix1" end end step 'I should see "Bugfix2" in issues list' do - within ".issues-list" do + page.within ".issues-list" do expect(page).to have_content "Bugfix2" end end step 'I should not see "Bugfix2" in issues list' do - within ".issues-list" do + page.within ".issues-list" do expect(page).not_to have_content "Bugfix2" end end step 'I should not see "Feature1" in issues list' do - within ".issues-list" do + page.within ".issues-list" do expect(page).not_to have_content "Feature1" end end @@ -33,7 +33,7 @@ class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps end step 'I click link "feature"' do - within ".labels-filter" do + page.within ".labels-filter" do click_link "feature" end end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index 87a3d280cd..6a462fec26 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -87,7 +87,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I should see label \'bug\' with issue' do - within '.issue-show-labels' do + page.within '.issue-show-labels' do expect(page).to have_content 'bug' end end @@ -201,7 +201,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I leave a comment with code block' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in "note[note]", with: "```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```" click_button "Add Comment" sleep 0.05 @@ -209,7 +209,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I should see an error alert section within the comment form' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do find(".error-alert") end end @@ -257,7 +257,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end step 'I click label \'bug\'' do - within ".issues-list" do + page.within ".issues-list" do click_link 'bug' end end diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 4de8a39672..2828f02c44 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -8,13 +8,13 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps end step 'I remove label \'bug\'' do - within "#label_#{bug_label.id}" do + page.within "#label_#{bug_label.id}" do click_link 'Remove' end end step 'I delete all labels' do - within '.labels' do + page.within '.labels' do all('.btn-remove').each do |remove| remove.click sleep 0.05 @@ -23,7 +23,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps end step 'I should see labels help message' do - within '.labels' do + page.within '.labels' do expect(page).to have_content 'Create first label or generate default set of '\ 'labels' end @@ -48,37 +48,37 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps end step 'I should see label label exist error message' do - within '.label-form' do + page.within '.label-form' do expect(page).to have_content 'Title has already been taken' end end step 'I should see label color error message' do - within '.label-form' do + page.within '.label-form' do expect(page).to have_content 'Color is invalid' end end step 'I should see label \'feature\'' do - within '.manage-labels-list' do + page.within '.manage-labels-list' do expect(page).to have_content 'feature' end end step 'I should see label \'bug\'' do - within '.manage-labels-list' do + page.within '.manage-labels-list' do expect(page).to have_content 'bug' end end step 'I should not see label \'bug\'' do - within '.manage-labels-list' do + page.within '.manage-labels-list' do expect(page).not_to have_content 'bug' end end step 'I should see label \'support\'' do - within '.manage-labels-list' do + page.within '.manage-labels-list' do expect(page).to have_content 'support' end end @@ -90,7 +90,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps end step 'I should see label \'fix\'' do - within '.manage-labels-list' do + page.within '.manage-labels-list' do expect(page).to have_content 'fix' end end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index fe019a0b3a..6e8c5f5ddd 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -24,7 +24,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see merge request "Wiki Feature"' do - within '.merge-request' do + page.within '.merge-request' do expect(page).to have_content "Wiki Feature" end end @@ -113,7 +113,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click on the Changes tab via Javascript' do - within '.merge-request-tabs' do + page.within '.merge-request-tabs' do click_link 'Changes' end @@ -134,11 +134,11 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I click on the commit in the merge request' do - within '.merge-request-tabs' do + page.within '.merge-request-tabs' do click_link 'Commits' end - within '.commits' do + page.within '.commits' do click_link Commit.truncate_sha(sample_commit.id) end end @@ -199,13 +199,13 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps merge!: true, ) - within '.mr-state-widget' do + page.within '.mr-state-widget' do click_button "Accept Merge Request" end end step 'I should see merged request' do - within '.issue-box' do + page.within '.issue-box' do expect(page).to have_content "Accepted" end end @@ -215,43 +215,43 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see reopened merge request "Bug NS-04"' do - within '.issue-box' do + page.within '.issue-box' do expect(page).to have_content "Open" end end step 'I click link "Hide inline discussion" of the second file' do - within '.files [id^=diff]:nth-child(2)' do + page.within '.files [id^=diff]:nth-child(2)' do find('.js-toggle-diff-comments').click end end step 'I click link "Show inline discussion" of the second file' do - within '.files [id^=diff]:nth-child(2)' do + page.within '.files [id^=diff]:nth-child(2)' do find('.js-toggle-diff-comments').click end end step 'I should not see a comment like "Line is wrong" in the second file' do - within '.files [id^=diff]:nth-child(2)' do + page.within '.files [id^=diff]:nth-child(2)' do expect(page).not_to have_visible_content "Line is wrong" end end step 'I should see a comment like "Line is wrong" in the second file' do - within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do + page.within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do expect(page).to have_visible_content "Line is wrong" end end step 'I should not see a comment like "Line is wrong here" in the second file' do - within '.files [id^=diff]:nth-child(2)' do + page.within '.files [id^=diff]:nth-child(2)' do expect(page).not_to have_visible_content "Line is wrong here" end end step 'I should see a comment like "Line is wrong here" in the second file' do - within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do + page.within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do expect(page).to have_visible_content "Line is wrong here" end end @@ -259,12 +259,12 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I leave a comment like "Line is correct" on line 12 of the first file' do init_diff_note_first_file - within(".js-discussion-note-form") do + page.within(".js-discussion-note-form") do fill_in "note_note", with: "Line is correct" click_button "Add Comment" end - within ".files [id^=diff]:nth-child(1) .note-body > .note-text" do + page.within ".files [id^=diff]:nth-child(1) .note-body > .note-text" do expect(page).to have_content "Line is correct" end end @@ -272,14 +272,14 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I leave a comment like "Line is wrong" on line 39 of the second file' do init_diff_note_second_file - within(".js-discussion-note-form") do + page.within(".js-discussion-note-form") do fill_in "note_note", with: "Line is wrong on here" click_button "Add Comment" end end step 'I should still see a comment like "Line is correct" in the first file' do - within '.files [id^=diff]:nth-child(1) .note-body > .note-text' do + page.within '.files [id^=diff]:nth-child(1) .note-body > .note-text' do expect(page).to have_visible_content "Line is correct" end end @@ -297,7 +297,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see comments on the side-by-side diff page' do - within '.files [id^=diff]:nth-child(1) .parallel .note-body > .note-text' do + page.within '.files [id^=diff]:nth-child(1) .parallel .note-body > .note-text' do expect(page).to have_visible_content "Line is correct" end end @@ -329,7 +329,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end def leave_comment(message) - within(".js-discussion-note-form") do + page.within(".js-discussion-note-form") do fill_in "note_note", with: message click_button "Add Comment" end diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index 14b06917f0..992cf2734f 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -24,7 +24,7 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should have "master" on graph' do - within '.network-graph' do + page.within '.network-graph' do expect(page).to have_content 'master' end end @@ -45,13 +45,13 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should have content not containing "v1.0.0"' do - within '.network-graph' do + page.within '.network-graph' do expect(page).to have_content 'Change some files' end end step 'page should not have content not containing "v1.0.0"' do - within '.network-graph' do + page.within '.network-graph' do expect(page).not_to have_content 'Change some files' end end @@ -65,13 +65,13 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should have "feature" on graph' do - within '.network-graph' do + page.within '.network-graph' do expect(page).to have_content 'feature' end end When 'I looking for a commit by SHA of "v1.0.0"' do - within ".network-form" do + page.within ".network-form" do fill_in 'extended_sha1', with: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' find('button').click end @@ -79,13 +79,13 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps end step 'page should have "v1.0.0" on graph' do - within '.network-graph' do + page.within '.network-graph' do expect(page).to have_content 'v1.0.0' end end When 'I look for a commit by ";"' do - within ".network-form" do + page.within ".network-form" do fill_in 'extended_sha1', with: ';' find('button').click end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 126c9c0524..ee4c7cd0f0 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -67,7 +67,7 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see project "Shop" version' do - within '.project-side' do + page.within '.project-side' do expect(page).to have_content '6.7.0.pre' end end diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb index 373f5bb8ad..0e724138a8 100644 --- a/features/steps/project/redirects.rb +++ b/features/steps/project/redirects.rb @@ -18,7 +18,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I should see project "Community" home page' do Gitlab.config.gitlab.should_receive(:host).and_return("www.example.com") - within '.navbar-gitlab .title' do + page.within '.navbar-gitlab .title' do expect(page).to have_content 'Community' end end diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index ff3e14b53b..eedb4e1b74 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -42,7 +42,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I click link "Edit"' do - within ".file-title" do + page.within ".file-title" do click_link "Edit" end end @@ -54,7 +54,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps step 'I submit new snippet "Snippet three"' do fill_in "project_snippet_title", :with => "Snippet three" fill_in "project_snippet_file_name", :with => "my_snippet.rb" - within('.file-editor') do + page.within('.file-editor') do find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three' end click_button "Create snippet" @@ -75,7 +75,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I leave a comment like "Good snippet!"' do - within('.js-main-target-form') do + page.within('.js-main-target-form') do fill_in "note_note", with: "Good snippet!" click_button "Add Comment" end diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 58a6ef4f39..398c9bf575 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -124,7 +124,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I click on readme file' do - within '.tree-table' do + page.within '.tree-table' do click_link 'README.md' end end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index b6534f757c..c78e86fa1a 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -67,27 +67,27 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I click on link "empty" in the README' do - within('.readme-holder') do + page.within('.readme-holder') do click_link "empty" end end step 'I click on link "id" in the README' do - within('.readme-holder') do + page.within('.readme-holder') do click_link "#id" end end step 'I navigate to the doc/api/README' do - within '.tree-table' do + page.within '.tree-table' do click_link "doc" end - within '.tree-table' do + page.within '.tree-table' do click_link "api" end - within '.tree-table' do + page.within '.tree-table' do click_link "README.md" end end diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb index 4f4329359f..97d6301645 100644 --- a/features/steps/project/team_management.rb +++ b/features/steps/project/team_management.rb @@ -22,7 +22,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps step 'I select "Mike" as "Reporter"' do user = User.find_by(name: "Mike") - within ".users-project-form" do + page.within ".users-project-form" do select2(user.id, from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end @@ -30,13 +30,13 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I should see "Mike" in team list as "Reporter"' do - within ".access-reporter" do + page.within ".access-reporter" do expect(page).to have_content('Mike') end end step 'I select "sjobs@apple.com" as "Reporter"' do - within ".users-project-form" do + page.within ".users-project-form" do select2("sjobs@apple.com", from: "#user_ids", multiple: true) select "Reporter", from: "access_level" end @@ -44,7 +44,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do - within ".access-reporter" do + page.within ".access-reporter" do expect(page).to have_content('sjobs@apple.com') expect(page).to have_content('invited') expect(page).to have_content('Reporter') @@ -52,7 +52,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I should see "Dmitriy" in team list as "Developer"' do - within ".access-developer" do + page.within ".access-developer" do expect(page).to have_content('Dmitriy') end end @@ -61,7 +61,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps project = Project.find_by(name: "Shop") user = User.find_by(name: 'Dmitriy') project_member = project.project_members.find_by(user_id: user.id) - within "#project_member_#{project_member.id}" do + page.within "#project_member_#{project_member.id}" do click_button "Edit access level" select "Reporter", from: "project_member_access_level" click_button "Save" @@ -69,7 +69,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps end step 'I should see "Dmitriy" in team list as "Reporter"' do - within ".access-reporter" do + page.within ".access-reporter" do expect(page).to have_content('Dmitriy') end end @@ -123,7 +123,7 @@ class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps project = Project.find_by(name: "Shop") user = User.find_by(name: 'Dmitriy') project_member = project.project_members.find_by(user_id: user.id) - within "#project_member_#{project_member.id}" do + page.within "#project_member_#{project_member.id}" do click_link('Remove user from team') end end diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index c6062e2f13..eebfaee1ed 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -6,7 +6,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps include WikiHelper step 'I click on the Cancel button' do - within(:css, ".form-actions") do + page.within(:css, ".form-actions") do click_on "Cancel" end end diff --git a/features/steps/search.rb b/features/steps/search.rb index 3703a7565d..fec5d9f0e4 100644 --- a/features/steps/search.rb +++ b/features/steps/search.rb @@ -24,25 +24,25 @@ class Spinach::Features::Search < Spinach::FeatureSteps end step 'I click "Issues" link' do - within '.search-filter' do + page.within '.search-filter' do click_link 'Issues' end end step 'I click project "Shop" link' do - within '.project-filter' do + page.within '.project-filter' do click_link project.name_with_namespace end end step 'I click "Merge requests" link' do - within '.search-filter' do + page.within '.search-filter' do click_link 'Merge requests' end end step 'I click "Wiki" link' do - within '.search-filter' do + page.within '.search-filter' do click_link 'Wiki' end end diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb index 5b75e45e18..a716ca5837 100644 --- a/features/steps/shared/diff_note.rb +++ b/features/steps/shared/diff_note.rb @@ -3,7 +3,7 @@ module SharedDiffNote include RepoHelpers step 'I cancel the diff comment' do - within(diff_file_selector) do + page.within(diff_file_selector) do find(".js-close-discussion-note-form").click end end @@ -14,14 +14,14 @@ module SharedDiffNote end step 'I haven\'t written any diff comment text' do - within(diff_file_selector) do + page.within(diff_file_selector) do fill_in "note[note]", with: "" end end step 'I leave a diff comment like "Typo, please fix"' do click_diff_line(sample_commit.line_code) - within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "Typo, please fix" find(".js-comment-button").trigger("click") sleep 0.05 @@ -30,7 +30,7 @@ module SharedDiffNote step 'I preview a diff comment text like "Should fix it :smile:"' do click_diff_line(sample_commit.line_code) - within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do + page.within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do fill_in "note[note]", with: "Should fix it :smile:" find('.js-md-preview-button').click end @@ -39,7 +39,7 @@ module SharedDiffNote step 'I preview another diff comment text like "DRY this up"' do click_diff_line(sample_commit.del_line_code) - within("#{diff_file_selector} form[rel$='#{sample_commit.del_line_code}']") do + page.within("#{diff_file_selector} form[rel$='#{sample_commit.del_line_code}']") do fill_in "note[note]", with: "DRY this up" find('.js-md-preview-button').click end @@ -54,62 +54,62 @@ module SharedDiffNote end step 'I write a diff comment like ":-1: I don\'t like this"' do - within(diff_file_selector) do + page.within(diff_file_selector) do fill_in "note[note]", with: ":-1: I don\'t like this" end end step 'I submit the diff comment' do - within(diff_file_selector) do + page.within(diff_file_selector) do click_button("Add Comment") end end step 'I should not see the diff comment form' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).not_to have_css("form.new_note") end end step 'The diff comment preview tab should say there is nothing to do' do - within(diff_file_selector) do + page.within(diff_file_selector) do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_content('Nothing to preview.') end end step 'I should not see the diff comment text field' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(find('.js-note-text')).not_to be_visible end end step 'I should only see one diff form' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_css("form.new_note", count: 1) end end step 'I should see a diff comment form with ":-1: I don\'t like this"' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_field("note[note]", with: ":-1: I don\'t like this") end end step 'I should see a diff comment saying "Typo, please fix"' do - within("#{diff_file_selector} .note") do + page.within("#{diff_file_selector} .note") do expect(page).to have_content("Typo, please fix") end end step 'I should see a discussion reply button' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_button('Reply') end end step 'I should see a temporary diff comment form' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_css(".js-temp-notes-holder form.new_note") end end @@ -119,38 +119,38 @@ module SharedDiffNote end step 'I should see an empty diff comment form' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_field("note[note]", with: "") end end step 'I should see the cancel comment button' do - within("#{diff_file_selector} form") do + page.within("#{diff_file_selector} form") do expect(page).to have_css(".js-close-discussion-note-form", text: "Cancel") end end step 'I should see the diff comment preview' do - within("#{diff_file_selector} form") do + page.within("#{diff_file_selector} form") do expect(page).to have_css('.js-md-preview', visible: true) end end step 'I should see the diff comment write tab' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_css('.js-md-write-button', visible: true) end end step 'The diff comment preview tab should display rendered Markdown' do - within(diff_file_selector) do + page.within(diff_file_selector) do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_css('img.emoji', visible: true) end end step 'I should see two separate previews' do - within(diff_file_selector) do + page.within(diff_file_selector) do expect(page).to have_css('.js-md-preview', visible: true, count: 2) expect(page).to have_content('Should fix it') expect(page).to have_content('DRY this up') diff --git a/features/steps/shared/markdown.rb b/features/steps/shared/markdown.rb index 34172f5bb5..56b36f7c46 100644 --- a/features/steps/shared/markdown.rb +++ b/features/steps/shared/markdown.rb @@ -19,7 +19,7 @@ module SharedMarkdown end step 'The Markdown preview tab should say there is nothing to do' do - within('.gfm-form') do + page.within('.gfm-form') do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_content('Nothing to preview.') end @@ -38,7 +38,7 @@ module SharedMarkdown end step 'The Markdown preview tab should display rendered Markdown' do - within('.gfm-form') do + page.within('.gfm-form') do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_css('img.emoji', visible: true) end @@ -49,7 +49,7 @@ module SharedMarkdown end step 'I preview a description text like "Bug fixed :smile:"' do - within('.gfm-form') do + page.within('.gfm-form') do fill_in 'Description', with: 'Bug fixed :smile:' find('.js-md-preview-button').click end diff --git a/features/steps/shared/note.rb b/features/steps/shared/note.rb index 59dca1db70..b2675546a1 100644 --- a/features/steps/shared/note.rb +++ b/features/steps/shared/note.rb @@ -7,13 +7,13 @@ module SharedNote end step 'I haven\'t written any comment text' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in "note[note]", with: "" end end step 'I leave a comment like "XML attached"' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in "note[note]", with: "XML attached" click_button "Add Comment" sleep 0.05 @@ -21,20 +21,20 @@ module SharedNote end step 'I preview a comment text like "Bug fixed :smile:"' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in "note[note]", with: "Bug fixed :smile:" find('.js-md-preview-button').click end end step 'I submit the comment' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do click_button "Add Comment" end end step 'I write a comment like ":+1: Nice"' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in 'note[note]', with: ':+1: Nice' end end @@ -44,63 +44,63 @@ module SharedNote end step 'I should not see the cancel comment button' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do should_not have_link("Cancel") end end step 'I should not see the comment preview' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do expect(find('.js-md-preview')).not_to be_visible end end step 'The comment preview tab should say there is nothing to do' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_content('Nothing to preview.') end end step 'I should not see the comment text field' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do expect(find('.js-note-text')).not_to be_visible end end step 'I should see a comment saying "XML attached"' do - within(".note") do + page.within(".note") do expect(page).to have_content("XML attached") end end step 'I should see an empty comment text field' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do expect(page).to have_field("note[note]", with: "") end end step 'I should see the comment write tab' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do expect(page).to have_css('.js-md-write-button', visible: true) end end step 'The comment preview tab should be display rendered Markdown' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do find('.js-md-preview-button').click expect(find('.js-md-preview')).to have_css('img.emoji', visible: true) end end step 'I should see the comment preview' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do expect(page).to have_css('.js-md-preview', visible: true) end end step 'I should see comment "XML attached"' do - within(".note") do + page.within(".note") do expect(page).to have_content("XML attached") end end @@ -108,7 +108,7 @@ module SharedNote # Markdown step 'I leave a comment with a header containing "Comment with a header"' do - within(".js-main-target-form") do + page.within(".js-main-target-form") do fill_in "note[note]", with: "# Comment with a header" click_button "Add Comment" sleep 0.05 @@ -116,7 +116,7 @@ module SharedNote end step 'The comment with the header should not have an ID' do - within(".note-body > .note-text") do + page.within(".note-body > .note-text") do expect(page).to have_content("Comment with a header") expect(page).not_to have_css("#comment-with-a-header") end @@ -126,7 +126,7 @@ module SharedNote find(".note").hover find('.js-note-edit').click - within(".current-note-edit-form") do + page.within(".current-note-edit-form") do fill_in 'note[note]', with: '+1 Awesome!' click_button 'Save Comment' sleep 0.05 @@ -134,7 +134,7 @@ module SharedNote end step 'I should see +1 in the description' do - within(".note") do + page.within(".note") do expect(page).to have_content("+1 Awesome!") end end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb index ce8cbe80aa..3b94b7d862 100644 --- a/features/steps/shared/project_tab.rb +++ b/features/steps/shared/project_tab.rb @@ -45,7 +45,7 @@ module SharedProjectTab end step 'the active main tab should be Settings' do - within '.nav-sidebar' do + page.within '.nav-sidebar' do expect(page).to have_content('Back to project') end end diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index 0f56fb0306..09fdd1b5a1 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -13,7 +13,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I click link "Edit"' do - within ".file-title" do + page.within ".file-title" do click_link "Edit" end end @@ -25,7 +25,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps step 'I submit new snippet "Personal snippet three"' do fill_in "personal_snippet_title", :with => "Personal snippet three" fill_in "personal_snippet_file_name", :with => "my_snippet.rb" - within('.file-editor') do + page.within('.file-editor') do find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of snippet three' end click_button "Create snippet" diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index e6c6ec27e7..007fcb2893 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -32,19 +32,19 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps end step 'I click "Internal" filter' do - within('.nav-tabs') do + page.within('.nav-tabs') do click_link "Internal" end end step 'I click "Private" filter' do - within('.nav-tabs') do + page.within('.nav-tabs') do click_link "Private" end end step 'I click "Public" filter' do - within('.nav-tabs') do + page.within('.nav-tabs') do click_link "Public" end end diff --git a/features/steps/user.rb b/features/steps/user.rb index 5cbbecc749..3230234cb6 100644 --- a/features/steps/user.rb +++ b/features/steps/user.rb @@ -28,7 +28,7 @@ class Spinach::Features::User < Spinach::FeatureSteps end step 'I should see contributed projects' do - within '.contributed-projects' do + page.within '.contributed-projects' do expect(page).to have_content(@contributed_project.name) end end From 4c42fc7c4cc4d322109306c433f1c234bdcfc397 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Mon, 1 Jun 2015 17:43:59 -0400 Subject: [PATCH 48/51] Call `page.all` instead of `all` in feature steps There's a naming conflict between Capybara and rspec-matchers which both define the `all` method. See https://github.com/jnicklas/capybara/issues/1396 --- features/steps/admin/settings.rb | 2 +- features/steps/dashboard/new_project.rb | 2 +- features/steps/explore/projects.rb | 4 ++-- features/steps/project/commits/branches.rb | 2 +- features/steps/project/commits/commits.rb | 2 +- features/steps/project/commits/tags.rb | 4 ++-- features/steps/project/issues/issues.rb | 2 +- features/steps/project/issues/labels.rb | 2 +- features/steps/project/merge_requests.rb | 2 +- features/steps/project/source/multiselect_blob.rb | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/features/steps/admin/settings.rb b/features/steps/admin/settings.rb index 06616bfbd7..1c0b7a4b71 100644 --- a/features/steps/admin/settings.rb +++ b/features/steps/admin/settings.rb @@ -45,7 +45,7 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps end step 'I should see all checkboxes checked' do - all('input[type=checkbox]').each do |checkbox| + page.all('input[type=checkbox]').each do |checkbox| expect(checkbox).to be_checked end end diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb index ea89ad215c..b4ade65ee5 100644 --- a/features/steps/dashboard/new_project.rb +++ b/features/steps/dashboard/new_project.rb @@ -22,7 +22,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps expect(github_modal).to be_visible expect(github_modal).to have_content "To enable importing projects from GitHub" - all('.modal-body').each do |element| + page.all('.modal-body').each do |element| expect(element).not_to be_visible unless element == github_modal end end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 17c16c3fb1..49c2f6a125 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -22,14 +22,14 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps step 'I should see empty public project details with http clone info' do project = Project.find_by(name: 'Empty Public Project') - all(:css, '.git-empty .clone').each do |element| + page.all(:css, '.git-empty .clone').each do |element| expect(element.text).to include(project.http_url_to_repo) end end step 'I should see empty public project details with ssh clone info' do project = Project.find_by(name: 'Empty Public Project') - all(:css, '.git-empty .clone').each do |element| + page.all(:css, '.git-empty .clone').each do |element| expect(element.text).to include(project.url_to_repo) end end diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb index ff5baf5dda..338f5e8d3e 100644 --- a/features/steps/project/commits/branches.rb +++ b/features/steps/project/commits/branches.rb @@ -80,6 +80,6 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps end step "I should not see branch 'improve/awesome'" do - expect(all(visible: true)).not_to have_content 'improve/awesome' + expect(page.all(visible: true)).not_to have_content 'improve/awesome' end end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index f0acea1d47..4b19e3beed 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -83,7 +83,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'The diff links to both the previous and current image' do - links = all('.two-up span div a') + links = page.all('.two-up span div a') expect(links[0]['href']).to match %r{blob/#{sample_image_commit.old_blob_id}} expect(links[1]['href']).to match %r{blob/#{sample_image_commit.new_blob_id}} end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb index beecfd3a3c..e6f8faf50f 100644 --- a/features/steps/project/commits/tags.rb +++ b/features/steps/project/commits/tags.rb @@ -61,13 +61,13 @@ class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps step "I should not see tag 'v1.1.0'" do page.within '.tags' do - expect(all(visible: true)).not_to have_content 'v1.1.0' + expect(page.all(visible: true)).not_to have_content 'v1.1.0' end end step 'I delete all tags' do page.within '.tags' do - all('.btn-remove').each do |remove| + page.all('.btn-remove').each do |remove| remove.click sleep 0.05 end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index 6a462fec26..6873c043e1 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -190,7 +190,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I see empty project details with ssh clone info' do project = Project.find_by(name: 'Empty Project') - all(:css, '.git-empty .clone').each do |element| + page.all(:css, '.git-empty .clone').each do |element| expect(element.text).to include(project.url_to_repo) end end diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 2828f02c44..d656acf422 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -15,7 +15,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps step 'I delete all labels' do page.within '.labels' do - all('.btn-remove').each do |remove| + page.all('.btn-remove').each do |remove| remove.click sleep 0.05 end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 6e8c5f5ddd..62c64e60f6 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -121,7 +121,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I should see the proper Inline and Side-by-side links' do - buttons = all('#commit-diff-viewtype') + buttons = page.all('#commit-diff-viewtype') expect(buttons.count).to eq(2) buttons.each do |b| diff --git a/features/steps/project/source/multiselect_blob.rb b/features/steps/project/source/multiselect_blob.rb index 212537fc33..8e14623b89 100644 --- a/features/steps/project/source/multiselect_blob.rb +++ b/features/steps/project/source/multiselect_blob.rb @@ -30,7 +30,7 @@ class Spinach::Features::ProjectSourceMultiselectBlob < Spinach::FeatureSteps ids = Array(range).map { |n| "LC#{n}" } extra = false - highlighted = all("#tree-content-holder .highlight .line.hll") + highlighted = page.all("#tree-content-holder .highlight .line.hll") highlighted.each do |element| extra ||= ids.delete(element[:id]).nil? end From 91ab3849bd163d41500f33fc94da499b60bfc8c8 Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Fri, 12 Jun 2015 11:58:18 +0200 Subject: [PATCH 49/51] Remove text since rss is now to prominent. --- app/views/dashboard/_activities.html.haml | 1 - app/views/groups/show.html.haml | 1 - app/views/projects/_section.html.haml | 1 - 3 files changed, 3 deletions(-) diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml index ba49013d83..213b5d65b3 100644 --- a/app/views/dashboard/_activities.html.haml +++ b/app/views/dashboard/_activities.html.haml @@ -6,7 +6,6 @@ %li.pull-right = link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do %i.fa.fa-rss - Activity Feed = render 'shared/event_filter' %hr diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 0687840af3..d31dae7d64 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -27,7 +27,6 @@ %li = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do %i.fa.fa-rss - Activity Feed = render 'shared/event_filter' %hr diff --git a/app/views/projects/_section.html.haml b/app/views/projects/_section.html.haml index f4f876f380..d7b06197f6 100644 --- a/app/views/projects/_section.html.haml +++ b/app/views/projects/_section.html.haml @@ -18,7 +18,6 @@ %li = link_to namespace_project_path(@project.namespace, @project, format: :atom, private_token: current_user.private_token), title: "Feed", class: 'rss-btn' do %i.fa.fa-rss - Activity Feed = render 'shared/event_filter' %hr From f0ecdf5e246c6883f82a5a7b0b87f71a03fa8c84 Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Fri, 12 Jun 2015 12:09:50 +0200 Subject: [PATCH 50/51] Fix link to howto_rc1.md The relative link that was there before breaks when you copy-paste the issue template into an actual issue. --- doc/release/monthly.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release/monthly.md b/doc/release/monthly.md index 57d904ff38..97418db747 100644 --- a/doc/release/monthly.md +++ b/doc/release/monthly.md @@ -39,7 +39,7 @@ Xth: (6 working days before the 22nd) - [ ] Merge CE master in to EE master via merge request (#LINK) - [ ] Determine QA person and notify this person -- [ ] Check the tasks in [how to rc1 guide](howto_rc1.md) and delegate tasks if necessary +- [ ] Check the tasks in [how to rc1 guide](https://dev.gitlab.org/gitlab/gitlabhq/blob/master/doc/release/howto_rc1.md) and delegate tasks if necessary - [ ] Create CE, EE, CI RC1 versions (#LINK) Xth: (5 working days before the 22nd) From 7ff669a76911a73c9cd7622486608549d7f63489 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 12 Jun 2015 13:49:15 +0200 Subject: [PATCH 51/51] Fix tests for EE after CE merge Signed-off-by: Dmitriy Zaporozhets --- features/project/project.feature | 3 ++- features/steps/groups_management.rb | 1 - features/steps/project/merge_requests.rb | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/features/project/project.feature b/features/project/project.feature index 3c185c81e0..1e334bc8ce 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -67,9 +67,10 @@ Feature: Project Scenario: I should see audit events And gitlab user "Pete" And "Pete" is "Shop" developer - When I visit project "Shop" settings page + When I visit project "Shop" page And I go to "Members" And I change "Pete" access level to master + And I visit project "Shop" settings page And I go to "Audit Events" Then I should see the audit event listed diff --git a/features/steps/groups_management.rb b/features/steps/groups_management.rb index 31ef91e953..3a6562d550 100644 --- a/features/steps/groups_management.rb +++ b/features/steps/groups_management.rb @@ -24,7 +24,6 @@ class Spinach::Features::GroupsManagement < Spinach::FeatureSteps step 'I go to "Open" project members page' do click_link 'Sourcing / Open' - click_link 'Settings' click_link 'Members' end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index c999a561b8..c208345282 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -334,21 +334,24 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps merge_request = MergeRequest.find_by!(title: "Bug NS-04") project = merge_request.target_project project.approvals_before_merge = 1 + project.ensure_satellite_exists project.save! end step 'I click link "Approve"' do - click_button 'Approve Merge Request' + within '.mr-state-widget' do + click_button 'Approve Merge Request' + end end step 'I should not see merge button' do - within '.can_be_merged' do + within '.mr-state-widget' do page.should_not have_button("Accept Merge Request") end end step 'I should see approved merge request "Bug NS-04"' do - within '.can_be_merged' do + within '.mr-state-widget' do page.should have_button("Accept Merge Request") end end