From 7be7cf2936646ea2c80d9e5bec6a5526326785f3 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sat, 26 Jul 2014 21:45:34 +0200 Subject: Remove unused title parameter. It is always overridden by to humanized source branch name by MergeRequests::BuilService, which is used by new_project_merge_request_path. --- app/helpers/merge_requests_helper.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index cc63db2035e..259928449f7 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -19,8 +19,7 @@ module MergeRequestsHelper source_project_id: event.project.id, target_project_id: target_project.id, source_branch: event.branch_name, - target_branch: target_project.repository.root_ref, - title: event.branch_name.titleize.humanize + target_branch: target_project.repository.root_ref } end -- cgit v1.2.1 From 92160789aa2134a582211efeb0fd1a3034e4ca0f Mon Sep 17 00:00:00 2001 From: Ben Bodenmiller Date: Sun, 24 Aug 2014 23:47:19 -0700 Subject: add sign-in count add sign-in count to admin section profile view --- app/views/admin/users/show.html.haml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 3c30ccd78b3..f3d7b857e0d 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -78,6 +78,11 @@ - else never + %li + %span.light Sign-in count: + %strong + = @user.sign_in_count + - if @user.ldap_user? %li %span.light LDAP uid: -- cgit v1.2.1 From 765eabeacccbc199bb2a762dffdb7abde6adb246 Mon Sep 17 00:00:00 2001 From: Ben Bodenmiller Date: Mon, 1 Sep 2014 15:47:15 -0700 Subject: add HSTS Policy warning Add warning about HSTS header as it means user will need to provide secure connection access to site for next 24 months from page view. See https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security for more details. --- lib/support/nginx/gitlab-ssl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl index 9ab228b46d7..9125a813888 100644 --- a/lib/support/nginx/gitlab-ssl +++ b/lib/support/nginx/gitlab-ssl @@ -83,6 +83,8 @@ server { ssl_prefer_server_ciphers on; + ## [WARNING] The following header states that the browser should only communicate + ## with your server over a secure connection for the next 24 months. add_header Strict-Transport-Security max-age=63072000; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; -- cgit v1.2.1 From 7d9cdc2d37cec34544069cf85dc7ea33137589eb Mon Sep 17 00:00:00 2001 From: uran Date: Fri, 12 Sep 2014 17:53:08 +0300 Subject: Source repo is now clickable. --- app/views/projects/merge_requests/show/_mr_title.html.haml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index 563a5244993..1c319b83e2b 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -31,7 +31,12 @@ %span.prepend-left-20 %span From - if @merge_request.for_fork? - %strong.label-branch #{@merge_request.source_project_namespace}:#{@merge_request.source_branch} + %strong.label-branch< + - if @merge_request.source_project + = link_to @merge_request.source_project_namespace, project_path(@merge_request.source_project) + - else + \ #{@merge_request.source_project_namespace} + \:#{@merge_request.source_branch} %span into %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} - else -- cgit v1.2.1 From 99bc22d7b47e95902972a4e996cb22d6b06a6202 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 23 Sep 2014 23:55:23 +0200 Subject: Remove test line without effect because no should. --- features/steps/project/issues.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/steps/project/issues.rb b/features/steps/project/issues.rb index 1aaf8b1cb7e..6619edd96b1 100644 --- a/features/steps/project/issues.rb +++ b/features/steps/project/issues.rb @@ -232,9 +232,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps def filter_issue(text) fill_in 'issue_search', with: text - - # make sure AJAX request finished - URI.parse(current_url).request_uri == project_issues_path(project, issue_search: text) end def project -- cgit v1.2.1 From d29cbc70b247608eda5241675dcfe002e0a10e0e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 1 Oct 2014 12:56:23 +0300 Subject: Remove I18n.enforce_available_locales deprecation message Signed-off-by: Dmitriy Zaporozhets --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 99dfafdb786..e36df913d0b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -2,7 +2,7 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' require 'devise' - +I18n.config.enforce_available_locales = false Bundler.require(:default, Rails.env) module Gitlab -- cgit v1.2.1 From 1c9d2e39c1aef8e10ebff6e57c174c197a3a1c93 Mon Sep 17 00:00:00 2001 From: Kirill Zaitsev Date: Mon, 15 Sep 2014 11:10:35 +0400 Subject: Hook attributes --- app/models/commit.rb | 15 +++++++++++++++ app/models/concerns/issuable.rb | 2 +- app/models/issue.rb | 4 ++++ app/models/merge_request.rb | 14 ++++++++++++++ app/models/project.rb | 10 ++++++++++ app/services/git_push_service.rb | 11 +---------- doc/web_hooks/web_hooks.md | 26 +++++++++++++++++++++++++- 7 files changed, 70 insertions(+), 12 deletions(-) diff --git a/app/models/commit.rb b/app/models/commit.rb index c8b2e0475ff..d18738a72dc 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -88,6 +88,21 @@ class Commit description.present? end + def hook_attrs(project) + path_with_namespace = project.path_with_namespace + + { + id: id, + message: safe_message, + timestamp: committed_date.xmlschema, + url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{id}", + author: { + name: author_name, + email: author_email + } + } + end + # Discover issues should be closed when this commit is pushed to a project's # default branch. def closes_issues project diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 698b5b8c30a..553087946d6 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -134,7 +134,7 @@ module Issuable def to_hook_data { object_kind: self.class.name.underscore, - object_attributes: self.attributes + object_attributes: hook_attrs } end diff --git a/app/models/issue.rb b/app/models/issue.rb index 45a8e43b03d..7c0344d38c2 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -48,6 +48,10 @@ class Issue < ActiveRecord::Base state :closed end + def hook_attrs + attributes + end + # Mentionable overrides. def gfm_reference diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 4894c617674..e0358c1889c 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -211,6 +211,20 @@ class MergeRequest < ActiveRecord::Base Gitlab::Satellite::MergeAction.new(current_user, self).format_patch end + def hook_attrs + attrs = { + source: source_project.hook_attrs, + target: target_project.hook_attrs, + last_commit: nil + } + + unless last_commit.nil? + attrs.merge!(last_commit: last_commit.hook_attrs(source_project)) + end + + attributes.merge!(attrs) + end + def for_fork? target_project != source_project end diff --git a/app/models/project.rb b/app/models/project.rb index f9278f19dad..f070e16b972 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -544,6 +544,16 @@ class Project < ActiveRecord::Base end end + def hook_attrs + { + name: name, + ssh_url: ssh_url_to_repo, + http_url: http_url_to_repo, + namespace: namespace.name, + visibility_level: visibility_level + } + end + # Reset events cache related to this project # # Since we do cache @event we need to reset cache in special cases: diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 17c84c78d2d..b2d20491392 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -150,16 +150,7 @@ class GitPushService # will be passed as post receive hook data. # push_commits_limited.each do |commit| - data[:commits] << { - id: commit.id, - message: commit.safe_message, - timestamp: commit.committed_date.xmlschema, - url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{commit.id}", - author: { - name: commit.author_name, - email: commit.author_email - } - } + data[:commits] << commit.hook_attrs(project) end data diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md index 16817d1933d..31791da8074 100644 --- a/doc/web_hooks/web_hooks.md +++ b/doc/web_hooks/web_hooks.md @@ -109,7 +109,31 @@ Triggered when a new merge request is created or an existing merge request was u "merge_status": "unchecked", "target_project_id": 14, "iid": 1, - "description": "" + "description": "", + "source": { + "name": "awesome_project", + "ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git", + "http_url": "http://example.com/awesome_space/awesome_project.git", + "visibility_level": 20, + "namespace": "awesome_space" + }, + "target": { + "name": "awesome_project", + "ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git", + "http_url": "http://example.com/awesome_space/awesome_project.git", + "visibility_level": 20, + "namespace": "awesome_space" + }, + "last_commit": { + "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "message": "fixed readme", + "timestamp": "2012-01-03T23:36:29+02:00", + "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "author": { + "name": "GitLab dev user", + "email": "gitlabdev@dv6700.(none)" + } + } } } ``` -- cgit v1.2.1 From d2808476e3f85c9940500b84ee14d38615ceca41 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 2 Oct 2014 12:49:31 +0300 Subject: Add new milestone link. Hide empty milestone selectbox Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/_issuable_form.html.haml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml index 0ae1fb3cabe..316b71f6be7 100644 --- a/app/views/projects/_issuable_form.html.haml +++ b/app/views/projects/_issuable_form.html.haml @@ -42,8 +42,14 @@ = f.label :milestone_id, class: 'control-label' do %i.icon-time Milestone - .col-sm-10= f.select(:milestone_id, milestone_options(issuable), - { include_blank: 'Select milestone' }, { class: 'select2' }) + .col-sm-10 + - if milestone_options(issuable).present? + = f.select(:milestone_id, milestone_options(issuable), + { include_blank: 'Select milestone' }, { class: 'select2' }) + - else + %span.light No open milestones available. +   + = link_to 'Create new milestone', new_project_milestone_path .form-group = f.label :label_ids, class: 'control-label' do %i.icon-tag -- cgit v1.2.1 From d3388d4790c6d09e97d9961e3e9de2d0c60d704b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 2 Oct 2014 12:55:02 +0300 Subject: New label link Signed-off-by: Dmitriy Zaporozhets --- app/views/projects/_issuable_form.html.haml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml index 316b71f6be7..114470f1db4 100644 --- a/app/views/projects/_issuable_form.html.haml +++ b/app/views/projects/_issuable_form.html.haml @@ -49,14 +49,20 @@ - else %span.light No open milestones available.   - = link_to 'Create new milestone', new_project_milestone_path + = link_to 'Create new milestone', new_project_milestone_path(issuable.project) .form-group = f.label :label_ids, class: 'control-label' do %i.icon-tag Labels .col-sm-10 - = f.collection_select :label_ids, issuable.project.labels.all, :id, :name, + - if issuable.project.labels.any? + = f.collection_select :label_ids, issuable.project.labels.all, :id, :name, { selected: issuable.label_ids }, multiple: true, class: 'select2' + - else + %span.light No labels yet. +   + = link_to 'Create new label', new_project_label_path(issuable.project) + .form-actions - if issuable.new_record? = f.submit "Submit new #{issuable.class.model_name.human.downcase}", class: 'btn btn-create' -- cgit v1.2.1 From 3098e7a453c84ac4df1686b8bad6ef8004aca60d Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sat, 27 Sep 2014 00:41:17 +0200 Subject: Factor commit message textareas. --- app/assets/javascripts/merge_request.js.coffee | 2 +- app/controllers/projects/merge_requests_controller.rb | 2 +- app/views/projects/blob/_remove.html.haml | 8 ++------ app/views/projects/edit_tree/show.html.haml | 9 ++------- .../projects/merge_requests/show/_mr_accept.html.haml | 12 +++--------- app/views/projects/new_tree/show.html.haml | 11 ++--------- app/views/shared/_commit_message_container.html.haml | 17 ++++++++++++++--- features/steps/project/merge_requests.rb | 2 +- 8 files changed, 26 insertions(+), 37 deletions(-) diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index 59e53b69e3d..86dff05849c 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -15,7 +15,7 @@ class MergeRequest modal = $('#modal_merge_info').modal(show: false) - disableButtonIfEmptyField '#merge_commit_message', '.accept_merge_request' + disableButtonIfEmptyField '#commit_message', '.accept_merge_request' # Local jQuery finder diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2667cc7a4f7..4bab3ae6e61 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -122,7 +122,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController if @merge_request.open? && @merge_request.can_be_merged? @merge_request.should_remove_source_branch = params[:should_remove_source_branch] - @merge_request.automerge!(current_user, params[:merge_commit_message]) + @merge_request.automerge!(current_user, params[:commit_message]) @status = true else @status = false diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml index 93ffd4463b1..da84dc4b6cf 100644 --- a/app/views/projects/blob/_remove.html.haml +++ b/app/views/projects/blob/_remove.html.haml @@ -10,12 +10,8 @@ .modal-body = form_tag project_blob_path(@project, @id), method: :delete, class: 'form-horizontal' do - .form-group.commit_message-group - = label_tag 'commit_message', class: "control-label" do - Commit message - .col-sm-10 - = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message', - params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3, class: 'form-control')} + = render 'shared/commit_message_container', params: params, + placeholder: 'Removed this file because...' .form-group .col-sm-2 .col-sm-10 diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml index 62798b51d82..aca7d874abf 100644 --- a/app/views/projects/edit_tree/show.html.haml +++ b/app/views/projects/edit_tree/show.html.haml @@ -21,13 +21,8 @@ .center %h2 %i.icon-spinner.icon-spin - - .form-group.commit_message-group - = label_tag 'commit_message', class: "control-label" do - Commit message - .col-sm-10 - = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message', '', - placeholder: "Update #{@blob.name}", required: true, rows: 3, class: 'form-control')} + = render 'shared/commit_message_container', params: params, + placeholder: "Update #{@blob.name}" .form-actions = hidden_field_tag 'last_commit', @last_commit = hidden_field_tag 'content', '', id: "file-content" diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 88cc8e17fa6..e2cf2b60234 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -22,15 +22,9 @@ %strong= link_to "modify merge commit message", "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" before accepting merge request .js-toggle-content.hide - .form-group - = label_tag :merge_commit_message, "Commit message", class: 'control-label' - .col-sm-10 - = render 'shared/commit_message_container', {textarea: text_area_tag(:merge_commit_message, - @merge_request.merge_commit_message, class: "form-control js-gfm-input", rows: 14, required: true)} - %p.hint - Try to keep the first line under 52 characters - and the others under 72. - + = render 'shared/commit_message_container', params: params, + text: @merge_request.merge_commit_message, + rows: 14, hint: true .accept-group .pull-left = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" diff --git a/app/views/projects/new_tree/show.html.haml b/app/views/projects/new_tree/show.html.haml index 24d77344fd5..3df1c032ba1 100644 --- a/app/views/projects/new_tree/show.html.haml +++ b/app/views/projects/new_tree/show.html.haml @@ -19,15 +19,8 @@ Encoding .col-sm-10 = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control' - - .form-group.commit_message-group - = label_tag 'commit_message', class: "control-label" do - Commit message - .col-sm-10 - = render 'shared/commit_message_container', {textarea: text_area_tag('commit_message', - params[:commit_message], placeholder: 'Add new file', - required: true, rows: 3, class: 'form-control')} - + = render 'shared/commit_message_container', params: params, + placeholder: 'Add new file' .file-holder .file-title %i.icon-file diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml index 4365947e701..5071ff640f1 100644 --- a/app/views/shared/_commit_message_container.html.haml +++ b/app/views/shared/_commit_message_container.html.haml @@ -1,3 +1,14 @@ -.commit-message-container - .max-width-marker - = textarea +.form-group.commit_message-group + = label_tag 'commit_message', class: 'control-label' do + Commit message + .col-sm-10 + .commit-message-container + .max-width-marker + = text_area_tag 'commit_message', + (params[:commit_message] || local_assigns[:text]), + class: 'form-control', placeholder: local_assigns[:placeholder], + required: true, rows: (local_assigns[:rows] || 3) + - if local_assigns[:hint] + %p.hint + Try to keep the first line under 52 characters + and the others under 72. diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 0cc78f0f58d..c101c696253 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -154,7 +154,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I modify merge commit message' do find('.modify-merge-commit-link').click - fill_in 'merge_commit_message', with: "wow such merge" + fill_in 'commit_message', with: 'wow such merge' end step 'merge request "Bug NS-05" is mergeable' do -- cgit v1.2.1 From 30c447ed2f35a0d1f4eb0f6200aa9ab952c46768 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Thu, 2 Oct 2014 14:38:26 +0200 Subject: Try signing in the user after user confirmation is correct and redirect to dashboard, otherwise redirect to signin page --- app/controllers/confirmations_controller.rb | 17 +++++++++++++++++ config/routes.rb | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 app/controllers/confirmations_controller.rb diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb new file mode 100644 index 00000000000..bc98eab133c --- /dev/null +++ b/app/controllers/confirmations_controller.rb @@ -0,0 +1,17 @@ +class ConfirmationsController < Devise::ConfirmationsController + + protected + + def after_confirmation_path_for(resource_name, resource) + if signed_in?(resource_name) + signed_in_root_path(resource) + else + sign_in(resource) + if signed_in?(resource_name) + signed_in_root_path(resource) + else + new_session_path(resource_name) + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 00267b13161..2534153758b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -170,7 +170,7 @@ Gitlab::Application.routes.draw do resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] - devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions } + devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations } devise_scope :user do get "/users/auth/:provider/omniauth_error" => "omniauth_callbacks#omniauth_error", as: :omniauth_error -- cgit v1.2.1 From 97c5d38097a6308c31e0e5f9afaef719d5080b5f Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 2 Oct 2014 18:27:18 +0200 Subject: Add a counterexample to 'do it in Ruby' --- doc/development/shell_commands.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md index 1f3908f4e27..23c8365c340 100644 --- a/doc/development/shell_commands.md +++ b/doc/development/shell_commands.md @@ -22,6 +22,12 @@ FileUtils.mkdir_p "tmp/special/directory" contents = `cat #{filename}` # Correct contents = File.read(filename) + +# Sometimes a shell command is just the best solution. The example below has no +# user input, and is hard to implement correctly in Ruby: delete all files and +# directories older than 120 minutes under /some/path, but not /some/path +# itself. +Gitlab::Popen.popen(%W(find /some/path -not -path /some/path -mmin +120 -delete)) ``` This coding style could have prevented CVE-2013-4490. -- cgit v1.2.1 From b0a3276253498475029fe25bcaef0eacc9e27ee6 Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 2 Oct 2014 18:53:07 +0200 Subject: Bump org-mode to 0.9.9 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 3d9af1c91c2..4d831c1c232 100644 --- a/Gemfile +++ b/Gemfile @@ -89,7 +89,7 @@ gem "github-markup" gem 'redcarpet', '~> 3.1.2' gem 'RedCloth' gem 'rdoc', '~>3.6' -gem 'org-ruby' +gem 'org-ruby', '= 0.9.9' gem 'creole', '~>0.3.6' gem 'wikicloth', '=0.8.1' gem 'asciidoctor', '= 0.1.4' diff --git a/Gemfile.lock b/Gemfile.lock index d0f29258ffa..3e029481eeb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -332,7 +332,7 @@ GEM omniauth-twitter (1.0.1) multi_json (~> 1.3) omniauth-oauth (~> 1.0) - org-ruby (0.9.8) + org-ruby (0.9.9) rubypants (~> 0.2) orm_adapter (0.5.0) pg (0.15.1) @@ -655,7 +655,7 @@ DEPENDENCIES omniauth-google-oauth2 omniauth-shibboleth omniauth-twitter - org-ruby + org-ruby (= 0.9.9) pg poltergeist (~> 1.5.1) pry -- cgit v1.2.1 From d5c8ca7412f024a254653f0a72e3b1fe026adcde Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Fri, 3 Oct 2014 08:01:54 +0200 Subject: Add move to html-pipeline-gitlab to changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index b9020d825cb..0250b4a23c0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ v 7.4.0 - API: filter project issues by milestone (Julien Bianchi) - Fail harder in the backup script - Zen mode for wiki and milestones (Robert Schilling) + - Move Emoji parsing to html-pipeline-gitlab (Robert Schilling) v 7.3.2 - Fix creating new file via web editor -- cgit v1.2.1 From b4963e9dda1ced7c219f24172e9fa4c8a5076b69 Mon Sep 17 00:00:00 2001 From: Kirill Zaitsev Date: Fri, 19 Sep 2014 12:23:18 +0400 Subject: Add tag_push_events to project hook api --- app/models/hooks/web_hook.rb | 1 + doc/api/projects.md | 2 ++ lib/api/entities.rb | 3 ++- lib/api/project_hooks.rb | 16 ++++++++++++++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 752eb8074ac..23fa01e0b70 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -21,6 +21,7 @@ class WebHook < ActiveRecord::Base default_value_for :push_events, true default_value_for :issues_events, false default_value_for :merge_requests_events, false + default_value_for :tag_push_events, false # HTTParty timeout default_timeout Gitlab.config.gitlab.webhook_timeout diff --git a/doc/api/projects.md b/doc/api/projects.md index 8385e11b805..dfe3502b6e4 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -447,6 +447,7 @@ Parameters: - `push_events` - Trigger hook on push events - `issues_events` - Trigger hook on issues events - `merge_requests_events` - Trigger hook on merge_requests events +- `tag_push_events` - Trigger hook on push_tag events ### Edit project hook @@ -464,6 +465,7 @@ Parameters: - `push_events` - Trigger hook on push events - `issues_events` - Trigger hook on issues events - `merge_requests_events` - Trigger hook on merge_requests events +- `tag_push_events` - Trigger hook on push_tag events ### Delete project hook diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ffa3e8a149e..80e9470195e 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -30,7 +30,8 @@ module API end class ProjectHook < Hook - expose :project_id, :push_events, :issues_events, :merge_requests_events + expose :project_id, :push_events + expose :issues_events, :merge_requests_events, :tag_push_events end class ForkedFromProject < Grape::Entity diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb index 79c3d122d32..7d056b9bf58 100644 --- a/lib/api/project_hooks.rb +++ b/lib/api/project_hooks.rb @@ -38,7 +38,13 @@ module API # POST /projects/:id/hooks post ":id/hooks" do required_attributes! [:url] - attrs = attributes_for_keys [:url, :push_events, :issues_events, :merge_requests_events] + attrs = attributes_for_keys [ + :url, + :push_events, + :issues_events, + :merge_requests_events, + :tag_push_events + ] @hook = user_project.hooks.new(attrs) if @hook.save @@ -62,7 +68,13 @@ module API put ":id/hooks/:hook_id" do @hook = user_project.hooks.find(params[:hook_id]) required_attributes! [:url] - attrs = attributes_for_keys [:url, :push_events, :issues_events, :merge_requests_events] + attrs = attributes_for_keys [ + :url, + :push_events, + :issues_events, + :merge_requests_events, + :tag_push_events + ] if @hook.update_attributes attrs present @hook, with: Entities::ProjectHook -- cgit v1.2.1 From 2e9f5de86896e53e9cf34aef52bbc2ad08019a21 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Fri, 26 Sep 2014 00:07:40 +0200 Subject: Add parenthesis to function def with arguments. --- app/controllers/application_controller.rb | 2 +- app/controllers/registrations_controller.rb | 4 ++-- app/helpers/events_helper.rb | 2 +- app/helpers/issues_helper.rb | 4 ++-- app/helpers/merge_requests_helper.rb | 4 ++-- app/helpers/profile_helper.rb | 2 +- app/helpers/projects_helper.rb | 4 ++-- app/helpers/tab_helper.rb | 2 +- app/helpers/tags_helper.rb | 4 ++-- app/helpers/tree_helper.rb | 2 +- app/models/ability.rb | 4 ++-- app/models/commit.rb | 2 +- app/models/concerns/mentionable.rb | 10 +++++----- app/models/members/project_member.rb | 2 +- app/models/namespace.rb | 2 +- app/models/network/graph.rb | 2 +- app/models/project.rb | 4 ++-- app/models/project_services/gitlab_ci_service.rb | 4 ++-- app/models/project_team.rb | 2 +- app/models/user.rb | 14 +++++++------- app/services/base_service.rb | 2 +- app/services/git_push_service.rb | 14 +++++++------- app/workers/repository_import_worker.rb | 2 +- features/steps/group.rb | 2 +- lib/api/helpers.rb | 2 +- lib/event_filter.rb | 8 ++++---- lib/gitlab/backend/shell.rb | 2 +- lib/gitlab/diff/parser.rb | 2 +- lib/gitlab/inline_diff.rb | 6 +++--- lib/gitlab/logger.rb | 2 +- lib/gitlab/reference_extractor.rb | 12 ++++++------ lib/gitlab/satellite/satellite.rb | 2 +- spec/lib/gitlab/satellite/action_spec.rb | 2 +- 33 files changed, 67 insertions(+), 67 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5ffec7f75bf..1a5215ca309 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -62,7 +62,7 @@ class ApplicationController < ActionController::Base end end - def after_sign_in_path_for resource + def after_sign_in_path_for(resource) if resource.is_a?(User) && resource.respond_to?(:blocked?) && resource.blocked? sign_out resource flash[:alert] = "Your account is blocked. Retry when an admin has unblocked it." diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 9e70978992f..6d3214b70a8 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -15,11 +15,11 @@ class RegistrationsController < Devise::RegistrationsController super end - def after_sign_up_path_for resource + def after_sign_up_path_for(resource) new_user_session_path end - def after_inactive_sign_up_path_for resource + def after_inactive_sign_up_path_for(resource) new_user_session_path end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 6f738764b0e..10a895d8cae 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -19,7 +19,7 @@ module EventsHelper [event.action_name, target].join(" ") end - def event_filter_link key, tooltip + def event_filter_link(key, tooltip) key = key.to_s inactive = if @event_filter.active? key nil diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 2031519c32f..7671033b539 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -1,5 +1,5 @@ module IssuesHelper - def issue_css_classes issue + def issue_css_classes(issue) classes = "issue" classes << " closed" if issue.closed? classes << " today" if issue.today? @@ -84,7 +84,7 @@ module IssuesHelper 'id', 'name', object.assignee_id) end - def milestone_options object + def milestone_options(object) options_from_collection_for_select(object.project.milestones.active, 'id', 'title', object.milestone_id) end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index cc63db2035e..d1ea47eb7b3 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -24,14 +24,14 @@ module MergeRequestsHelper } end - def mr_css_classes mr + def mr_css_classes(mr) classes = "merge-request" classes << " closed" if mr.closed? classes << " merged" if mr.merged? classes end - def ci_build_details_path merge_request + def ci_build_details_path(merge_request) merge_request.source_project.ci_service.build_page(merge_request.last_commit.sha) end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index 297ae83d895..0b375558305 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -1,5 +1,5 @@ module ProfileHelper - def oauth_active_class provider + def oauth_active_class(provider) if current_user.provider == provider.to_s 'active' end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index f7da30bcc4b..6a16f112cb3 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -3,7 +3,7 @@ module ProjectsHelper "You are going to remove #{user.name} from #{project.name} project team. Are you sure?" end - def link_to_project project + def link_to_project(project) link_to project do title = content_tag(:span, project.name, class: 'project-name') @@ -39,7 +39,7 @@ module ProjectsHelper end end - def project_title project + def project_title(project) if project.group content_tag :span do link_to(simple_sanitize(project.group.name), group_path(project.group)) + " / " + project.name diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 610175f8447..bc43e078568 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -89,7 +89,7 @@ module TabHelper end # Use nav_tab for save controller/action but different params - def nav_tab key, value, &block + def nav_tab(key, value, &block) o = {} o[:class] = "" diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index ebed6a83746..ef89bb32c6d 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -1,9 +1,9 @@ module TagsHelper - def tag_path tag + def tag_path(tag) "/tags/#{tag}" end - def tag_list project + def tag_list(project) html = '' project.tag_list.each do |tag| html += link_to tag, tag_path(tag) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index d815257a4e3..ed3c401d873 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -80,7 +80,7 @@ module TreeHelper end end - def up_dir_path tree + def up_dir_path(tree) file = File.join(@path, "..") tree_join(@ref, file) end diff --git a/app/models/ability.rb b/app/models/ability.rb index 716a23a4284..e155abc1449 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -184,7 +184,7 @@ class Ability ] end - def group_abilities user, group + def group_abilities(user, group) rules = [] if user.admin? || group.users.include?(user) || ProjectsFinder.new.execute(user, group: group).any? @@ -209,7 +209,7 @@ class Ability rules.flatten end - def namespace_abilities user, namespace + def namespace_abilities(user, namespace) rules = [] # Only namespace owner and administrators can manage it diff --git a/app/models/commit.rb b/app/models/commit.rb index c8b2e0475ff..7f586ebe781 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -90,7 +90,7 @@ class Commit # Discover issues should be closed when this commit is pushed to a project's # default branch. - def closes_issues project + def closes_issues(project) Gitlab::ClosingIssueExtractor.closed_by_message_in_project(safe_message, project) end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 81414959f3b..71dd2f8c697 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -10,7 +10,7 @@ module Mentionable module ClassMethods # Indicate which attributes of the Mentionable to search for GFM references. - def attr_mentionable *attrs + def attr_mentionable(*attrs) mentionable_attrs.concat(attrs.map(&:to_s)) end @@ -38,7 +38,7 @@ module Mentionable # Determine whether or not a cross-reference Note has already been created between this Mentionable and # the specified target. - def has_mentioned? target + def has_mentioned?(target) Note.cross_reference_exists?(target, local_reference) end @@ -64,7 +64,7 @@ module Mentionable end # Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference. - def references p = project, text = mentionable_text + def references(p = project, text = mentionable_text) return [] if text.blank? ext = Gitlab::ReferenceExtractor.new ext.analyze(text) @@ -72,7 +72,7 @@ module Mentionable end # Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+. - def create_cross_references! p = project, a = author, without = [] + def create_cross_references!(p = project, a = author, without = []) refs = references(p) - without refs.each do |ref| Note.create_cross_reference_note(ref, local_reference, a, p) @@ -81,7 +81,7 @@ module Mentionable # If the mentionable_text field is about to change, locate any *added* references and create cross references for # them. Invoke from an observer's #before_save implementation. - def notice_added_references p = project, a = author + def notice_added_references(p = project, a = author) ch = changed_attributes original, mentionable_changed = "", false self.class.mentionable_attrs.each do |attr| diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb index f14900ad3e6..71525f91961 100644 --- a/app/models/members/project_member.rb +++ b/app/models/members/project_member.rb @@ -77,7 +77,7 @@ class ProjectMember < Member false end - def truncate_team project + def truncate_team(project) truncate_teams [project.id] end diff --git a/app/models/namespace.rb b/app/models/namespace.rb index b19b72906e7..c0c6de0ee7d 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -38,7 +38,7 @@ class Namespace < ActiveRecord::Base scope :root, -> { where('type IS NULL') } - def self.search query + def self.search(query) where("name LIKE :query OR path LIKE :query", query: "%#{query}%") end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb index 9c95470beb1..43979b5e807 100644 --- a/app/models/network/graph.rb +++ b/app/models/network/graph.rb @@ -6,7 +6,7 @@ module Network @max_count ||= 650 end - def initialize project, ref, commit, filter_ref + def initialize(project, ref, commit, filter_ref) @project = project @ref = ref @commit = commit diff --git a/app/models/project.rb b/app/models/project.rb index f9278f19dad..0e940bca2c9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -331,7 +331,7 @@ class Project < ActiveRecord::Base path end - def items_for entity + def items_for(entity) case entity when 'issue' then issues @@ -504,7 +504,7 @@ class Project < ActiveRecord::Base end # Check if current branch name is marked as protected in the system - def protected_branch? branch_name + def protected_branch?(branch_name) protected_branches_names.include?(branch_name) end diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 4a19ca2f655..001b11c5966 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -27,7 +27,7 @@ class GitlabCiService < CiService hook.save end - def commit_status_path sha + def commit_status_path(sha) project_url + "/builds/#{sha}/status.json?token=#{token}" end @@ -54,7 +54,7 @@ class GitlabCiService < CiService end end - def build_page sha + def build_page(sha) project_url + "/builds/#{sha}" end diff --git a/app/models/project_team.rb b/app/models/project_team.rb index e2af10c6899..e065554d3b8 100644 --- a/app/models/project_team.rb +++ b/app/models/project_team.rb @@ -11,7 +11,7 @@ class ProjectTeam # @team << [@user, :master] # @team << [@users, :master] # - def << args + def <<(args) users = args.first if users.respond_to?(:each) diff --git a/app/models/user.rb b/app/models/user.rb index ed3eba4cdf0..c90f2462426 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -203,7 +203,7 @@ class User < ActiveRecord::Base User.where(name: name).first end - def filter filter_name + def filter(filter_name) case filter_name when "admins"; self.admins when "blocked"; self.blocked @@ -213,7 +213,7 @@ class User < ActiveRecord::Base end end - def search query + def search(query) where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%") end @@ -332,7 +332,7 @@ class User < ActiveRecord::Base several_namespaces? || admin end - def can? action, subject + def can?(action, subject) abilities.allowed?(self, action, subject) end @@ -353,7 +353,7 @@ class User < ActiveRecord::Base (personal_projects.count.to_f / projects_limit) * 100 end - def recent_push project_id = nil + def recent_push(project_id = nil) # Get push events not earlier than 2 hours ago events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours) events = events.where(project_id: project_id) if project_id @@ -382,11 +382,11 @@ class User < ActiveRecord::Base project.team_member_by_id(self.id) end - def already_forked? project + def already_forked?(project) !!fork_of(project) end - def fork_of project + def fork_of(project) links = ForkedProjectLink.where(forked_from_project_id: project, forked_to_project_id: personal_projects) if links.any? @@ -512,7 +512,7 @@ class User < ActiveRecord::Base NotificationService.new end - def log_info message + def log_info(message) Gitlab::AppLogger.info message end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 051612633cd..ed286c04095 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -25,7 +25,7 @@ class BaseService EventCreateService.new end - def log_info message + def log_info(message) Gitlab::AppLogger.info message end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index 17c84c78d2d..1fe43f46c10 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -75,7 +75,7 @@ class GitPushService # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. - def process_commit_messages ref + def process_commit_messages(ref) is_default_branch = is_default_branch?(ref) @push_commits.each do |commit| @@ -165,34 +165,34 @@ class GitPushService data end - def push_to_existing_branch? ref, oldrev + def push_to_existing_branch?(ref, oldrev) ref_parts = ref.split('/') # Return if this is not a push to a branch (e.g. new commits) ref_parts[1] =~ /heads/ && oldrev != "0000000000000000000000000000000000000000" end - def push_to_new_branch? ref, oldrev + def push_to_new_branch?(ref, oldrev) ref_parts = ref.split('/') ref_parts[1] =~ /heads/ && oldrev == "0000000000000000000000000000000000000000" end - def push_remove_branch? ref, newrev + def push_remove_branch?(ref, newrev) ref_parts = ref.split('/') ref_parts[1] =~ /heads/ && newrev == "0000000000000000000000000000000000000000" end - def push_to_branch? ref + def push_to_branch?(ref) ref =~ /refs\/heads/ end - def is_default_branch? ref + def is_default_branch?(ref) ref == "refs/heads/#{project.default_branch}" end - def commit_user commit + def commit_user(commit) User.find_for_commit(commit.author_email, commit.author_name) || user end end diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 43ef54631a9..01586150cd2 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -19,4 +19,4 @@ class RepositoryImportWorker project.import_fail end end -end \ No newline at end of file +end diff --git a/features/steps/group.rb b/features/steps/group.rb index da0cf7bbd45..616a297db99 100644 --- a/features/steps/group.rb +++ b/features/steps/group.rb @@ -201,7 +201,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps protected - def assigned_to_me key + def assigned_to_me(key) project.send(key).where(assignee_id: current_user.id) end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 3a619169eca..3262884f6d3 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -71,7 +71,7 @@ module API forbidden! unless current_user.is_admin? end - def authorize! action, subject + def authorize!(action, subject) unless abilities.allowed?(current_user, action, subject) forbidden! end diff --git a/lib/event_filter.rb b/lib/event_filter.rb index 9b4b8c3801a..163937c02cf 100644 --- a/lib/event_filter.rb +++ b/lib/event_filter.rb @@ -23,7 +23,7 @@ class EventFilter end end - def initialize params + def initialize(params) @params = if params params.dup else @@ -31,7 +31,7 @@ class EventFilter end end - def apply_filter events + def apply_filter(events) return events unless params.present? filter = params.dup @@ -50,7 +50,7 @@ class EventFilter events = events.where(action: actions) end - def options key + def options(key) filter = params.dup if filter.include? key @@ -62,7 +62,7 @@ class EventFilter filter end - def active? key + def active?(key) params.include? key end end diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb index 907373ab991..f95bbde5b39 100644 --- a/lib/gitlab/backend/shell.rb +++ b/lib/gitlab/backend/shell.rb @@ -213,7 +213,7 @@ module Gitlab FileUtils.rm_r(satellites_path, force: true) end - def url_to_repo path + def url_to_repo(path) Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git" end diff --git a/lib/gitlab/diff/parser.rb b/lib/gitlab/diff/parser.rb index 9d6309954a4..f7c1f20d762 100644 --- a/lib/gitlab/diff/parser.rb +++ b/lib/gitlab/diff/parser.rb @@ -72,7 +72,7 @@ module Gitlab end end - def html_escape str + def html_escape(str) replacements = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } str.gsub(/[&"'><]/, replacements) end diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb index 89c8e0680c3..3517ecdf5cf 100644 --- a/lib/gitlab/inline_diff.rb +++ b/lib/gitlab/inline_diff.rb @@ -5,7 +5,7 @@ module Gitlab START = "#!idiff-start!#" FINISH = "#!idiff-finish!#" - def processing diff_arr + def processing(diff_arr) indexes = _indexes_of_changed_lines diff_arr indexes.each do |index| @@ -52,7 +52,7 @@ module Gitlab diff_arr end - def _indexes_of_changed_lines diff_arr + def _indexes_of_changed_lines(diff_arr) chain_of_first_symbols = "" diff_arr.each_with_index do |line, i| chain_of_first_symbols += line[0] @@ -68,7 +68,7 @@ module Gitlab indexes end - def replace_markers line + def replace_markers(line) line.gsub!(START, "") line.gsub!(FINISH, "") line diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb index 64cf3303ea3..8a73ec5038a 100644 --- a/lib/gitlab/logger.rb +++ b/lib/gitlab/logger.rb @@ -15,7 +15,7 @@ module Gitlab tail_output.split("\n") end - def self.read_latest_for filename + def self.read_latest_for(filename) path = Rails.root.join("log", filename) tail_output, _ = Gitlab::Popen.popen(%W(tail -n 2000 #{path})) tail_output.split("\n") diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 1eda614807f..73b19ad55d5 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -9,38 +9,38 @@ module Gitlab @users, @issues, @merge_requests, @snippets, @commits = [], [], [], [], [] end - def analyze string + def analyze(string) parse_references(string.dup) end # Given a valid project, resolve the extracted identifiers of the requested type to # model objects. - def users_for project + def users_for(project) users.map do |identifier| project.users.where(username: identifier).first end.reject(&:nil?) end - def issues_for project + def issues_for(project) issues.map do |identifier| project.issues.where(iid: identifier).first end.reject(&:nil?) end - def merge_requests_for project + def merge_requests_for(project) merge_requests.map do |identifier| project.merge_requests.where(iid: identifier).first end.reject(&:nil?) end - def snippets_for project + def snippets_for(project) snippets.map do |identifier| project.snippets.where(id: identifier).first end.reject(&:nil?) end - def commits_for project + def commits_for(project) repo = project.repository return [] if repo.nil? diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index f34d661c9fc..1de84309d15 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -11,7 +11,7 @@ module Gitlab @project = project end - def log message + def log(message) Gitlab::Satellite::Logger.error(message) end diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb index 2af1e9e32f9..3eb1258d67e 100644 --- a/spec/lib/gitlab/satellite/action_spec.rb +++ b/spec/lib/gitlab/satellite/action_spec.rb @@ -97,7 +97,7 @@ describe 'Gitlab::Satellite::Action' do end class FileLockStatusChecker < File - def flocked? &block + def flocked?(&block) status = flock LOCK_EX|LOCK_NB case status when false -- cgit v1.2.1 From 5d8be4438add1183d91e030b852c628cf09f4916 Mon Sep 17 00:00:00 2001 From: Sullivan SENECHAL Date: Thu, 2 Oct 2014 00:21:29 +0200 Subject: Upgrade to Font Awesome v4.2 --- CHANGELOG | 1 + Gemfile | 2 +- Gemfile.lock | 4 ++-- app/assets/javascripts/application.js.coffee | 4 ++-- .../javascripts/behaviors/toggler_behavior.coffee | 4 ++-- app/assets/javascripts/markdown_area.js.coffee | 4 ++-- app/assets/stylesheets/gl_bootstrap.scss | 2 +- app/assets/stylesheets/sections/notes.scss | 3 +-- app/helpers/application_helper.rb | 2 +- app/helpers/events_helper.rb | 8 ++++---- app/helpers/icons_helper.rb | 10 +++++----- app/helpers/notes_helper.rb | 2 +- app/helpers/notifications_helper.rb | 8 ++++---- app/helpers/projects_helper.rb | 4 ++-- app/helpers/tree_helper.rb | 4 ++-- app/views/admin/background_jobs/show.html.haml | 6 +++--- app/views/admin/broadcast_messages/index.html.haml | 4 ++-- app/views/admin/groups/_form.html.haml | 2 +- app/views/admin/groups/index.html.haml | 2 +- app/views/admin/groups/show.html.haml | 4 ++-- app/views/admin/logs/show.html.haml | 16 ++++++++-------- app/views/admin/projects/show.html.haml | 8 ++++---- app/views/admin/users/index.html.haml | 8 ++++---- app/views/admin/users/show.html.haml | 8 ++++---- app/views/dashboard/_groups.html.haml | 4 ++-- app/views/dashboard/_project.html.haml | 2 +- app/views/dashboard/_projects.html.haml | 4 ++-- app/views/dashboard/_projects_filter.html.haml | 4 ++-- app/views/dashboard/_sidebar.html.haml | 2 +- .../dashboard/_zero_authorized_projects.html.haml | 6 +++--- app/views/dashboard/issues.html.haml | 2 +- app/views/dashboard/merge_requests.html.haml | 2 +- app/views/dashboard/projects.html.haml | 8 ++++---- app/views/dashboard/show.html.haml | 2 +- app/views/events/event/_note.html.haml | 4 ++-- app/views/explore/groups/index.html.haml | 2 +- app/views/explore/projects/_project.html.haml | 2 +- app/views/explore/projects/starred.html.haml | 2 +- app/views/explore/projects/trending.html.haml | 2 +- app/views/groups/_projects.html.haml | 4 ++-- app/views/groups/_settings_nav.html.haml | 4 ++-- app/views/groups/edit.html.haml | 2 +- app/views/groups/group_members/_group_member.html.haml | 6 +++--- app/views/groups/issues.html.haml | 2 +- app/views/groups/members.html.haml | 2 +- app/views/groups/merge_requests.html.haml | 2 +- app/views/groups/milestones/index.html.haml | 2 +- app/views/groups/new.html.haml | 2 +- app/views/groups/projects.html.haml | 2 +- app/views/groups/show.html.haml | 2 +- app/views/help/_shortcuts.html.haml | 16 ++++++++-------- app/views/layouts/_broadcast.html.haml | 2 +- app/views/layouts/_head_panel.html.haml | 18 +++++++++--------- app/views/layouts/_public_head_panel.html.haml | 2 +- app/views/profiles/accounts/show.html.haml | 2 +- app/views/profiles/groups/index.html.haml | 6 +++--- app/views/profiles/notifications/_settings.html.haml | 2 +- app/views/profiles/show.html.haml | 2 +- app/views/projects/_dropdown.html.haml | 6 +++--- app/views/projects/_issuable_form.html.haml | 4 ++-- app/views/projects/_settings_nav.html.haml | 12 ++++++------ app/views/projects/blame/show.html.haml | 2 +- app/views/projects/blob/_blob.html.haml | 4 ++-- app/views/projects/blob/_download.html.haml | 2 +- app/views/projects/branches/_branch.html.haml | 6 +++--- app/views/projects/branches/index.html.haml | 2 +- app/views/projects/branches/new.html.haml | 2 +- app/views/projects/commit/_commit_box.html.haml | 4 ++-- app/views/projects/commits/_commit.html.haml | 2 +- app/views/projects/commits/_commits.html.haml | 2 +- app/views/projects/commits/show.html.haml | 2 +- app/views/projects/deploy_keys/_deploy_key.html.haml | 6 +++--- app/views/projects/deploy_keys/index.html.haml | 2 +- app/views/projects/diffs/_file.html.haml | 2 +- app/views/projects/diffs/_stats.html.haml | 10 +++++----- app/views/projects/edit.html.haml | 6 +++--- app/views/projects/edit_tree/show.html.haml | 4 ++-- app/views/projects/fork.html.haml | 4 ++-- app/views/projects/graphs/show.html.haml | 2 +- app/views/projects/import.html.haml | 2 +- app/views/projects/issues/_head.html.haml | 8 ++++---- app/views/projects/issues/_issue.html.haml | 6 +++--- app/views/projects/issues/_issues.html.haml | 4 ++-- app/views/projects/issues/index.html.haml | 2 +- app/views/projects/issues/show.html.haml | 4 ++-- .../projects/merge_requests/_merge_request.html.haml | 8 ++++---- .../projects/merge_requests/_new_submit.html.haml | 6 +++--- app/views/projects/merge_requests/_show.html.haml | 4 ++-- app/views/projects/merge_requests/index.html.haml | 8 ++++---- .../projects/merge_requests/show/_commits.html.haml | 2 +- .../projects/merge_requests/show/_mr_accept.html.haml | 4 ++-- .../projects/merge_requests/show/_mr_ci.html.haml | 10 +++++----- .../projects/merge_requests/show/_mr_title.html.haml | 4 ++-- .../show/_remove_source_branch.html.haml | 4 ++-- .../merge_requests/show/_state_widget.html.haml | 2 +- app/views/projects/milestones/_milestone.html.haml | 2 +- app/views/projects/milestones/index.html.haml | 4 ++-- app/views/projects/milestones/show.html.haml | 4 ++-- app/views/projects/network/show.html.haml | 2 +- app/views/projects/new.html.haml | 6 +++--- app/views/projects/new_tree/show.html.haml | 2 +- .../projects/notes/_diff_notes_with_reply.html.haml | 2 +- .../notes/_diff_notes_with_reply_parallel.html.haml | 4 ++-- app/views/projects/notes/_form.html.haml | 2 +- app/views/projects/notes/_note.html.haml | 16 ++++++++-------- app/views/projects/notes/discussions/_active.html.haml | 2 +- app/views/projects/notes/discussions/_commit.html.haml | 2 +- .../projects/notes/discussions/_outdated.html.haml | 2 +- app/views/projects/protected_branches/index.html.haml | 2 +- .../projects/repositories/_download_archive.html.haml | 14 +++++++------- app/views/projects/show.html.haml | 6 +++--- app/views/projects/snippets/show.html.haml | 2 +- app/views/projects/tags/_tag.html.haml | 4 ++-- app/views/projects/tags/index.html.haml | 2 +- app/views/projects/tags/new.html.haml | 2 +- .../projects/team_members/_group_members.html.haml | 2 +- app/views/projects/team_members/_team_member.html.haml | 2 +- app/views/projects/tree/_readme.html.haml | 2 +- app/views/projects/tree/_spinner.html.haml | 2 +- app/views/projects/tree/_submodule_item.html.haml | 2 +- app/views/projects/tree/_tree.html.haml | 4 ++-- app/views/projects/wikis/_main_links.html.haml | 2 +- app/views/projects/wikis/_nav.html.haml | 4 ++-- app/views/search/_filter.html.haml | 4 ++-- app/views/search/_project_filter.html.haml | 8 ++++---- app/views/search/_snippet_filter.html.haml | 4 ++-- app/views/search/results/_blob.html.haml | 2 +- app/views/search/results/_empty.html.haml | 2 +- app/views/search/results/_note.html.haml | 2 +- app/views/search/results/_snippet_blob.html.haml | 4 ++-- app/views/search/results/_snippet_title.html.haml | 2 +- app/views/search/results/_wiki_blob.html.haml | 2 +- app/views/shared/_file_hljs.html.haml | 2 +- app/views/shared/_filter.html.haml | 2 +- app/views/shared/_project_filter.html.haml | 6 +++--- app/views/snippets/_snippet.html.haml | 2 +- app/views/snippets/show.html.haml | 4 ++-- app/views/users/show.html.haml | 2 +- features/steps/profile/group.rb | 8 ++++---- spec/helpers/notifications_helper_spec.rb | 8 ++++---- spec/support/login_helpers.rb | 2 +- 141 files changed, 290 insertions(+), 290 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0250b4a23c0..86f544091c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ v 7.4.0 - Fail harder in the backup script - Zen mode for wiki and milestones (Robert Schilling) - Move Emoji parsing to html-pipeline-gitlab (Robert Schilling) + - Font Awesome 4.2 integration (Sullivan Senechal) v 7.3.2 - Fix creating new file via web editor diff --git a/Gemfile b/Gemfile index 3d9af1c91c2..3ea6adf5dce 100644 --- a/Gemfile +++ b/Gemfile @@ -180,7 +180,7 @@ gem "jquery-ui-rails" gem "jquery-scrollto-rails" gem "raphael-rails", "~> 2.1.2" gem 'bootstrap-sass', '~> 3.0' -gem "font-awesome-rails", '~> 3.2' +gem "font-awesome-rails", '~> 4.2' gem "gitlab_emoji", "~> 0.0.1.1" gem "gon", '~> 5.0.0' gem 'nprogress-rails' diff --git a/Gemfile.lock b/Gemfile.lock index d0f29258ffa..42f50d58806 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -152,7 +152,7 @@ GEM net-ssh (>= 2.1.3) fog-json (1.0.0) multi_json (~> 1.0) - font-awesome-rails (3.2.1.3) + font-awesome-rails (4.2.0.0) railties (>= 3.2, < 5.0) foreman (0.63.0) dotenv (>= 0.7) @@ -614,7 +614,7 @@ DEPENDENCIES factory_girl_rails ffaker fog (~> 1.14) - font-awesome-rails (~> 3.2) + font-awesome-rails (~> 4.2) foreman gemnasium-gitlab-service (~> 0.2) github-markup diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee index 8d377057d16..a1a4dc8e24f 100644 --- a/app/assets/javascripts/application.js.coffee +++ b/app/assets/javascripts/application.js.coffee @@ -172,8 +172,8 @@ $ -> # Show/hide comments on diff $("body").on "click", ".js-toggle-diff-comments", (e) -> $(@).find('i'). - toggleClass('icon-chevron-down'). - toggleClass('icon-chevron-up') + toggleClass('fa fa-chevron-down'). + toggleClass('fa fa-chevron-up') $(@).closest(".diff-file").find(".notes_holder").toggle() e.preventDefault() diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee index 1b2ed9efc25..177b6918270 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ b/app/assets/javascripts/behaviors/toggler_behavior.coffee @@ -8,7 +8,7 @@ $ -> # $("body").on "click", ".js-toggle-button", (e) -> $(@).find('i'). - toggleClass('icon-chevron-down'). - toggleClass('icon-chevron-up') + toggleClass('fa fa-chevron-down'). + toggleClass('fa fa-chevron-up') $(@).closest(".js-toggle-container").find(".js-toggle-content").toggle() e.preventDefault() diff --git a/app/assets/javascripts/markdown_area.js.coffee b/app/assets/javascripts/markdown_area.js.coffee index fca7b5bc030..a0ebfc98ce6 100644 --- a/app/assets/javascripts/markdown_area.js.coffee +++ b/app/assets/javascripts/markdown_area.js.coffee @@ -7,8 +7,8 @@ $(document).ready -> divHover = "
" divSpinner = "
" divAlert = "
" - iconPicture = "" - iconSpinner = "" + iconPicture = "" + iconSpinner = "" btnAlert = "" project_image_path_upload = window.project_image_path_upload or null diff --git a/app/assets/stylesheets/gl_bootstrap.scss b/app/assets/stylesheets/gl_bootstrap.scss index 34b0608646c..45044c5acb6 100644 --- a/app/assets/stylesheets/gl_bootstrap.scss +++ b/app/assets/stylesheets/gl_bootstrap.scss @@ -124,7 +124,7 @@ $list-group-active-bg: $bg_primary; color: #888; text-shadow: 0 1px 1px #fff; } - i[class^="icon-"] { + i[class~="fa"] { line-height: 14px; } } diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss index d1bdc9aa179..7eb42fddade 100644 --- a/app/assets/stylesheets/sections/notes.scss +++ b/app/assets/stylesheets/sections/notes.scss @@ -119,8 +119,7 @@ ul.notes { display: none; float: right; - [class^="icon-"], - [class*="icon-"] { + [class~="fa"] { font-size: 16px; line-height: 16px; vertical-align: middle; diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 728c5041074..34d312b4100 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -229,7 +229,7 @@ module ApplicationHelper css_class << " hide" unless visible content_tag :div, class: css_class do - content_tag(:i, nil, class: 'icon-spinner icon-spin') + text + content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 10a895d8cae..6aeab7bb8ce 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -36,10 +36,10 @@ module EventsHelper def icon_for_event { - EventFilter.push => "icon-upload-alt", - EventFilter.merged => "icon-check", - EventFilter.comments => "icon-comments", - EventFilter.team => "icon-user", + EventFilter.push => 'fa fa-upload', + EventFilter.merged => 'fa fa-check-square-o', + EventFilter.comments => 'fa fa-comments', + EventFilter.team => 'fa fa-user', } end diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb index f0f771b4ba0..aaa8f8d0077 100644 --- a/app/helpers/icons_helper.rb +++ b/app/helpers/icons_helper.rb @@ -1,21 +1,21 @@ module IconsHelper def boolean_to_icon(value) if value.to_s == "true" - content_tag :i, nil, class: 'icon-circle cgreen' + content_tag :i, nil, class: 'fa fa-circle cgreen' else - content_tag :i, nil, class: 'icon-off clgray' + content_tag :i, nil, class: 'fa fa-power-off clgray' end end def public_icon - content_tag :i, nil, class: 'icon-globe' + content_tag :i, nil, class: 'fa fa-globe' end def internal_icon - content_tag :i, nil, class: 'icon-shield' + content_tag :i, nil, class: 'fa fa-shield' end def private_icon - content_tag :i, nil, class: 'icon-lock' + content_tag :i, nil, class: 'fa fa-lock' end end diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 15d4b875c4c..901052edec6 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -69,7 +69,7 @@ module NotesHelper button_tag class: 'btn reply-btn js-discussion-reply-button', data: data, title: 'Add a reply' do - link_text = content_tag(:i, nil, class: 'icon-comment') + link_text = content_tag(:i, nil, class: 'fa fa-comment') link_text << ' Reply' end end diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index 6c43f97446b..bad380e98a8 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -1,13 +1,13 @@ module NotificationsHelper def notification_icon(notification) if notification.disabled? - content_tag :i, nil, class: 'icon-volume-off ns-mute' + content_tag :i, nil, class: 'fa fa-volume-off ns-mute' elsif notification.participating? - content_tag :i, nil, class: 'icon-volume-down ns-part' + content_tag :i, nil, class: 'fa fa-volume-down ns-part' elsif notification.watch? - content_tag :i, nil, class: 'icon-volume-up ns-watch' + content_tag :i, nil, class: 'fa fa-volume-up ns-watch' else - content_tag :i, nil, class: 'icon-circle-blank ns-default' + content_tag :i, nil, class: 'fa fa-circle-o ns-default' end end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6a16f112cb3..6df7dae7314 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -133,7 +133,7 @@ module ProjectsHelper 'Star' end - content_tag('i', ' ', class: 'icon-star') + toggle_text + content_tag('i', ' ', class: 'fa fa-star') + toggle_text end count_html = content_tag('span', class: 'count') do @@ -157,7 +157,7 @@ module ProjectsHelper end def link_to_toggle_fork - out = content_tag(:i, '', class: 'icon-code-fork') + out = content_tag(:i, '', class: 'fa fa-code-fork') out << ' Fork' out << content_tag(:span, class: 'count') do @project.forks_count.to_s diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index ed3c401d873..c3b537eac47 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -36,9 +36,9 @@ module TreeHelper # type - String type of the tree item; either 'folder' or 'file' def tree_icon(type) icon_class = if type == 'folder' - 'icon-folder-close' + 'fa fa-folder' else - 'icon-file-alt' + 'fa fa-file-o' end content_tag :i, nil, class: icon_class diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml index c79d1280dd9..9dcf7b488ee 100644 --- a/app/views/admin/background_jobs/show.html.haml +++ b/app/views/admin/background_jobs/show.html.haml @@ -8,7 +8,7 @@ .panel-body - if @sidekiq_processes.empty? %h4.cred - %i.icon-warning-sign + %i.fa.fa-exclamation-triangle There are no running sidekiq processes. Please restart GitLab - else %table.table @@ -32,10 +32,10 @@ .clearfix %p - %i.icon-exclamation-sign + %i.fa.fa-exclamation-circle If '[25 of 25 busy]' is shown, restart GitLab with 'sudo service gitlab reload'. %p - %i.icon-exclamation-sign + %i.fa.fa-exclamation-circle If more than one sidekiq process is listed, stop GitLab, kill the remaining sidekiq processes (sudo pkill -u #{Settings.gitlab.user} -f sidekiq) and restart GitLab. diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml index c58ca2c9a33..7b483ee6556 100644 --- a/app/views/admin/broadcast_messages/index.html.haml +++ b/app/views/admin/broadcast_messages/index.html.haml @@ -3,7 +3,7 @@ %p.light Broadcast messages are displayed for every user and can be used to notify users about scheduled maintenance, recent upgrades and more. .broadcast-message-preview - %i.icon-bullhorn + %i.fa.fa-bullhorn %span Your message here = form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal'} do |f| @@ -53,7 +53,7 @@ #{broadcast_message.ends_at.to_s(:short)}   = link_to [:admin, broadcast_message], method: :delete, remote: true, class: 'remove-row btn btn-tiny' do - %i.icon-remove.cred + %i.fa.fa-times.cred .message= broadcast_message.message diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml index 31990ee5932..c56863ce274 100644 --- a/app/views/admin/groups/_form.html.haml +++ b/app/views/admin/groups/_form.html.haml @@ -17,7 +17,7 @@ = f.label :avatar, "Group avatar", class: 'control-label' .col-sm-10 %a.choose-btn.btn.btn-small.js-choose-group-avatar-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-avatar-filename File name... diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml index 9a0d5967927..09105679bd2 100644 --- a/app/views/admin/groups/index.html.haml +++ b/app/views/admin/groups/index.html.haml @@ -24,7 +24,7 @@ %h4 = link_to [:admin, group] do - %i.icon-folder-close + %i.fa.fa-folder = group.name → diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index d59d2a23179..c1a9214b77a 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -2,7 +2,7 @@ Group: #{@group.name} = link_to edit_admin_group_path(@group), class: "btn pull-right" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit %hr .row @@ -81,6 +81,6 @@ %span.pull-right.light = member.human_access = link_to group_group_members_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - %i.icon-minus.icon-white + %i.fa.fa-minus.fa-inverse .panel-footer = paginate @members, param_name: 'members_page', theme: 'gitlab' diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml index cce8aeb02c7..b3f8f012f00 100644 --- a/app/views/admin/logs/show.html.haml +++ b/app/views/admin/logs/show.html.haml @@ -13,11 +13,11 @@ .tab-pane.active#githost .file-holder#README .file-title - %i.icon-file + %i.fa.fa-file githost.log .pull-right = link_to '#', class: 'log-bottom' do - %i.icon-arrow-down + %i.fa.fa-arrow-down Scroll down .file-content.logs %ol @@ -27,11 +27,11 @@ .tab-pane#application .file-holder#README .file-title - %i.icon-file + %i.fa.fa-file application.log .pull-right = link_to '#', class: 'log-bottom' do - %i.icon-arrow-down + %i.fa.fa-arrow-down Scroll down .file-content.logs %ol @@ -41,11 +41,11 @@ .tab-pane#production .file-holder#README .file-title - %i.icon-file + %i.fa.fa-file production.log .pull-right = link_to '#', class: 'log-bottom' do - %i.icon-arrow-down + %i.fa.fa-arrow-down Scroll down .file-content.logs %ol @@ -55,11 +55,11 @@ .tab-pane#sidekiq .file-holder#README .file-title - %i.icon-file + %i.fa.fa-file sidekiq.log .pull-right = link_to '#', class: 'log-bottom' do - %i.icon-arrow-down + %i.fa.fa-arrow-down Scroll down .file-content.logs %ol diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 8413f0cb7f9..6d536199851 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -1,7 +1,7 @@ %h3.page-title Project: #{@project.name_with_namespace} = link_to edit_project_path(@project), class: "btn pull-right" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit %hr .row @@ -98,7 +98,7 @@ group members (#{@group.group_members.count}) .pull-right = link_to admin_group_path(@group), class: 'btn btn-small' do - %i.icon-edit + %i.fa.fa-pencil-square-o %ul.well-list - @group_members.each do |member| = render 'groups/group_members/group_member', member: member, show_controls: false @@ -112,7 +112,7 @@ (#{@project.users.count}) .pull-right = link_to project_team_index_path(@project), class: "btn btn-tiny" do - %i.icon-edit + %i.fa.fa-pencil-square-o Manage Access %ul.well-list.team_members - @project_members.each do |project_member| @@ -127,6 +127,6 @@ - else %span.light= project_member.human_access = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, remote: true, class: "btn btn-small btn-remove" do - %i.icon-remove + %i.fa.fa-times .panel-footer = paginate @project_members, param_name: 'project_members_page', theme: 'gitlab' diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index f2fa5ea91c1..5c2664e14fe 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -23,7 +23,7 @@ .form-group = search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'form-control' = button_tag class: 'btn btn-primary' do - %i.icon-search + %i.fa.fa-search %hr = link_to 'Reset', admin_users_path, class: "btn btn-cancel" @@ -38,9 +38,9 @@ %li .list-item-name - if user.blocked? - %i.icon-lock.cred + %i.fa.fa-lock.cred - else - %i.icon-user.cgreen + %i.fa.fa-user.cgreen = link_to user.name, [:admin, user] - if user.admin? %strong.cred (Admin) @@ -48,7 +48,7 @@ %span.cred It's you! .pull-right %span.light - %i.icon-envelope + %i.fa.fa-envelope = mail_to user.email, user.email, class: 'light'   = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn btn-small" diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index c8295cf707e..211d77d5185 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -8,7 +8,7 @@ .pull-right = link_to edit_admin_user_path(@user), class: "btn btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit %hr %ul.nav.nav-tabs @@ -45,7 +45,7 @@ %span.light Secondary email: %strong= email.email = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-tiny btn btn-remove pull-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do - %i.icon-remove + %i.fa.fa-times %li %span.light Can create groups: @@ -177,7 +177,7 @@ %span.light= user_group.human_access - unless user_group.owner? = link_to group_group_member_path(group, user_group), data: { confirm: remove_user_from_group_message(group, @user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - %i.icon-remove.icon-white + %i.fa.fa-times.fa-inverse - else .nothing-here-block This user has no groups. @@ -216,4 +216,4 @@ - if tm.respond_to? :project = link_to project_team_member_path(project, @user), data: { confirm: remove_from_project_team_message(project, @user) }, remote: true, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from project' do - %i.icon-remove + %i.fa.fa-times diff --git a/app/views/dashboard/_groups.html.haml b/app/views/dashboard/_groups.html.haml index 9bcc77b8d8e..5460cf56f22 100644 --- a/app/views/dashboard/_groups.html.haml +++ b/app/views/dashboard/_groups.html.haml @@ -3,7 +3,7 @@ = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' - if current_user.can_create_group? = link_to new_group_path, class: "btn btn-new pull-right" do - %i.icon-plus + %i.fa.fa-plus New group %ul.well-list.dash-list - groups.each do |group| @@ -13,7 +13,7 @@ %span.group-name.filter-title = truncate(group.name, length: 35) %span.arrow - %i.icon-angle-right + %i.fa.fa-angle-right - if groups.blank? %li .nothing-here-block You have no groups yet. diff --git a/app/views/dashboard/_project.html.haml b/app/views/dashboard/_project.html.haml index e326bee53ab..89ed5102754 100644 --- a/app/views/dashboard/_project.html.haml +++ b/app/views/dashboard/_project.html.haml @@ -9,4 +9,4 @@ %span.project-name.filter-title = project.name %span.arrow - %i.icon-angle-right + %i.fa.fa-angle-right diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml index 0cc253a8dd1..3598425777f 100644 --- a/app/views/dashboard/_projects.html.haml +++ b/app/views/dashboard/_projects.html.haml @@ -3,7 +3,7 @@ = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' - if current_user.can_create_project? = link_to new_project_path, class: "btn btn-new pull-right" do - %i.icon-plus + %i.fa.fa-plus New project %ul.well-list.dash-list @@ -21,4 +21,4 @@ .pull-right = link_to projects_dashboard_path do Show all - %i.icon-angle-right + %i.fa.fa-angle-right diff --git a/app/views/dashboard/_projects_filter.html.haml b/app/views/dashboard/_projects_filter.html.haml index e4fa2d59e8a..b65e882e693 100644 --- a/app/views/dashboard/_projects_filter.html.haml +++ b/app/views/dashboard/_projects_filter.html.haml @@ -37,7 +37,7 @@ - @groups.each do |group| %li{ class: (group.name == params[:group]) ? 'active' : 'light' } = link_to projects_dashboard_filter_path(group: group.name) do - %i.icon-folder-close-alt + %i.fa.fa-folder-o = group.name %small.pull-right = group.projects.count @@ -51,5 +51,5 @@ - @tags.each do |tag| %li{ class: (tag.name == params[:tag]) ? 'active' : 'light' } = link_to projects_dashboard_filter_path(scope: params[:scope], tag: tag.name) do - %i.icon-tag + %i.fa.fa-tag = tag.name diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml index fed4b2776ae..add9eb7fa29 100644 --- a/app/views/dashboard/_sidebar.html.haml +++ b/app/views/dashboard/_sidebar.html.haml @@ -18,7 +18,7 @@ %span.rss-icon = link_to dashboard_path(:atom, { private_token: current_user.private_token }) do %strong - %i.icon-rss + %i.fa.fa-rss News Feed %hr diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml index ff85e32bc4e..711e607f0bc 100644 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/_zero_authorized_projects.html.haml @@ -3,7 +3,7 @@ %hr %div .dashboard-intro-icon - %i.icon-bookmark-empty + %i.fa.fa-bookmark-o %div %p.slead You don't have access to any projects right now. @@ -23,7 +23,7 @@ %hr %div .dashboard-intro-icon - %i.icon-group + %i.fa.fa-users %div %p.slead You can create a group for several dependent projects. @@ -37,7 +37,7 @@ %hr %div .dashboard-intro-icon - %i.icon-globe + %i.fa.fa-globe %div %p.slead There are diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index d3ff291eaa8..7c1f1ddbb80 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -7,7 +7,7 @@ .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/filter', entity: 'issue' .col-md-9 diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 7a9ea9f6f90..c96584c7b6b 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -7,7 +7,7 @@ %hr .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/filter', entity: 'merge_request' .col-md-9 diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml index 2714ebc53de..f124c688be1 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -40,23 +40,23 @@ - if current_user.can_leave_project?(project) .pull-right = link_to leave_project_team_members_path(project), data: { confirm: "Leave project?"}, method: :delete, remote: true, class: "btn-tiny btn remove-row", title: 'Leave project' do - %i.icon-signout + %i.fa.fa-sign-out Leave - if project.forked_from_project %small.pull-right - %i.icon-code-fork + %i.fa.fa-code-fork Forked from: = link_to project.forked_from_project.name_with_namespace, project_path(project.forked_from_project) .project-info .pull-right - if project.archived? %span.label - %i.icon-archive + %i.fa.fa-archive Archived - project.tags.each do |tag| %span.label.label-info - %i.icon-tag + %i.fa.fa-tag = tag.name - if project.description.present? %p= truncate project.description, length: 100 diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml index 6a08b1aa640..10951af6a09 100644 --- a/app/views/dashboard/show.html.haml +++ b/app/views/dashboard/show.html.haml @@ -6,7 +6,7 @@ = render 'sidebar' .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x - else = render "zero_authorized_projects" diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml index ad2afbce14c..6ec8e54fba5 100644 --- a/app/views/events/event/_note.html.haml +++ b/app/views/events/event/_note.html.haml @@ -9,7 +9,7 @@ .event-body .event-note .md - %i.icon-comment-alt.event-note-icon + %i.fa.fa-comment-o.event-note-icon = event_note(event.target.note) - note = event.target - if note.attachment.url @@ -18,5 +18,5 @@ = image_tag note.attachment.secure_url, class: 'note-image-attach' - else = link_to note.attachment.secure_url, target: "_blank", class: 'note-file-attach' do - %i.icon-paper-clip + %i.fa.fa-paperclip = note.attachment_identifier diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml index 80ddd5c1bde..c8243ff782c 100644 --- a/app/views/explore/groups/index.html.haml +++ b/app/views/explore/groups/index.html.haml @@ -36,7 +36,7 @@ .clearfix %h4 = link_to group_path(id: group.path) do - %i.icon-group + %i.fa.fa-users = group.name .clearfix %p diff --git a/app/views/explore/projects/_project.html.haml b/app/views/explore/projects/_project.html.haml index fd5aacbfdb4..4bc79d0a8c7 100644 --- a/app/views/explore/projects/_project.html.haml +++ b/app/views/explore/projects/_project.html.haml @@ -21,5 +21,5 @@ · = link_to pluralize(project.repository.tag_names.count, 'tag'), project_tags_path(project) - else - %i.icon-warning-sign + %i.fa.fa-exclamation-triangle Empty repository diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml index 9c793d4050c..d4b11405517 100644 --- a/app/views/explore/projects/starred.html.haml +++ b/app/views/explore/projects/starred.html.haml @@ -1,6 +1,6 @@ .explore-trending-block %p.lead - %i.icon-comments-alt + %i.fa.fa-comments-o See most starred projects %hr .public-projects diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index 18bb1ac0ba4..9cad9238933 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -1,6 +1,6 @@ .explore-trending-block %p.lead - %i.icon-comments-alt + %i.fa.fa-comments-o See most discussed projects for last month %hr .public-projects diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml index 2ebff21b819..2c65b3049e3 100644 --- a/app/views/groups/_projects.html.haml +++ b/app/views/groups/_projects.html.haml @@ -4,7 +4,7 @@ - if can? current_user, :create_projects, @group .panel-head-actions = link_to new_project_path(namespace_id: @group.id), class: "btn btn-new" do - %i.icon-plus + %i.fa.fa-plus New project %ul.well-list - if projects.blank? @@ -18,4 +18,4 @@ %span.project-name = project.name %span.arrow - %i.icon-angle-right + %i.fa.fa-angle-right diff --git a/app/views/groups/_settings_nav.html.haml b/app/views/groups/_settings_nav.html.haml index 32eae31a47d..ec1fb4a2c00 100644 --- a/app/views/groups/_settings_nav.html.haml +++ b/app/views/groups/_settings_nav.html.haml @@ -1,10 +1,10 @@ %ul.nav.nav-pills.nav-stacked.nav-stacked-menu = nav_link(path: 'groups#edit') do = link_to edit_group_path(@group) do - %i.icon-edit + %i.fa.fa-pencil-square-o Group = nav_link(path: 'groups#projects') do = link_to projects_group_path(@group) do - %i.icon-folder-close + %i.fa.fa-folder Projects diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 97f22df044f..0b15affe785 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -32,7 +32,7 @@ - else You can upload a group avatar here %a.choose-btn.btn.btn-small.js-choose-group-avatar-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-avatar-filename File name... diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml index 099e50a384e..d05016d9c3f 100644 --- a/app/views/groups/group_members/_group_member.html.haml +++ b/app/views/groups/group_members/_group_member.html.haml @@ -15,14 +15,14 @@ - if show_controls - if can?(current_user, :modify, member) = link_to '#', class: "btn-tiny btn js-toggle-button", title: 'Edit access level' do - %i.icon-edit + %i.fa.fa-pencil-square-o - if can?(current_user, :destroy, member) - if current_user == member.user = link_to leave_profile_group_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - %i.icon-minus.icon-white + %i.fa.fa-minus.fa-inverse - else = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, user) }, method: :delete, remote: true, class: "btn-tiny btn btn-remove", title: 'Remove user from group' do - %i.icon-minus.icon-white + %i.fa.fa-minus.fa-inverse .edit-member.hide.js-toggle-content = form_for [@group, member], remote: true do |f| diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 0152ae86833..1932ba2f644 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -11,7 +11,7 @@ .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/filter', entity: 'issue' .col-md-9 diff --git a/app/views/groups/members.html.haml b/app/views/groups/members.html.haml index ebf407d4ef1..ba554cd5ef1 100644 --- a/app/views/groups/members.html.haml +++ b/app/views/groups/members.html.haml @@ -19,7 +19,7 @@ .pull-right = link_to '#', class: 'btn btn-new js-toggle-button' do Add members - %i.icon-chevron-down + %i.fa.fa-chevron-down .js-toggle-content.hide.new-group-member-holder = render "new_group_member" diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 71d346d0469..86d5acdaa32 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -10,7 +10,7 @@ %hr .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/filter', entity: 'merge_request' .col-md-9 diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index 54e901173f0..2727525f070 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -11,7 +11,7 @@ .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'groups/filter', entity: 'milestone' .col-md-9 diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml index cdc087f949a..235e299343a 100644 --- a/app/views/groups/new.html.haml +++ b/app/views/groups/new.html.haml @@ -17,7 +17,7 @@ = f.label :avatar, "Group avatar", class: 'control-label' .col-sm-10 %a.choose-btn.btn.btn-small.js-choose-group-avatar-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-avatar-filename File name... diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index a5e752d776f..65a66355c56 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -9,7 +9,7 @@ - if can? current_user, :manage_group, @group .panel-head-actions = link_to new_project_path(namespace_id: @group.id), class: "btn btn-new" do - %i.icon-plus + %i.fa.fa-plus New Project %ul.well-list - @projects.each do |project| diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 6db393c882c..4f4fc537d34 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -30,7 +30,7 @@ .prepend-top-20 = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed" do %strong - %i.icon-rss + %i.fa.fa-rss News Feed %hr diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml index ff83ff5bc4d..7b21ca30d8c 100644 --- a/app/views/help/_shortcuts.html.haml +++ b/app/views/help/_shortcuts.html.haml @@ -29,12 +29,12 @@ %tr %td.shortcut .key - %i.icon-arrow-up + %i.fa.fa-arrow-up %td Move selection up %tr %td.shortcut .key - %i.icon-arrow-down + %i.fa.fa-arrow-down %td Move selection down %tr %td.shortcut @@ -132,28 +132,28 @@ %tr %td.shortcut .key - %i.icon-arrow-left + %i.fa.fa-arrow-left \/ .key h %td Scroll left %tr %td.shortcut .key - %i.icon-arrow-right + %i.fa.fa-arrow-right \/ .key l %td Scroll right %tr %td.shortcut .key - %i.icon-arrow-up + %i.fa.fa-arrow-up \/ .key k %td Scroll up %tr %td.shortcut .key - %i.icon-arrow-down + %i.fa.fa-arrow-down \/ .key j %td Scroll down @@ -161,7 +161,7 @@ %td.shortcut .key shift - %i.icon-arrow-up + %i.fa.fa-arrow-up \/ .key shift k @@ -170,7 +170,7 @@ %td.shortcut .key shift - %i.icon-arrow-down + %i.fa.fa-arrow-down \/ .key shift j diff --git a/app/views/layouts/_broadcast.html.haml b/app/views/layouts/_broadcast.html.haml index 5794e3de338..e7d477c225e 100644 --- a/app/views/layouts/_broadcast.html.haml +++ b/app/views/layouts/_broadcast.html.haml @@ -1,4 +1,4 @@ - if broadcast_message.present? .broadcast-message{ style: broadcast_styling(broadcast_message) } - %i.icon-bullhorn + %i.fa.fa-bullhorn = broadcast_message.message diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index 7c727aca785..5dcaee2fa02 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -10,7 +10,7 @@ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} %span.sr-only Toggle navigation - %i.icon-reorder + %i.fa.fa-bars .navbar-collapse.collapse %ul.nav.navbar-nav @@ -18,31 +18,31 @@ = render "layouts/search" %li.visible-sm.visible-xs = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do - %i.icon-search + %i.fa.fa-search %li = link_to help_path, title: 'Help', class: 'has_bottom_tooltip', 'data-original-title' => 'Help' do - %i.icon-question-sign + %i.fa.fa-question-circle %li = link_to explore_root_path, title: "Explore", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.icon-globe + %i.fa.fa-globe %li = link_to user_snippets_path(current_user), title: "My snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'My snippets' do - %i.icon-paste + %i.fa.fa-clipboard - if current_user.is_admin? %li = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do - %i.icon-cogs + %i.fa.fa-cogs - if current_user.can_create_project? %li = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do - %i.icon-plus + %i.fa.fa-plus %li = link_to profile_path, title: "Profile settings", class: 'has_bottom_tooltip', 'data-original-title' => 'Profile settings"' do - %i.icon-user + %i.fa.fa-user %li = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do - %i.icon-signout + %i.fa.fa-sign-out %li.hidden-xs = link_to current_user, class: "profile-pic", id: 'profile-pic' do = image_tag avatar_icon(current_user.email, 26), alt: 'User activity' diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml index 945c66e2adf..9bfc14d16c1 100644 --- a/app/views/layouts/_public_head_panel.html.haml +++ b/app/views/layouts/_public_head_panel.html.haml @@ -10,7 +10,7 @@ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} %span.sr-only Toggle navigation - %i.icon-reorder + %i.fa.fa-bars .pull-right.hidden-xs = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-new' diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index c60e1ca9297..a21dcff41c0 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -52,7 +52,7 @@   .loading-gif.hide %p - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Saving new username %p.light = user_url(@user) diff --git a/app/views/profiles/groups/index.html.haml b/app/views/profiles/groups/index.html.haml index 2efe72b1bb3..e9ffca8faf4 100644 --- a/app/views/profiles/groups/index.html.haml +++ b/app/views/profiles/groups/index.html.haml @@ -3,7 +3,7 @@ - if current_user.can_create_group? %span.pull-right = link_to new_group_path, class: "btn btn-new" do - %i.icon-plus + %i.fa.fa-plus New Group %p.light Group members have access to all a group's projects @@ -19,12 +19,12 @@ .pull-right - if can?(current_user, :manage_group, group) = link_to edit_group_path(group), class: "btn-small btn btn-grouped" do - %i.icon-cogs + %i.fa.fa-cogs Settings - if can?(current_user, :destroy, user_group) = link_to leave_profile_group_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-small btn btn-grouped", title: 'Remove user from group' do - %i.icon-signout + %i.fa.fa-sign-out Leave = link_to group, class: 'group-name' do diff --git a/app/views/profiles/notifications/_settings.html.haml b/app/views/profiles/notifications/_settings.html.haml index 940c553d1ba..2c85d2a9b2b 100644 --- a/app/views/profiles/notifications/_settings.html.haml +++ b/app/views/profiles/notifications/_settings.html.haml @@ -1,5 +1,5 @@ %li - %span.notification-icon-holder + %span.notification.fa.fa-holder - if notification.global? = notification_icon(@notification) - else diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index ed19dccf53e..d6b52f86154 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -78,7 +78,7 @@ or change it at #{link_to "gravatar.com", "http://gravatar.com"} %hr %a.choose-btn.btn.btn-small.js-choose-user-avatar-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-avatar-filename File name... diff --git a/app/views/projects/_dropdown.html.haml b/app/views/projects/_dropdown.html.haml index e283bd2bf1d..6ff46970336 100644 --- a/app/views/projects/_dropdown.html.haml +++ b/app/views/projects/_dropdown.html.haml @@ -1,7 +1,7 @@ - if current_user .dropdown.pull-right %a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"} - %i.icon-reorder + %i.fa.fa-bars %ul.dropdown-menu - if @project.issues_enabled && can?(current_user, :write_issue, @project) %li @@ -23,11 +23,11 @@ %li.divider %li = link_to new_project_branch_path(@project) do - %i.icon-code-fork + %i.fa.fa-code-fork Git branch %li = link_to new_project_tag_path(@project) do - %i.icon-tag + %i.fa.fa-tag Git tag diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml index 0ae1fb3cabe..19aced75836 100644 --- a/app/views/projects/_issuable_form.html.haml +++ b/app/views/projects/_issuable_form.html.haml @@ -29,7 +29,7 @@ .form-group .issue-assignee = f.label :assignee_id, class: 'control-label' do - %i.icon-user + %i.fa.fa-user Assign to .col-sm-10 = project_users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]", @@ -40,7 +40,7 @@ .form-group .issue-milestone = f.label :milestone_id, class: 'control-label' do - %i.icon-time + %i.fa.fa-clock-o Milestone .col-sm-10= f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, { class: 'select2' }) diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml index 9b73f06a5be..2008f8c558d 100644 --- a/app/views/projects/_settings_nav.html.haml +++ b/app/views/projects/_settings_nav.html.haml @@ -1,25 +1,25 @@ %ul.nav.nav-pills.nav-stacked.nav-stacked-menu.append-bottom-20.project-settings-nav = nav_link(path: 'projects#edit') do = link_to edit_project_path(@project), class: "stat-tab tab " do - %i.icon-edit + %i.fa.fa-pencil-square-o Project = nav_link(controller: [:team_members, :teams]) do = link_to project_team_index_path(@project), class: "team-tab tab" do - %i.icon-group + %i.fa.fa-users Members = nav_link(controller: :deploy_keys) do = link_to project_deploy_keys_path(@project) do - %i.icon-key + %i.fa.fa-key Deploy Keys = nav_link(controller: :hooks) do = link_to project_hooks_path(@project) do - %i.icon-link + %i.fa.fa-link Web Hooks = nav_link(controller: :services) do = link_to project_services_path(@project) do - %i.icon-cogs + %i.fa.fa-cogs Services = nav_link(controller: :protected_branches) do = link_to project_protected_branches_path(@project) do - %i.icon-lock + %i.fa.fa-lock Protected branches diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index aca6fde2886..e5cde488c3c 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -3,7 +3,7 @@ #tree-holder.tree-holder .file-holder .file-title - %i.icon-file + %i.fa.fa-file %span.file_name = @path %small= number_to_human_size @blob.size diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml index be785dacedb..492dff437b5 100644 --- a/app/views/projects/blob/_blob.html.haml +++ b/app/views/projects/blob/_blob.html.haml @@ -1,6 +1,6 @@ %ul.breadcrumb.repo-breadcrumb %li - %i.icon-angle-right + %i.fa.fa-angle-right = link_to project_tree_path(@project, @ref) do = @project.path - tree_breadcrumbs(@tree, 6) do |title, path| @@ -22,7 +22,7 @@ %div#tree-content-holder.tree-content-holder %article.file-holder .file-title.clearfix - %i.icon-file + %i.fa.fa-file %span.file_name = blob.name %small= number_to_human_size blob.size diff --git a/app/views/projects/blob/_download.html.haml b/app/views/projects/blob/_download.html.haml index cdbfee7cc68..74a45cd8ae3 100644 --- a/app/views/projects/blob/_download.html.haml +++ b/app/views/projects/blob/_download.html.haml @@ -2,6 +2,6 @@ .center = link_to project_raw_path(@project, @id) do %h1.light - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %h4 Download (#{number_to_human_size blob.size}) diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index 08a537e0541..8e58f3c247a 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -7,19 +7,19 @@ %span.label.label-info default - if @project.protected_branch? branch.name %span.label.label-success - %i.icon-lock + %i.fa.fa-lock protected .pull-right - if can?(current_user, :download_code, @project) = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-small' - if branch.name != @repository.root_ref = link_to project_compare_index_path(@project, from: @repository.root_ref, to: branch.name), class: 'btn btn-grouped btn-small', method: :post, title: "Compare" do - %i.icon-copy + %i.fa.fa-files-o Compare - if can_remove_branch?(@project, branch.name) = link_to project_branch_path(@project, branch.name), class: 'btn btn-grouped btn-small btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do - %i.icon-trash + %i.fa.fa-trash-o - if commit %ul.list-unstyled diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index 8bc4a8f7e98..9f2b1b59292 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -4,7 +4,7 @@ .pull-right - if can? current_user, :push_code, @project = link_to new_project_branch_path(@project), class: 'btn btn-create' do - %i.icon-add-sign + %i.fa.fa-add-sign New branch   .dropdown.inline diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index 3f202f7ea6b..f5a530d95f2 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -3,7 +3,7 @@ %button{ type: "button", class: "close", "data-dismiss" => "alert"} × = @error %h3.page-title - %i.icon-code-fork + %i.fa.fa-code-fork New branch = form_tag project_branches_path, method: :post, class: "form-horizontal" do .form-group diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 2bc9048b2ad..80ead5b96a8 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -2,11 +2,11 @@ %div - if @notes_count > 0 %span.btn.disabled.btn-grouped - %i.icon-comment + %i.fa.fa-comment = @notes_count .pull-left.btn-group %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt Download as %span.caret %ul.dropdown-menu diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 8e73663939f..68852ba973f 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -18,7 +18,7 @@ - if note_count > 0 %span.label.label-gray - %i.icon-comment= note_count + %i.fa.fa-comment= note_count - if commit.description? .commit-row-description.js-toggle-content diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index 77f795f23f2..d57659065a8 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -2,7 +2,7 @@ .row.commits-row .col-md-2 %h4 - %i.icon-calendar + %i.fa.fa-calendar %span= day.stamp("28 Aug, 2010") %p= pluralize(commits.count, 'commit') .col-md-10 diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 482a845558f..5717c24c274 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -6,7 +6,7 @@ - if current_user && current_user.private_token .commits-feed-holder.hidden-xs.hidden-sm = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed", class: 'btn' do - %i.icon-rss + %i.fa.fa-rss Commits feed %ul.breadcrumb.repo-breadcrumb diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml index 2b4f36fb4b8..a0345dbd9c3 100644 --- a/app/views/projects/deploy_keys/_deploy_key.html.haml +++ b/app/views/projects/deploy_keys/_deploy_key.html.haml @@ -2,19 +2,19 @@ .pull-right - if @available_keys.include?(deploy_key) = link_to enable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do - %i.icon-plus + %i.fa.fa-plus Enable - else - if deploy_key.projects.count > 1 = link_to disable_project_deploy_key_path(@project, deploy_key), class: 'btn btn-small', method: :put do - %i.icon-off + %i.fa.fa-power-off Disable - else = link_to 'Remove', project_deploy_key_path(@project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :delete, class: "btn btn-remove delete-key btn-small pull-right" = link_to project_deploy_key_path(deploy_key.projects.include?(@project) ? @project : deploy_key.projects.first, deploy_key) do - %i.icon-key + %i.fa.fa-key %strong= deploy_key.title %p.light.prepend-top-10 diff --git a/app/views/projects/deploy_keys/index.html.haml b/app/views/projects/deploy_keys/index.html.haml index f50aeba337a..6f475e0b395 100644 --- a/app/views/projects/deploy_keys/index.html.haml +++ b/app/views/projects/deploy_keys/index.html.haml @@ -2,7 +2,7 @@ Deploy keys allow read-only access to the repository = link_to new_project_deploy_key_path(@project), class: "btn btn-new pull-right", title: "New Deploy Key" do - %i.icon-plus + %i.fa.fa-plus New Deploy Key %p.light diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 751df6a02e9..c415ae2ddc8 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -22,7 +22,7 @@ Wrap text   = link_to '#', class: 'js-toggle-diff-comments btn btn-small' do - %i.icon-chevron-down + %i.fa.fa-chevron-down Diff comments   diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml index 8ef7cc6e086..20e51d18da5 100644 --- a/app/views/projects/diffs/_stats.html.haml +++ b/app/views/projects/diffs/_stats.html.haml @@ -11,7 +11,7 @@   = link_to '#', class: 'btn btn-small js-toggle-button' do Show diff stats - %i.icon-chevron-down + %i.fa.fa-chevron-down .file-stats.js-toggle-content.hide %ul.bordered-list - diffs.each_with_index do |diff, i| @@ -19,23 +19,23 @@ - if diff.deleted_file %span.deleted-file %a{href: "#diff-#{i}"} - %i.icon-minus + %i.fa.fa-minus = diff.old_path - elsif diff.renamed_file %span.renamed-file %a{href: "#diff-#{i}"} - %i.icon-minus + %i.fa.fa-minus = diff.old_path \-> = diff.new_path - elsif diff.new_file %span.new-file %a{href: "#diff-#{i}"} - %i.icon-plus + %i.fa.fa-plus = diff.new_path - else %span.edit-file %a{href: "#diff-#{i}"} - %i.icon-adjust + %i.fa.fa-adjust = diff.new_path diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index d9acb685517..5ee5641b069 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -89,13 +89,13 @@ .danger-settings.js-toggle-container .centered-light-block %h3 - %i.icon-warning-sign + %i.fa.fa-exclamation-triangle Dangerous settings %p Project settings below may result in data loss! = link_to '#', class: 'btn js-toggle-button' do Show them to me - %i.icon-chevron-down + %i.fa.fa-chevron-down .js-toggle-content.hide - if can? current_user, :archive_project, @project @@ -185,6 +185,6 @@ .save-project-loader.hide .center %h2 - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Saving project. %p Please wait a moment, this page will automatically refresh when ready. diff --git a/app/views/projects/edit_tree/show.html.haml b/app/views/projects/edit_tree/show.html.haml index 62798b51d82..5985d1fcc84 100644 --- a/app/views/projects/edit_tree/show.html.haml +++ b/app/views/projects/edit_tree/show.html.haml @@ -8,7 +8,7 @@ = form_tag(project_edit_tree_path(@project, @id), method: :put, class: "form-horizontal") do .file-holder.file .file-title - %i.icon-file + %i.fa.fa-file %span.file_name %span.monospace.light #{@ref}: = @path @@ -20,7 +20,7 @@ .js-edit-mode-pane#preview.hide .center %h2 - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin .form-group.commit_message-group = label_tag 'commit_message', class: "control-label" do diff --git a/app/views/projects/fork.html.haml b/app/views/projects/fork.html.haml index bdd75de447a..d8f5c7b98d6 100644 --- a/app/views/projects/fork.html.haml +++ b/app/views/projects/fork.html.haml @@ -1,6 +1,6 @@ .alert.alert-danger.alert-block %h4 - %i.icon-code-fork + %i.fa.fa-code-fork Fork Error! %p You tried to fork @@ -15,5 +15,5 @@ %p = link_to fork_project_path(@project), title: "Fork", class: "btn", method: "POST" do - %i.icon-code-fork + %i.fa.fa-code-fork Try to Fork again diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index e0a9f62752a..e3d5094ddc5 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -2,7 +2,7 @@ .loading-graph .center %h3.page-title - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Building repository graph. %p.slead Please wait a moment, this page will automatically refresh when ready. diff --git a/app/views/projects/import.html.haml b/app/views/projects/import.html.haml index 2b907748486..1f7fd26c646 100644 --- a/app/views/projects/import.html.haml +++ b/app/views/projects/import.html.haml @@ -2,7 +2,7 @@ .save-project-loader .center %h2 - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Import in progress. %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)} %p Please wait while we import the repository for you. Refresh at will. diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index 82cde14e05d..1d2f3ed8118 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -10,18 +10,18 @@ - if current_controller?(:milestones) %li.pull-right %button.btn.btn-default.sidebar-expand-button - %i.icon.icon-list + %i.icon.fa.fa-list - if current_controller?(:issues) - if current_user %li = link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do - %i.icon-rss + %i.fa.fa-rss %li.pull-right .pull-right %button.btn.btn-default.sidebar-expand-button - %i.icon.icon-list + %i.icon.fa.fa-list = form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do .append-right-10.hidden-xs.hidden-sm = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' } @@ -32,5 +32,5 @@ = hidden_field_tag :label_id, params['label_id'] - if can? current_user, :write_issue, @project = link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do - %i.icon-plus + %i.fa.fa-plus New Issue diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 1dfcd726068..e089b5fa1cf 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -20,11 +20,11 @@ = render 'votes/votes_inline', votable: issue - if issue.notes.any? %span - %i.icon-comments + %i.fa.fa-comments = issue.notes.count - if issue.milestone %span - %i.icon-time + %i.fa.fa-clock-o = issue.milestone.title .pull-right %small updated #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_update_ago')} @@ -41,7 +41,7 @@ - else = link_to 'Close', project_issue_path(issue.project, issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-small btn-grouped close_issue btn-close", remote: true = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml index 1d0dcd7f074..0bff8bdbead 100644 --- a/app/views/projects/issues/_issues.html.haml +++ b/app/views/projects/issues/_issues.html.haml @@ -4,7 +4,7 @@ .issues-filters .dropdown.inline %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.icon-user + %i.fa.fa-user %span.light assignee: - if @assignee.present? %strong= @assignee.name @@ -27,7 +27,7 @@ .dropdown.inline.prepend-left-10 %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.icon-time + %i.fa.fa-clock-o %span.light milestone: - if @milestone.present? %strong= @milestone.title diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index 5de77b8bf32..4ec362b3063 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -1,7 +1,7 @@ = render "head" .row .fixed.fixed.sidebar-expand-button.hidden-lg.hidden-md.hidden-xs - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/project_filter', project_entities_path: project_issues_path(@project), labels: true, redirect: 'issues', entity: 'issue' diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 41532fea741..4c1ea098d98 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -4,7 +4,7 @@ %span.pull-right.issue-btn-group - if can?(current_user, :write_issue, @project) = link_to new_project_issue_path(@project), class: "btn btn-grouped", title: "New Issue", id: "new_issue_link" do - %i.icon-plus + %i.fa.fa-plus New Issue - if can?(current_user, :modify_issue, @issue) - if @issue.closed? @@ -13,7 +13,7 @@ = link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue" = link_to edit_project_issue_path(@project, @issue), class: "btn btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit .clearfix diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 2649fb55c30..647e8873e9e 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -4,7 +4,7 @@ = link_to_gfm truncate(merge_request.title, length: 80), project_merge_request_path(merge_request.target_project, merge_request), class: "row_title" - if merge_request.merged? %small.pull-right - %i.icon-ok + %i.fa.fa-check MERGED - else %span.pull-right @@ -12,7 +12,7 @@ %span.light #{merge_request.source_project_namespace}: = truncate merge_request.source_branch, length: 25 - %i.icon-angle-right.light + %i.fa.fa-angle-right.light = merge_request.target_branch .merge-request-info - if merge_request.author @@ -21,11 +21,11 @@ = render 'votes/votes_inline', votable: merge_request - if merge_request.notes.any? %span - %i.icon-comments + %i.fa.fa-comments = merge_request.mr_and_commit_notes.count - if merge_request.milestone_id? %span - %i.icon-time + %i.fa.fa-clock-o = merge_request.milestone.title diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 9c51c40d32c..d4666eacd7e 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -30,7 +30,7 @@ .form-group .issue-assignee = f.label :assignee_id do - %i.icon-user + %i.fa.fa-user Assign to %div = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id, project_id: @merge_request.target_project_id) @@ -39,12 +39,12 @@ .form-group .issue-milestone = f.label :milestone_id do - %i.icon-time + %i.fa.fa-clock-o Milestone %div= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'}) .form-group = f.label :label_ids do - %i.icon-tag + %i.fa.fa-tag Labels %div = f.collection_select :label_ids, @merge_request.target_project.labels.all, :id, :name, { selected: @merge_request.label_ids }, multiple: true, class: 'select2' diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 4323c8f65a4..947e8f58ae5 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -10,12 +10,12 @@ %ul.nav.nav-pills.merge-request-tabs %li.notes-tab{data: {action: 'notes'}} = link_to project_merge_request_path(@project, @merge_request) do - %i.icon-comment + %i.fa.fa-comment Discussion %span.badge= @merge_request.mr_and_commit_notes.count %li.diffs-tab{data: {action: 'diffs'}} = link_to diffs_project_merge_request_path(@project, @merge_request) do - %i.icon-list-alt + %i.fa.fa-list-alt Changes %span.badge= @merge_request.diffs.size diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 0954fa8fcea..be638d7cac1 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -1,13 +1,13 @@ - if can? current_user, :write_merge_request, @project = link_to new_project_merge_request_path(@project), class: "pull-right btn btn-new", title: "New Merge Request" do - %i.icon-plus + %i.fa.fa-plus New Merge Request %h3.page-title Merge Requests %hr .row .fixed.sidebar-expand-button.hidden-lg.hidden-md - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project), labels: true, redirect: 'merge_requests', entity: 'merge_request' @@ -15,7 +15,7 @@ .mr-filters.append-bottom-10 .dropdown.inline %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.icon-user + %i.fa.fa-user %span.light assignee: - if @assignee.present? %strong= @assignee.name @@ -38,7 +38,7 @@ .dropdown.inline.prepend-left-10 %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.icon-time + %i.fa.fa-clock-o %span.light milestone: - if @milestone.present? %strong= @milestone.title diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml index ede709ea1df..a6587403871 100644 --- a/app/views/projects/merge_requests/show/_commits.html.haml +++ b/app/views/projects/merge_requests/show/_commits.html.haml @@ -1,7 +1,7 @@ - if @commits.present? .panel.panel-default .panel-heading - %i.icon-list + %i.fa.fa-list Commits (#{@commits.count}) .commits.mr-commits - if @commits.count > 8 diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml index 88cc8e17fa6..1ab5028c448 100644 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml @@ -63,7 +63,7 @@ .automerge_widget.unchecked %p %strong - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Checking for ability to automatically merge… .automerge_widget.already_cannot_be_merged.hide @@ -72,6 +72,6 @@ .merge-in-progress.hide %p - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin   Merge is in progress. Please wait. Page will be automatically reloaded.   diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml index b77eeac6123..dc64c096edc 100644 --- a/app/views/projects/merge_requests/show/_mr_ci.html.haml +++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml @@ -1,29 +1,29 @@ - if @commits.any? .ci_widget.ci-success{style: "display:none"} - %i.icon-ok + %i.fa.fa-check %span CI build passed for #{@merge_request.last_commit_short_sha}. = link_to "Build page", ci_build_details_path(@merge_request) .ci_widget.ci-failed{style: "display:none"} - %i.icon-remove + %i.fa.fa-times %span CI build failed for #{@merge_request.last_commit_short_sha}. = link_to "Build page", ci_build_details_path(@merge_request) - [:running, :pending].each do |status| .ci_widget{class: "ci-#{status}", style: "display:none"} - %i.icon-time + %i.fa.fa-clock-o %span CI build #{status} for #{@merge_request.last_commit_short_sha}. = link_to "Build page", ci_build_details_path(@merge_request) .ci_widget %strong - %i.icon-spinner + %i.fa.fa-spinner Checking for CI status for #{@merge_request.last_commit_short_sha} .ci_widget.ci-error{style: "display:none"} - %i.icon-remove + %i.fa.fa-times %span Cannot connect to the CI server. Please check your settings and try again. diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index 1c319b83e2b..276c980966a 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -6,7 +6,7 @@ - if @merge_request.open? .btn-group.pull-left %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt Download as %span.caret %ul.dropdown-menu @@ -16,7 +16,7 @@ = link_to 'Close', project_merge_request_path(@project, @merge_request, merge_request: { state_event: :close }), method: :put, class: "btn btn-grouped btn-close", title: "Close merge request" = link_to edit_project_merge_request_path(@project, @merge_request), class: "btn btn-grouped", id:"edit_merge_request" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit - if @merge_request.closed? = link_to 'Reopen', project_merge_request_path(@project, @merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link", title: "Close merge request" 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 index 491360af1bb..4fe5935bcf3 100644 --- a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml +++ b/app/views/projects/merge_requests/show/_remove_source_branch.html.haml @@ -5,13 +5,13 @@ .remove_source_branch_widget %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now = link_to project_branch_path(@merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-small remove_source_branch" do - %i.icon-remove + %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.icon-refresh.icon-spin + %i.fa.fa-refresh.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 index a5f8af89d1a..5db77ab2754 100644 --- a/app/views/projects/merge_requests/show/_state_widget.html.haml +++ b/app/views/projects/merge_requests/show/_state_widget.html.haml @@ -34,7 +34,7 @@ - if !@closes_issues.empty? && @merge_request.open? .panel-footer %span - %i.icon-ok + %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/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index 4018d132a55..1002b9513ff 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -2,7 +2,7 @@ .pull-right - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit = link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-small btn-close" %h4 diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index f0e48a51777..03367b7cdbf 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -4,12 +4,12 @@ Milestones - if can? current_user, :admin_milestone, @project = link_to new_project_milestone_path(@project), class: "pull-right btn btn-new", title: "New Milestone" do - %i.icon-plus + %i.fa.fa-plus New Milestone .row .fixed.sidebar-expand-button.hidden-lg.hidden-md.hidden-xs - %i.icon-list.icon-2x + %i.fa.fa-list.fa-2x .col-md-3.responsive-side %ul.nav.nav-pills.nav-stacked %li{class: ("active" if (params[:f] == "active" || !params[:f]))} diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 1a495aa1c40..8263f7530a2 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -4,7 +4,7 @@ .pull-right - if can?(current_user, :admin_milestone, @project) = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit - if @milestone.active? = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-grouped" @@ -70,7 +70,7 @@ .pull-right = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small btn-grouped", title: "New Issue" do - %i.icon-plus + %i.fa.fa-plus New Issue = link_to 'Browse Issues', project_issues_path(@milestone.project, milestone_id: @milestone.id), class: "btn btn-small edit-milestone-link btn-grouped" diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index 52a66f64d9f..4a21b84fb85 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -4,7 +4,7 @@ = form_tag project_network_path(@project, @id), method: :get, class: 'form-inline network-form' do |f| = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Input an extended SHA1 syntax", class: 'search-input form-control input-mx-250 search-sha' = button_tag class: 'btn btn-success btn-search-sha' do - %i.icon-search + %i.fa.fa-search .inline.prepend-left-20 .checkbox.light = label_tag :filter_ref do diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 949b72356d7..6c986050c45 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -23,7 +23,7 @@ .col-sm-2 .col-sm-10 = link_to "#", class: 'js-toggle-button' do - %i.icon-edit + %i.fa.fa-pencil-square-o %span Customize repository name? .js-toggle-content.hide .form-group @@ -39,7 +39,7 @@ .col-sm-2 .col-sm-10 = link_to "#", class: 'js-toggle-button' do - %i.icon-upload-alt + %i.fa.fa-upload %span Import existing repository? .js-toggle-content.hide .form-group.import-url-data @@ -74,6 +74,6 @@ .save-project-loader.hide .center %h2 - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Creating project & repository. %p Please wait a moment, this page will automatically refresh when ready. diff --git a/app/views/projects/new_tree/show.html.haml b/app/views/projects/new_tree/show.html.haml index 24d77344fd5..bb317e4f137 100644 --- a/app/views/projects/new_tree/show.html.haml +++ b/app/views/projects/new_tree/show.html.haml @@ -30,7 +30,7 @@ .file-holder .file-title - %i.icon-file + %i.fa.fa-file .file-content.code %pre#editor= params[:content] diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml index a01056b7166..c731baf0a65 100644 --- a/app/views/projects/notes/_diff_notes_with_reply.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml @@ -4,7 +4,7 @@ %tr.notes_holder %td.notes_line{ colspan: 2 } %span.discussion-notes-count - %i.icon-comment + %i.fa.fa-comment = notes.count %td.notes_content %ul.notes{ rel: note.discussion_id } diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml index 506d1fff008..789f3e19fd2 100644 --- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml +++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml @@ -5,7 +5,7 @@ - if note1 %td.notes_line %span.btn.disabled - %i.icon-comment + %i.fa.fa-comment = notes1.count %td.notes_content.parallel %ul.notes{ rel: note1.discussion_id } @@ -20,7 +20,7 @@ - if note2 %td.notes_line %span.btn.disabled - %i.icon-comment + %i.fa.fa-comment = notes2.count %td.notes_content.parallel %ul.notes{ rel: note2.discussion_id } diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index 52d6719a2ed..c68b3817e79 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -31,7 +31,7 @@ .note-form-option %a.choose-btn.btn.js-choose-note-attachment-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-attachment-filename File name... diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 394fa88e045..814bf19970c 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -6,16 +6,16 @@ .note-header .note-actions = link_to "##{dom_id(note)}", name: dom_id(note) do - %i.icon-link + %i.fa.fa-link Link here   - if can?(current_user, :admin_note, note) && note.editable? = link_to "#", title: "Edit comment", class: "js-note-edit" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit   = link_to project_note_path(@project, note), title: "Remove comment", method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: "danger js-note-delete" do - %i.icon-trash.cred + %i.fa.fa-trash-o.cred Remove = link_to_member(@project, note.author, avatar: false) %span.note-last-update @@ -23,11 +23,11 @@ - if note.upvote? %span.vote.upvote.label.label-success - %i.icon-thumbs-up + %i.fa.fa-thumbs-up \+1 - if note.downvote? %span.vote.downvote.label.label-danger - %i.icon-thumbs-down + %i.fa.fa-thumbs-down \-1 @@ -45,7 +45,7 @@ .note-form-option %a.choose-btn.btn.js-choose-note-attachment-button - %i.icon-paper-clip + %i.fa.fa-paperclip %span Choose File ...   %span.file_name.js-attachment-filename File name... @@ -61,9 +61,9 @@ = image_tag note.attachment.secure_url, class: 'note-image-attach' .attachment.pull-right = link_to note.attachment.secure_url, target: "_blank" do - %i.icon-paper-clip + %i.fa.fa-paperclip = note.attachment_identifier = link_to delete_attachment_project_note_path(@project, note), title: "Delete this attachment", method: :delete, remote: true, data: { confirm: 'Are you sure you want to remove the attachment?' }, class: "danger js-note-attachment-delete" do - %i.icon-trash.cred + %i.fa.fa-trash-o.cred .clear diff --git a/app/views/projects/notes/discussions/_active.html.haml b/app/views/projects/notes/discussions/_active.html.haml index eb416c5b5f0..52c06ec172d 100644 --- a/app/views/projects/notes/discussions/_active.html.haml +++ b/app/views/projects/notes/discussions/_active.html.haml @@ -3,7 +3,7 @@ .discussion-header .discussion-actions = link_to "#", class: "js-toggle-button" do - %i.icon-chevron-up + %i.fa.fa-chevron-up Show/hide discussion %div = link_to_member(@project, note.author, avatar: false) diff --git a/app/views/projects/notes/discussions/_commit.html.haml b/app/views/projects/notes/discussions/_commit.html.haml index a928029a5e5..94f16a5f02e 100644 --- a/app/views/projects/notes/discussions/_commit.html.haml +++ b/app/views/projects/notes/discussions/_commit.html.haml @@ -3,7 +3,7 @@ .discussion-header .discussion-actions = link_to "#", class: "js-toggle-button" do - %i.icon-chevron-up + %i.fa.fa-chevron-up Show/hide discussion %div = link_to_member(@project, note.author, avatar: false) diff --git a/app/views/projects/notes/discussions/_outdated.html.haml b/app/views/projects/notes/discussions/_outdated.html.haml index 4ae914c107b..52a1d342f55 100644 --- a/app/views/projects/notes/discussions/_outdated.html.haml +++ b/app/views/projects/notes/discussions/_outdated.html.haml @@ -3,7 +3,7 @@ .discussion-header .discussion-actions = link_to "#", class: "js-toggle-button" do - %i.icon-chevron-down + %i.fa.fa-chevron-down Show/hide discussion %div = link_to_member(@project, note.author, avatar: false) diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml index 3980a6c0863..49a3ef4c8a7 100644 --- a/app/views/projects/protected_branches/index.html.haml +++ b/app/views/projects/protected_branches/index.html.haml @@ -35,7 +35,7 @@ - if @project.root_ref?(branch.name) %span.label.label-info default %span.label.label-success - %i.icon-lock + %i.fa.fa-lock .pull-right - if can? current_user, :admin_project, @project = link_to 'Unprotect', [@project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-small" diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml index ed6f8ddd187..3b4f1a4298d 100644 --- a/app/views/projects/repositories/_download_archive.html.haml +++ b/app/views/projects/repositories/_download_archive.html.haml @@ -4,7 +4,7 @@ - if split_button == true %span.btn-group{class: btn_class} = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn', rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span Download zip %a.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' } %span.caret @@ -13,25 +13,25 @@ %ul.dropdown-menu{ role: 'menu' } %li = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span Download zip %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span Download tar.gz %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.bz2'), rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span Download tar.bz2 %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar'), rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span Download tar - else %span.btn-group{class: btn_class} = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn', rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span zip = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz'), class: 'btn', rel: 'nofollow' do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt %span tar.gz diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 19bef02b51f..09664ed51eb 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -29,13 +29,13 @@ - if @project.archived? .alert.alert-warning %h4 - %i.icon-warning-sign + %i.fa.fa-exclamation-triangle Archived project! %p Repository is read-only - if @project.forked_from_project .alert.alert-success - %i.icon-code-fork.project-fork-icon + %i.fa.fa-code-fork.project-fork-icon Forked from: %br = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) @@ -73,7 +73,7 @@ %article.readme-holder#README = link_to project_blob_path(@project, tree_join(@repository.root_ref, readme.name)) do %h4.readme-file-title - %i.icon-file + %i.fa.fa-file = readme.name .wiki = render_readme(readme) diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index e4fdbd868c3..ada0d30c496 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -22,7 +22,7 @@ .file-holder .file-title - %i.icon-file + %i.fa.fa-file %span.file_name = @snippet.file_name .options diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml index 9ed737b181f..bce105a033b 100644 --- a/app/views/projects/tags/_tag.html.haml +++ b/app/views/projects/tags/_tag.html.haml @@ -2,14 +2,14 @@ %li %h4 = link_to project_commits_path(@project, tag.name), class: "" do - %i.icon-tag + %i.fa.fa-tag = tag.name .pull-right - if can? current_user, :download_code, @project = render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'btn-grouped btn-group-small' - if can?(current_user, :admin_project, @project) = link_to project_tag_path(@project, tag.name), class: 'btn btn-small btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do - %i.icon-trash + %i.fa.fa-trash-o - if commit %ul.list-unstyled diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index 6cbf99239ee..ac74e3b6d36 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -5,7 +5,7 @@ - if can? current_user, :push_code, @project .pull-right = link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do - %i.icon-add-sign + %i.fa.fa-add-sign New tag %p.light diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index 45ee61caf68..aa08b397763 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -3,7 +3,7 @@ %button{ type: "button", class: "close", "data-dismiss" => "alert"} × = @error %h3.page-title - %i.icon-code-fork + %i.fa.fa-code-fork New tag = form_tag project_tags_path, method: :post, class: "form-horizontal" do .form-group diff --git a/app/views/projects/team_members/_group_members.html.haml b/app/views/projects/team_members/_group_members.html.haml index 77ffab89f37..df3c914fdea 100644 --- a/app/views/projects/team_members/_group_members.html.haml +++ b/app/views/projects/team_members/_group_members.html.haml @@ -5,7 +5,7 @@ group members (#{group_users_count}) .pull-right = link_to members_group_path(@group), class: 'btn btn-small' do - %i.icon-edit + %i.fa.fa-pencil-square-o %ul.well-list - @group.group_members.order('access_level DESC').limit(20).each do |member| = render 'groups/group_members/group_member', member: member, show_controls: false diff --git a/app/views/projects/team_members/_team_member.html.haml b/app/views/projects/team_members/_team_member.html.haml index 79b78665417..5f29b58de32 100644 --- a/app/views/projects/team_members/_team_member.html.haml +++ b/app/views/projects/team_members/_team_member.html.haml @@ -8,7 +8,7 @@ = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: "medium project-access-select span2 trigger-submit"   = link_to project_team_member_path(@project, user), data: { confirm: remove_from_project_team_message(@project, user)}, method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do - %i.icon-minus.icon-white + %i.fa.fa-minus.fa-inverse = image_tag avatar_icon(user.email, 32), class: "avatar s32" %p %strong= user.name diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml index ec2701af0eb..f082d711865 100644 --- a/app/views/projects/tree/_readme.html.haml +++ b/app/views/projects/tree/_readme.html.haml @@ -1,7 +1,7 @@ %article.readme-holder#README = link_to '#README' do %h4.readme-file-title - %i.icon-file + %i.fa.fa-file = readme.name .wiki = render_readme(readme) diff --git a/app/views/projects/tree/_spinner.html.haml b/app/views/projects/tree/_spinner.html.haml index 5a9e77b63df..b47ad0f41e4 100644 --- a/app/views/projects/tree/_spinner.html.haml +++ b/app/views/projects/tree/_spinner.html.haml @@ -1,3 +1,3 @@ %span.log_loading.hide - %i.icon-spinner.icon-spin + %i.fa.fa-spinner.fa-spin Loading commit data... diff --git a/app/views/projects/tree/_submodule_item.html.haml b/app/views/projects/tree/_submodule_item.html.haml index 474604df654..a8ec9df2c8f 100644 --- a/app/views/projects/tree/_submodule_item.html.haml +++ b/app/views/projects/tree/_submodule_item.html.haml @@ -1,7 +1,7 @@ - tree, commit = submodule_links(submodule_item) %tr{ class: "tree-item" } %td.tree-item-file-name - %i.icon-archive + %i.fa.fa-archive %span = link_to truncate(submodule_item.name, length: 40), tree @ diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml index 9fe990d0fbd..1159fcadffd 100644 --- a/app/views/projects/tree/_tree.html.haml +++ b/app/views/projects/tree/_tree.html.haml @@ -12,7 +12,7 @@ %li = link_to project_new_tree_path(@project, @id), title: 'New file', id: 'new-file-link' do %small - %i.icon-plus + %i.fa.fa-plus %div#tree-content-holder.tree-content-holder %table#tree-slider{class: "table_#{@hex_path} tree-table" } @@ -24,7 +24,7 @@ .pull-left Last Commit .last-commit.hidden-sm.pull-left   - %i.icon-angle-right + %i.fa.fa-angle-right   %small.light = link_to @commit.short_id, project_commit_path(@project, @commit) diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 68d70873231..30410bc95e0 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -4,5 +4,5 @@ Page History - if can?(current_user, :write_wiki, @project) = link_to edit_project_wiki_path(@project, @page), class: "btn btn-grouped" do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index 0a7e51e974c..a2010f3794f 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -7,13 +7,13 @@ = nav_link(path: 'wikis#git_access') do = link_to git_access_project_wikis_path(@project) do - %i.icon-download-alt + %i.fa.fa-arrow-circle-o-down-alt Git Access - if can?(current_user, :write_wiki, @project) .pull-right = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - %i.icon-plus + %i.fa.fa-plus New Page = render 'projects/wikis/new' diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml index 049aff0bc9b..eca69ce50b1 100644 --- a/app/views/search/_filter.html.haml +++ b/app/views/search/_filter.html.haml @@ -1,6 +1,6 @@ .dropdown.inline %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} - %i.icon-tags + %i.fa.fa-tags %span.light Group: - if @group.present? %strong= @group.name @@ -18,7 +18,7 @@ .dropdown.inline.prepend-left-10.project-filter %a.dropdown-toggle.btn.btn-small{href: '#', "data-toggle" => "dropdown"} - %i.icon-tags + %i.fa.fa-tags %span.light Project: - if @project.present? %strong= @project.name_with_namespace diff --git a/app/views/search/_project_filter.html.haml b/app/views/search/_project_filter.html.haml index 57a45c9acb6..c201b3d6c47 100644 --- a/app/views/search/_project_filter.html.haml +++ b/app/views/search/_project_filter.html.haml @@ -1,25 +1,25 @@ %ul.nav.nav-pills.nav-stacked.search-filter %li{class: ("active" if @scope == 'blobs')} = link_to search_filter_path(scope: 'blobs') do - %i.icon-code + %i.fa.fa-code Code .pull-right = @search_results.blobs_count %li{class: ("active" if @scope == 'issues')} = link_to search_filter_path(scope: 'issues') do - %i.icon-exclamation-sign + %i.fa.fa-exclamation-circle Issues .pull-right = @search_results.issues_count %li{class: ("active" if @scope == 'merge_requests')} = link_to search_filter_path(scope: 'merge_requests') do - %i.icon-code-fork + %i.fa.fa-code-fork Merge requests .pull-right = @search_results.merge_requests_count %li{class: ("active" if @scope == 'notes')} = link_to search_filter_path(scope: 'notes') do - %i.icon-comments + %i.fa.fa-comments Comments .pull-right = @search_results.notes_count diff --git a/app/views/search/_snippet_filter.html.haml b/app/views/search/_snippet_filter.html.haml index 0d1984a0d78..95d23fa9f47 100644 --- a/app/views/search/_snippet_filter.html.haml +++ b/app/views/search/_snippet_filter.html.haml @@ -1,13 +1,13 @@ %ul.nav.nav-pills.nav-stacked.search-filter %li{class: ("active" if @scope == 'snippet_blobs')} = link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do - %i.icon-code + %i.fa.fa-code Snippet Contents .pull-right = @search_results.snippet_blobs_count %li{class: ("active" if @scope == 'snippet_titles')} = link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do - %i.icon-book + %i.fa.fa-book Titles and Filenames .pull-right = @search_results.snippet_titles_count diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml index f9d217e8408..b46b4832e19 100644 --- a/app/views/search/results/_blob.html.haml +++ b/app/views/search/results/_blob.html.haml @@ -2,7 +2,7 @@ .file-holder .file-title = link_to project_blob_path(@project, tree_join(blob.ref, blob.filename), :anchor => "L" + blob.startline.to_s) do - %i.icon-file + %i.fa.fa-file %strong = blob.filename .file-content.code.term diff --git a/app/views/search/results/_empty.html.haml b/app/views/search/results/_empty.html.haml index 3615f6ae52a..01fb8cd9b8e 100644 --- a/app/views/search/results/_empty.html.haml +++ b/app/views/search/results/_empty.html.haml @@ -1,4 +1,4 @@ .search_box .search_glyph - %span.icon-search + %span.fa.fa-search %h4 #{message} diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml index 6a446538574..f2327cd69cc 100644 --- a/app/views/search/results/_note.html.haml +++ b/app/views/search/results/_note.html.haml @@ -1,7 +1,7 @@ - project = note.project .search-result-row %h5.note-search-caption.str-truncated - %i.icon-comment + %i.fa.fa-comment = link_to_member(project, note.author, avatar: false) commented on diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml index a3d909d44dc..6fc2cdf6362 100644 --- a/app/views/search/results/_snippet_blob.html.haml +++ b/app/views/search/results/_snippet_blob.html.haml @@ -11,7 +11,7 @@ = link_to snippet_path do .file-holder .file-title - %i.icon-file + %i.fa.fa-file %strong= snippet_blob[:snippet_object].file_name %span.options .btn-group.tree-btn-group.pull-right @@ -46,7 +46,7 @@ - offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1 - i = index + offset = link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do - %i.icon-link + %i.fa.fa-link = i - unless snippet == snippet_blob[:snippet_chunks].last %a diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml index 84abb9293b2..f7e5ee5e20e 100644 --- a/app/views/search/results/_snippet_title.html.haml +++ b/app/views/search/results/_snippet_title.html.haml @@ -4,7 +4,7 @@ = truncate(snippet_title.title, length: 60) - if snippet_title.private? %span.label.label-gray - %i.icon-lock + %i.fa.fa-lock private %span.cgray.monospace.tiny.pull-right.term = snippet_title.file_name diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index 75414d73b0c..e361074b6a0 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -2,7 +2,7 @@ .file-holder .file-title = link_to project_wiki_path(@project, wiki_blob.filename) do - %i.icon-file + %i.fa.fa-file %strong = wiki_blob.filename .file-content.code.term diff --git a/app/views/shared/_file_hljs.html.haml b/app/views/shared/_file_hljs.html.haml index cbc01bd60e0..444c948b026 100644 --- a/app/views/shared/_file_hljs.html.haml +++ b/app/views/shared/_file_hljs.html.haml @@ -5,7 +5,7 @@ - offset = defined?(first_line_number) ? first_line_number : 1 - i = index + offset = link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do - %i.icon-link + %i.fa.fa-link = i .highlight %pre diff --git a/app/views/shared/_filter.html.haml b/app/views/shared/_filter.html.haml index 9e65ce11ade..d366dd97a71 100644 --- a/app/views/shared/_filter.html.haml +++ b/app/views/shared/_filter.html.haml @@ -45,6 +45,6 @@ %fieldset - if params[:state].present? || params[:project_id].present? = link_to filter_path(entity, state: nil, project_id: nil), class: 'pull-right cgray' do - %i.icon-remove + %i.fa.fa-times %strong Clear filter diff --git a/app/views/shared/_project_filter.html.haml b/app/views/shared/_project_filter.html.haml index 5e7d1c2c885..ea6a49e1501 100644 --- a/app/views/shared/_project_filter.html.haml +++ b/app/views/shared/_project_filter.html.haml @@ -38,7 +38,7 @@ Labels %small.pull-right = link_to project_labels_path(@project), class: 'light' do - %i.icon-edit + %i.fa.fa-pencil-square-o %ul.nav.nav-pills.nav-stacked.nav-small.labels-filter - @project.labels.order_by_name.each do |label| %li{class: label_filter_class(label.name)} @@ -46,7 +46,7 @@ = render_colored_label(label) - if selected_label?(label.name) .pull-right - %i.icon-remove + %i.fa.fa-times - if @project.labels.empty? .light-well @@ -58,7 +58,7 @@ %fieldset - if %w(state scope milestone_id assignee_id label_name).select { |k| params[k].present? }.any? = link_to project_entities_path, class: 'cgray pull-right' do - %i.icon-remove + %i.fa.fa-times %strong Clear filter diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml index e6f83167330..c584dd8dfb6 100644 --- a/app/views/snippets/_snippet.html.haml +++ b/app/views/snippets/_snippet.html.haml @@ -4,7 +4,7 @@ = truncate(snippet.title, length: 60) - if snippet.private? %span.label.label-gray - %i.icon-lock + %i.fa.fa-lock private %span.cgray.monospace.tiny.pull-right = snippet.file_name diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 1d2e3d5ae4a..f5bc543de10 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -3,7 +3,7 @@ - if @snippet.private? %span.label.label-success - %i.icon-lock + %i.fa.fa-lock private .pull-right @@ -30,7 +30,7 @@ .file-holder .file-title - %i.icon-file + %i.fa.fa-file %span.file_name = @snippet.file_name .options diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 60159a29b99..cb49c030af2 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -6,7 +6,7 @@ - if @user == current_user .pull-right = link_to profile_path, class: 'btn' do - %i.icon-edit + %i.fa.fa-pencil-square-o Edit Profile settings %br %span.user-show-username #{@user.username} diff --git a/features/steps/profile/group.rb b/features/steps/profile/group.rb index 81d5bc15e21..0a10e04e219 100644 --- a/features/steps/profile/group.rb +++ b/features/steps/profile/group.rb @@ -7,22 +7,22 @@ class Spinach::Features::ProfileGroup < Spinach::FeatureSteps # Leave step 'I click on the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").find(:css, 'i.icon-signout').click + find(:css, 'li', text: "Owner").find(:css, 'i.fa.fa-sign-out').click # poltergeist always confirms popups. end step 'I click on the "Leave" button for group "Guest"' do - find(:css, 'li', text: "Guest").find(:css, 'i.icon-signout').click + find(:css, 'li', text: "Guest").find(:css, 'i.fa.fa-sign-out').click # poltergeist always confirms popups. end step 'I should not see the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").should_not have_selector(:css, 'i.icon-signout') + find(:css, 'li', text: "Owner").should_not 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.icon-signout') + find(:css, 'li', text: "Guest").should_not have_selector(:css, 'i.fa.fa-sign-out') # poltergeist always confirms popups. end diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 3ecabbaf045..31ecdacf28e 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -8,7 +8,7 @@ describe NotificationsHelper do before { notification.stub(disabled?: true) } it "has a red icon" do - notification_icon(notification).should match('class="icon-volume-off ns-mute"') + notification_icon(notification).should match('class="fa fa-volume-off ns-mute"') end end @@ -16,7 +16,7 @@ describe NotificationsHelper do before { notification.stub(participating?: true) } it "has a blue icon" do - notification_icon(notification).should match('class="icon-volume-down ns-part"') + notification_icon(notification).should match('class="fa fa-volume-down ns-part"') end end @@ -24,12 +24,12 @@ describe NotificationsHelper do before { notification.stub(watch?: true) } it "has a green icon" do - notification_icon(notification).should match('class="icon-volume-up ns-watch"') + notification_icon(notification).should match('class="fa fa-volume-up ns-watch"') end end it "has a blue icon" do - notification_icon(notification).should match('class="icon-circle-blank ns-default"') + notification_icon(notification).should match('class="fa fa-circle-o ns-default"') end end end diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index cd8a076318c..791d2a1fd64 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -21,6 +21,6 @@ module LoginHelpers # Requires Javascript driver. def logout - find(:css, ".icon-signout").click + find(:css, ".fa.fa-sign-out").click end end -- cgit v1.2.1 From 3960a5a25aa857959544d274097b4f0e38777468 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Fri, 3 Oct 2014 12:19:31 +0200 Subject: Remove assignment without effect. --- features/steps/shared/paths.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index babbef33ec4..141ff13b67d 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -411,7 +411,7 @@ module SharedPaths end def project - project = Project.find_by!(name: "Shop") + Project.find_by!(name: 'Shop') end # ---------------------------------------- -- cgit v1.2.1 From 6014e28c2df977643ed4d1c5480158db0e9a09eb Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Fri, 3 Oct 2014 12:21:23 +0200 Subject: Remove outdated comment on the project test seed --- spec/factories/projects.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 5324654c48c..23314b3b1a4 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -47,16 +47,6 @@ FactoryGirl.define do end end - # Generates a test repository from the repository stored under `spec/seed_project.tar.gz`. - # Once you run `rake gitlab:setup`, you can see what the repository looks like under `tmp/repositories/gitlabhq`. - # In order to modify files in the repository, you must untar the seed, modify and remake the tar. - # Before recompressing, do not forget to `git checkout master`. - # After recompressing, you need to run `RAILS_ENV=test bundle exec rake gitlab:setup` to regenerate the seeds under tmp. - # - # If you want to modify the repository only for an specific type of tests, e.g., markdown tests, - # consider using a feature branch to reduce the chances of collision with other tests. - # Create a new commit, and use the same commit message that you will use for the change in the main repo. - # Changing the commig message and SHA of branch `master` may break tests. factory :project, parent: :empty_project do path { 'gitlabhq' } -- cgit v1.2.1 From d1fa3b336d1d3e3c1f9a10ca007e3d1193e5e205 Mon Sep 17 00:00:00 2001 From: Sullivan SENECHAL Date: Wed, 1 Oct 2014 02:48:41 +0200 Subject: Add Pushover service integration That introduce select field type for services options. --- CHANGELOG | 2 + app/controllers/projects/services_controller.rb | 3 +- app/models/project.rb | 3 +- app/models/project_services/pushover_service.rb | 113 ++++++++++++++++++++++++ app/views/projects/services/_form.html.haml | 5 ++ features/project/service.feature | 6 ++ features/steps/project/services.rb | 23 +++++ spec/models/project_spec.rb | 1 + spec/models/pushover_service_spec.rb | 69 +++++++++++++++ 9 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 app/models/project_services/pushover_service.rb create mode 100644 spec/models/pushover_service_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 86f544091c8..14d2572f742 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,8 @@ v 7.4.0 - Zen mode for wiki and milestones (Robert Schilling) - Move Emoji parsing to html-pipeline-gitlab (Robert Schilling) - Font Awesome 4.2 integration (Sullivan Senechal) + - Add Pushover service integration (Sullivan Senechal) + - Add select field type for services options (Sullivan Senechal) v 7.3.2 - Fix creating new file via web editor diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index b143dec3a93..4c558e137ea 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -40,7 +40,8 @@ class Projects::ServicesController < Projects::ApplicationController def service_params params.require(:service).permit( :title, :token, :type, :active, :api_key, :subdomain, - :room, :recipients, :project_url + :room, :recipients, :project_url, + :user_key, :device, :priority, :sound ) end end diff --git a/app/models/project.rb b/app/models/project.rb index d228da192e4..44d63d37bee 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -64,6 +64,7 @@ class Project < ActiveRecord::Base has_one :assembla_service, dependent: :destroy has_one :gemnasium_service, dependent: :destroy has_one :slack_service, dependent: :destroy + has_one :pushover_service, dependent: :destroy has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link # Merge Requests for target project should be removed with it @@ -311,7 +312,7 @@ class Project < ActiveRecord::Base end def available_services_names - %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack) + %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover) end def gitlab_ci? diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb new file mode 100644 index 00000000000..f247fde7762 --- /dev/null +++ b/app/models/project_services/pushover_service.rb @@ -0,0 +1,113 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# active :boolean default(FALSE), not null +# properties :text +# + +class PushoverService < Service + include HTTParty + base_uri 'https://api.pushover.net/1' + + prop_accessor :api_key, :user_key, :device, :priority, :sound + validates :api_key, :user_key, :priority, presence: true, if: :activated? + + def title + 'Pushover' + end + + def description + 'Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.' + end + + def to_param + 'pushover' + end + + def fields + [ + { type: 'text', name: 'api_key', placeholder: 'Your application key' }, + { type: 'text', name: 'user_key', placeholder: 'Your user key' }, + { type: 'text', name: 'device', placeholder: 'Leave blank for all active devices' }, + { type: 'select', name: 'priority', choices: + [ + ['Lowest Priority', -2], + ['Low Priority', -1], + ['Normal Priority', 0], + ['High Priority', 1] + ], + default_choice: 0 + }, + { type: 'select', name: 'sound', choices: + [ + ['Device default sound', nil], + ['Pushover (default)', 'pushover'], + ['Bike', 'bike'], + ['Bugle', 'bugle'], + ['Cash Register', 'cashregister'], + ['Classical', 'classical'], + ['Cosmic', 'cosmic'], + ['Falling', 'falling'], + ['Gamelan', 'gamelan'], + ['Incoming', 'incoming'], + ['Intermission', 'intermission'], + ['Magic', 'magic'], + ['Mechanical', 'mechanical'], + ['Piano Bar', 'pianobar'], + ['Siren', 'siren'], + ['Space Alarm', 'spacealarm'], + ['Tug Boat', 'tugboat'], + ['Alien Alarm (long)', 'alien'], + ['Climb (long)', 'climb'], + ['Persistent (long)', 'persistent'], + ['Pushover Echo (long)', 'echo'], + ['Up Down (long)', 'updown'], + ['None (silent)', 'none'] + ] + }, + ] + end + + def execute(push_data) + ref = push_data[:ref].gsub('refs/heads/', '') + before = push_data[:before] + after = push_data[:after] + + if before =~ /000000/ + message = "#{push_data[:user_name]} pushed new branch \"#{ref}\"." + elsif after =~ /000000/ + message = "#{push_data[:user_name]} deleted branch \"#{ref}\"." + else + message = "#{push_data[:user_name]} push to branch \"#{ref}\"." + end + + if push_data[:total_commits_count] > 0 + message << "\nTotal commits count: #{push_data[:total_commits_count]}" + end + + pushover_data = { + token: api_key, + user: user_key, + device: device, + priority: priority, + title: "#{project.name_with_namespace}", + message: message, + url: push_data[:repository][:homepage], + url_title: "See project #{project.name_with_namespace}" + } + + # Sound parameter MUST NOT be sent to API if not selected + if sound + pushover_data.merge!(sound: sound) + end + + PushoverService.post('/messages.json', body: pushover_data) + end +end diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index a5db7969a68..16d59d1fe9d 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -28,8 +28,11 @@ - @service.fields.each do |field| - name = field[:name] + - value = @service.send(name) - type = field[:type] - placeholder = field[:placeholder] + - choices = field[:choices] + - default_choice = field[:default_choice] .form-group = f.label name, class: "control-label" @@ -40,6 +43,8 @@ = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder - elsif type == 'checkbox' = f.check_box name + - elsif type == 'select' + = f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } .form-actions = f.submit 'Save', class: 'btn btn-save' diff --git a/features/project/service.feature b/features/project/service.feature index a5af065c9e7..af88eaefa8f 100644 --- a/features/project/service.feature +++ b/features/project/service.feature @@ -43,6 +43,12 @@ Feature: Project Services And I fill Slack settings Then I should see Slack service settings saved + Scenario: Activate Pushover service + When I visit project "Shop" services page + And I click Pushover service link + And I fill Pushover settings + Then I should see Pushover service settings saved + Scenario: Activate email on push service When I visit project "Shop" services page And I click email on push service link diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb index b56b413eac8..d816fcafbaa 100644 --- a/features/steps/project/services.rb +++ b/features/steps/project/services.rb @@ -13,6 +13,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps page.should have_content 'Hipchat' page.should have_content 'GitLab CI' page.should have_content 'Assembla' + page.should have_content 'Pushover' end step 'I click gitlab-ci service link' do @@ -118,4 +119,26 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps find_field('Room').value.should == '#gitlab' find_field('Token').value.should == 'verySecret' end + + step 'I click Pushover service link' do + click_link 'Pushover' + end + + step 'I fill Pushover settings' do + check 'Active' + fill_in 'Api key', with: 'verySecret' + fill_in 'User key', with: 'verySecret' + fill_in 'Device', with: 'myDevice' + select 'High Priority', from: 'Priority' + select 'Bike', from: 'Sound' + click_button 'Save' + 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' + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 524cab2b925..48b58400a1e 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -47,6 +47,7 @@ describe Project do it { should have_many(:protected_branches).dependent(:destroy) } it { should have_one(:forked_project_link).dependent(:destroy) } it { should have_one(:slack_service).dependent(:destroy) } + it { should have_one(:pushover_service).dependent(:destroy) } end describe "Mass assignment" do diff --git a/spec/models/pushover_service_spec.rb b/spec/models/pushover_service_spec.rb new file mode 100644 index 00000000000..59db69d7572 --- /dev/null +++ b/spec/models/pushover_service_spec.rb @@ -0,0 +1,69 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# active :boolean default(FALSE), not null +# properties :text +# + +require 'spec_helper' + +describe PushoverService do + describe 'Associations' do + it { should belong_to :project } + it { should have_one :service_hook } + end + + describe 'Validations' do + context 'active' do + before do + subject.active = true + end + + it { should validate_presence_of :api_key } + it { should validate_presence_of :user_key } + it { should validate_presence_of :priority } + end + end + + describe 'Execute' do + let(:pushover) { PushoverService.new } + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:sample_data) { GitPushService.new.sample_data(project, user) } + + let(:api_key) { 'verySecret' } + let(:user_key) { 'verySecret' } + let(:device) { 'myDevice' } + let(:priority) { 0 } + let(:sound) { 'bike' } + let(:api_url) { 'https://api.pushover.net/1/messages.json' } + + before do + pushover.stub( + project: project, + project_id: project.id, + service_hook: true, + api_key: api_key, + user_key: user_key, + device: device, + priority: priority, + sound: sound + ) + + WebMock.stub_request(:post, api_url) + end + + it 'should call Pushover API' do + pushover.execute(sample_data) + + WebMock.should have_requested(:post, api_url).once + end + end +end -- cgit v1.2.1 From 1b1ba6b0a51cda30df2fe68fa577f6045d187b86 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Wed, 1 Oct 2014 10:31:13 -0500 Subject: Implement cross-project Markdown references Enable linking to commits, merge requests, and issues in other projects by prepending a namespaced project path to the reference. --- CHANGELOG | 1 + doc/markdown/markdown.md | 6 ++ lib/gitlab/markdown.rb | 90 ++++++++++++++++--------- spec/helpers/gitlab_markdown_helper_spec.rb | 100 ++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 31 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 14d2572f742..857a5bc9234 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ v 7.4.0 - Font Awesome 4.2 integration (Sullivan Senechal) - Add Pushover service integration (Sullivan Senechal) - Add select field type for services options (Sullivan Senechal) + - Add cross-project references to the Markdown parser (Vinnie Okada) v 7.3.2 - Fix creating new file via web editor diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index 5627fd0659f..5c095ed1487 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -177,6 +177,12 @@ GFM will recognize the following: - 1234567 : for commits - \[file\](path/to/file) : for file references +GFM also recognizes references to commits, issues, and merge requests in other projects: + +- namespace/project#123 : for issues +- namespace/project!123 : for merge requests +- namespace/project@1234567 : for commits + # Standard Markdown ## Headers diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index d346acf0d32..8380193deb3 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -108,15 +108,18 @@ module Gitlab text end + NAME_STR = '[a-zA-Z][a-zA-Z0-9_\-\.]*' + PROJ_STR = "(?#{NAME_STR}/#{NAME_STR})" + REFERENCE_PATTERN = %r{ (?\W)? # Prefix ( # Reference - @(?[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name + @(?#{NAME_STR}) # User name |(?([A-Z\-]+-)\d+) # JIRA Issue ID - |\#(?([a-zA-Z\-]+-)?\d+) # Issue ID - |!(?\d+) # MR ID + |#{PROJ_STR}?\#(?([a-zA-Z\-]+-)?\d+) # Issue ID + |#{PROJ_STR}?!(?\d+) # MR ID |\$(?\d+) # Snippet ID - |(?[\h]{6,40}) # Commit ID + |(#{PROJ_STR}@)?(?[\h]{6,40}) # Commit ID |(?gfm-extraction-[\h]{6,40}) # Skip gfm extractions. Otherwise will be parsed as commit ) (?\W)? # Suffix @@ -127,38 +130,57 @@ module Gitlab def parse_references(text, project = @project) # parse reference links text.gsub!(REFERENCE_PATTERN) do |match| - prefix = $~[:prefix] - suffix = $~[:suffix] type = TYPES.select{|t| !$~[t].nil?}.first - if type - identifier = $~[type] - - # Avoid HTML entities - if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';' - match - elsif ref_link = reference_link(type, identifier, project) - "#{prefix}#{ref_link}#{suffix}" - else - match - end - else - match + actual_project = project + project_prefix = nil + project_path = $LAST_MATCH_INFO[:project] + if project_path + actual_project = ::Project.find_with_namespace(project_path) + project_prefix = project_path end + + parse_result($LAST_MATCH_INFO, type, + actual_project, project_prefix) || match + end + end + + # Called from #parse_references. Attempts to build a gitlab reference + # link. Returns nil if either +type+ or +project+ are nil, if the match + # string is an HTML entity, or if the reference is invalid. + def parse_result(match_info, type, project, project_prefix) + prefix = match_info[:prefix] + suffix = match_info[:suffix] + + return nil if html_entity?(prefix, suffix) || project.nil? || type.nil? + + identifier = match_info[type] + ref_link = reference_link(type, identifier, project, project_prefix) + + if ref_link + "#{prefix}#{ref_link}#{suffix}" + else + nil end end + # Return true if the +prefix+ and +suffix+ indicate that the matched string + # is an HTML entity like & + def html_entity?(prefix, suffix) + prefix && suffix && prefix[0] == '&' && suffix[-1] == ';' + end + # Private: Dispatches to a dedicated processing method based on reference # # reference - Object reference ("@1234", "!567", etc.) # identifier - Object identifier (Issue ID, SHA hash, etc.) # # Returns string rendered by the processing method - def reference_link(type, identifier, project = @project) - send("reference_#{type}", identifier, project) + def reference_link(type, identifier, project = @project, prefix_text = nil) + send("reference_#{type}", identifier, project, prefix_text) end - def reference_user(identifier, project = @project) + def reference_user(identifier, project = @project, _ = nil) options = html_options.merge( class: "gfm gfm-team_member #{html_options[:class]}" ) @@ -170,17 +192,17 @@ module Gitlab end end - def reference_issue(identifier, project = @project) + def reference_issue(identifier, project = @project, prefix_text = nil) if project.used_default_issues_tracker? || !external_issues_tracker_enabled? if project.issue_exists? identifier url = url_for_issue(identifier, project) - title = title_for_issue(identifier) + title = title_for_issue(identifier, project) options = html_options.merge( title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}" ) - link_to("##{identifier}", url, options) + link_to("#{prefix_text}##{identifier}", url, options) end else config = Gitlab.config @@ -191,18 +213,19 @@ module Gitlab end end - def reference_merge_request(identifier, project = @project) + def reference_merge_request(identifier, project = @project, + prefix_text = nil) if merge_request = project.merge_requests.find_by(iid: identifier) options = html_options.merge( title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}" ) url = project_merge_request_url(project, merge_request) - link_to("!#{identifier}", url, options) + link_to("#{prefix_text}!#{identifier}", url, options) end end - def reference_snippet(identifier, project = @project) + def reference_snippet(identifier, project = @project, _ = nil) if snippet = project.snippets.find_by(id: identifier) options = html_options.merge( title: "Snippet: #{snippet.title}", @@ -213,17 +236,22 @@ module Gitlab end end - def reference_commit(identifier, project = @project) + def reference_commit(identifier, project = @project, prefix_text = nil) if project.valid_repo? && commit = project.repository.commit(identifier) options = html_options.merge( title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}" ) - link_to(identifier, project_commit_url(project, commit), options) + link_to( + "#{prefix_text}#{identifier}", + project_commit_url(project, commit), + options + ) end end - def reference_external_issue(identifier, issue_tracker, project = @project) + def reference_external_issue(identifier, issue_tracker, project = @project, + _ = nil) url = url_for_issue(identifier, project) title = issue_tracker['title'] diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 6c865b1e079..da246ff1e0d 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -181,6 +181,74 @@ describe GitlabMarkdownHelper do end end + # Shared examples for referencing an object in a different project + # + # Expects the following attributes to be available in the example group: + # + # - object - The object itself + # - reference - The object reference string (e.g., #1234, $1234, !1234) + # - other_project - The project that owns the target object + # + # Currently limited to Snippets, Issues and MergeRequests + shared_examples 'cross-project referenced object' do + let(:project_path) { @other_project.path_with_namespace } + let(:full_reference) { "#{project_path}#{reference}" } + let(:actual) { "Reference to #{full_reference}" } + let(:expected) do + if object.is_a?(Commit) + project_commit_path(@other_project, object) + else + polymorphic_path([@other_project, object]) + end + end + + it 'should link using a valid id' do + gfm(actual).should match(expected) + end + + it 'should link with adjacent text' do + # Wrap the reference in parenthesis + gfm(actual.gsub(full_reference, "(#{full_reference})")).should( + match(expected) + ) + + # Append some text to the end of the reference + gfm(actual.gsub(full_reference, "#{full_reference}, right?")).should( + match(expected) + ) + end + + it 'should keep whitespace intact' do + actual = "Referenced #{full_reference} already." + expected = /Referenced [^\s]+<\/a> already/ + gfm(actual).should match(expected) + end + + it 'should not link with an invalid id' do + # Modify the reference string so it's still parsed, but is invalid + if object.is_a?(Commit) + reference.gsub!(/^(.).+$/, '\1' + '12345abcd') + else + reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2)) + end + gfm(actual).should == actual + end + + it 'should include a title attribute' do + if object.is_a?(Commit) + title = object.link_title + else + title = "#{object.class.to_s.titlecase}: #{object.title}" + end + gfm(actual).should match(/title="#{title}"/) + end + + it 'should include standard gfm classes' do + css = object.class.to_s.underscore + gfm(actual).should match(/class="\s?gfm gfm-#{css}\s?"/) + end + end + describe "referencing an issue" do let(:object) { issue } let(:reference) { "##{issue.iid}" } @@ -188,6 +256,38 @@ describe GitlabMarkdownHelper do include_examples 'referenced object' end + context 'cross-repo references' do + before(:all) do + @other_project = create(:project, :public) + @commit2 = @other_project.repository.commit + @issue2 = create(:issue, project: @other_project) + @merge_request2 = create(:merge_request, + source_project: @other_project, + target_project: @other_project) + end + + describe 'referencing an issue in another project' do + let(:object) { @issue2 } + let(:reference) { "##{@issue2.iid}" } + + include_examples 'cross-project referenced object' + end + + describe 'referencing an merge request in another project' do + let(:object) { @merge_request2 } + let(:reference) { "!#{@merge_request2.iid}" } + + include_examples 'cross-project referenced object' + end + + describe 'referencing a commit in another project' do + let(:object) { @commit2 } + let(:reference) { "@#{@commit2.id}" } + + include_examples 'cross-project referenced object' + end + end + describe "referencing a Jira issue" do let(:actual) { "Reference to JIRA-#{issue.iid}" } let(:expected) { "http://jira.example/browse/JIRA-#{issue.iid}" } -- cgit v1.2.1 From 7edc1439fe11e396bb6327a3f50aca5dfe3c411c Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Wed, 1 Oct 2014 13:45:26 -0500 Subject: Fix ReferenceExtractor The cross-project reference feature broke the ReferenceExtractor class; this fixes it. --- lib/gitlab/markdown.rb | 8 +++++--- lib/gitlab/reference_extractor.rb | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 8380193deb3..51c33f7cb1d 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -146,13 +146,15 @@ module Gitlab end # Called from #parse_references. Attempts to build a gitlab reference - # link. Returns nil if either +type+ or +project+ are nil, if the match - # string is an HTML entity, or if the reference is invalid. + # link. Returns nil if +type+ is nil, if the match string is an HTML + # entity, if the reference is invalid, or if the matched text includes an + # invalid project path. def parse_result(match_info, type, project, project_prefix) prefix = match_info[:prefix] suffix = match_info[:suffix] - return nil if html_entity?(prefix, suffix) || project.nil? || type.nil? + return nil if html_entity?(prefix, suffix) || type.nil? + return nil if project.nil? && !project_prefix.nil? identifier = match_info[type] ref_link = reference_link(type, identifier, project, project_prefix) diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index 73b19ad55d5..d2f02f712ce 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -51,7 +51,7 @@ module Gitlab private - def reference_link(type, identifier, project) + def reference_link(type, identifier, _, _) # Append identifier to the appropriate collection. send("#{type}s") << identifier end -- cgit v1.2.1 From 2c46c4523fc8aa41cb60e4840af16fdd595f7dd2 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Thu, 2 Oct 2014 13:26:39 -0500 Subject: Track projects in ReferenceExtractor Store both the project and identifier of extracted references. This prevents `ReferenceExtractor` from returning objects in the wrong project for cross-project references. --- app/models/concerns/mentionable.rb | 2 +- lib/gitlab/closing_issue_extractor.rb | 2 +- lib/gitlab/reference_extractor.rb | 52 ++++++++++++++++++----------- spec/lib/gitlab/reference_extractor_spec.rb | 52 ++++++++++++++++------------- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 71dd2f8c697..8c31cdd12d0 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -67,7 +67,7 @@ module Mentionable def references(p = project, text = mentionable_text) return [] if text.blank? ext = Gitlab::ReferenceExtractor.new - ext.analyze(text) + ext.analyze(text, p) (ext.issues_for(p) + ext.merge_requests_for(p) + ext.commits_for(p)).uniq - [local_reference] end diff --git a/lib/gitlab/closing_issue_extractor.rb b/lib/gitlab/closing_issue_extractor.rb index 90f1370c209..401e6e047b1 100644 --- a/lib/gitlab/closing_issue_extractor.rb +++ b/lib/gitlab/closing_issue_extractor.rb @@ -6,7 +6,7 @@ module Gitlab md = ISSUE_CLOSING_REGEX.match(message) if md extractor = Gitlab::ReferenceExtractor.new - extractor.analyze(md[0]) + extractor.analyze(md[0], project) extractor.issues_for(project) else [] diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb index d2f02f712ce..99165950aef 100644 --- a/lib/gitlab/reference_extractor.rb +++ b/lib/gitlab/reference_extractor.rb @@ -9,51 +9,63 @@ module Gitlab @users, @issues, @merge_requests, @snippets, @commits = [], [], [], [], [] end - def analyze(string) - parse_references(string.dup) + def analyze(string, project) + parse_references(string.dup, project) end # Given a valid project, resolve the extracted identifiers of the requested type to # model objects. def users_for(project) - users.map do |identifier| - project.users.where(username: identifier).first + users.map do |entry| + project.users.where(username: entry[:id]).first end.reject(&:nil?) end - def issues_for(project) - issues.map do |identifier| - project.issues.where(iid: identifier).first + def issues_for(project = nil) + issues.map do |entry| + if should_lookup?(project, entry[:project]) + entry[:project].issues.where(iid: entry[:id]).first + end end.reject(&:nil?) end - def merge_requests_for(project) - merge_requests.map do |identifier| - project.merge_requests.where(iid: identifier).first + def merge_requests_for(project = nil) + merge_requests.map do |entry| + if should_lookup?(project, entry[:project]) + entry[:project].merge_requests.where(iid: entry[:id]).first + end end.reject(&:nil?) end def snippets_for(project) - snippets.map do |identifier| - project.snippets.where(id: identifier).first + snippets.map do |entry| + project.snippets.where(id: entry[:id]).first end.reject(&:nil?) end - def commits_for(project) - repo = project.repository - return [] if repo.nil? - - commits.map do |identifier| - repo.commit(identifier) + def commits_for(project = nil) + commits.map do |entry| + repo = entry[:project].repository if entry[:project] + if should_lookup?(project, entry[:project]) + repo.commit(entry[:id]) if repo + end end.reject(&:nil?) end private - def reference_link(type, identifier, _, _) + def reference_link(type, identifier, project, _) # Append identifier to the appropriate collection. - send("#{type}s") << identifier + send("#{type}s") << { project: project, id: identifier } + end + + def should_lookup?(project, entry_project) + if entry_project.nil? + false + else + project.nil? || project.id == entry_project.id + end end end end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 99fed27c796..23867df39dd 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -2,45 +2,48 @@ require 'spec_helper' describe Gitlab::ReferenceExtractor do it 'extracts username references' do - subject.analyze "this contains a @user reference" - subject.users.should == ["user"] + subject.analyze('this contains a @user reference', nil) + subject.users.should == [{ project: nil, id: 'user' }] end it 'extracts issue references' do - subject.analyze "this one talks about issue #1234" - subject.issues.should == ["1234"] + subject.analyze('this one talks about issue #1234', nil) + subject.issues.should == [{ project: nil, id: '1234' }] end it 'extracts JIRA issue references' do - Gitlab.config.gitlab.stub(:issues_tracker).and_return("jira") - subject.analyze "this one talks about issue JIRA-1234" - subject.issues.should == ["JIRA-1234"] + Gitlab.config.gitlab.stub(:issues_tracker).and_return('jira') + subject.analyze('this one talks about issue JIRA-1234', nil) + subject.issues.should == [{ project: nil, id: 'JIRA-1234' }] end it 'extracts merge request references' do - subject.analyze "and here's !43, a merge request" - subject.merge_requests.should == ["43"] + subject.analyze("and here's !43, a merge request", nil) + subject.merge_requests.should == [{ project: nil, id: '43' }] end it 'extracts snippet ids' do - subject.analyze "snippets like $12 get extracted as well" - subject.snippets.should == ["12"] + subject.analyze('snippets like $12 get extracted as well', nil) + subject.snippets.should == [{ project: nil, id: '12' }] end it 'extracts commit shas' do - subject.analyze "commit shas 98cf0ae3 are pulled out as Strings" - subject.commits.should == ["98cf0ae3"] + subject.analyze('commit shas 98cf0ae3 are pulled out as Strings', nil) + subject.commits.should == [{ project: nil, id: '98cf0ae3' }] end it 'extracts multiple references and preserves their order' do - subject.analyze "@me and @you both care about this" - subject.users.should == ["me", "you"] + subject.analyze('@me and @you both care about this', nil) + subject.users.should == [ + { project: nil, id: 'me' }, + { project: nil, id: 'you' } + ] end it 'leaves the original note unmodified' do - text = "issue #123 is just the worst, @user" - subject.analyze text - text.should == "issue #123 is just the worst, @user" + text = 'issue #123 is just the worst, @user' + subject.analyze(text, nil) + text.should == 'issue #123 is just the worst, @user' end it 'handles all possible kinds of references' do @@ -59,7 +62,7 @@ describe Gitlab::ReferenceExtractor do project.team << [@u_foo, :reporter] project.team << [@u_bar, :guest] - subject.analyze "@foo, @baduser, @bar, and @offteam" + subject.analyze('@foo, @baduser, @bar, and @offteam', project) subject.users_for(project).should == [@u_foo, @u_bar] end @@ -67,7 +70,7 @@ describe Gitlab::ReferenceExtractor do @i0 = create(:issue, project: project) @i1 = create(:issue, project: project) - subject.analyze "##{@i0.iid}, ##{@i1.iid}, and #999." + subject.analyze("##{@i0.iid}, ##{@i1.iid}, and #999.", project) subject.issues_for(project).should == [@i0, @i1] end @@ -75,7 +78,7 @@ describe Gitlab::ReferenceExtractor do @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa') @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb') - subject.analyze "!999, !#{@m1.iid}, and !#{@m0.iid}." + subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.", project) subject.merge_requests_for(project).should == [@m1, @m0] end @@ -84,14 +87,15 @@ describe Gitlab::ReferenceExtractor do @s1 = create(:project_snippet, project: project) @s2 = create(:project_snippet) - subject.analyze "$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}" + subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}", project) subject.snippets_for(project).should == [@s0, @s1] end it 'accesses valid commits' do - commit = project.repository.commit("master") + commit = project.repository.commit('master') - subject.analyze "this references commits #{commit.sha[0..6]} and 012345" + subject.analyze("this references commits #{commit.sha[0..6]} and 012345", + project) extracted = subject.commits_for(project) extracted.should have(1).item extracted[0].sha.should == commit.sha -- cgit v1.2.1 From 088987e2dd4b7ad8d62ebd34448dbe194df7812d Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Fri, 3 Oct 2014 00:48:35 -0500 Subject: Make Mentionables work for cross-project refs Add a note to merge requests and issues when they're mentioned by a merge request, issue, or commit in another project. --- app/models/concerns/mentionable.rb | 4 +- app/models/note.rb | 73 +++++++++++++++++++++++++++-- spec/models/commit_spec.rb | 14 +++++- spec/models/note_spec.rb | 4 +- spec/support/mentionable_shared_examples.rb | 40 +++++++++++++--- 5 files changed, 120 insertions(+), 15 deletions(-) diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 8c31cdd12d0..5938d9cb28e 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -68,7 +68,9 @@ module Mentionable return [] if text.blank? ext = Gitlab::ReferenceExtractor.new ext.analyze(text, p) - (ext.issues_for(p) + ext.merge_requests_for(p) + ext.commits_for(p)).uniq - [local_reference] + (ext.issues_for + + ext.merge_requests_for + + ext.commits_for).uniq - [local_reference] end # Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+. diff --git a/app/models/note.rb b/app/models/note.rb index fa5fdea4eb0..0c1d792ca9a 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -70,13 +70,17 @@ class Note < ActiveRecord::Base ) end - # +noteable+ was referenced from +mentioner+, by including GFM in either +mentioner+'s description or an associated Note. - # Create a system Note associated with +noteable+ with a GFM back-reference to +mentioner+. + # +noteable+ was referenced from +mentioner+, by including GFM in either + # +mentioner+'s description or an associated Note. + # Create a system Note associated with +noteable+ with a GFM back-reference + # to +mentioner+. def create_cross_reference_note(noteable, mentioner, author, project) + gfm_reference = mentioner_gfm_ref(noteable, mentioner, project) + note_options = { project: project, author: author, - note: "_mentioned in #{mentioner.gfm_reference}_", + note: "_mentioned in #{gfm_reference}_", system: true } @@ -163,12 +167,73 @@ class Note < ActiveRecord::Base # Determine whether or not a cross-reference note already exists. def cross_reference_exists?(noteable, mentioner) - where(noteable_id: noteable.id, system: true, note: "_mentioned in #{mentioner.gfm_reference}_").any? + gfm_reference = mentioner_gfm_ref(noteable, mentioner) + + where(['noteable_id = ? and system = ? and note like ?', + noteable.id, true, "_mentioned in #{gfm_reference}_"]).any? end def search(query) where("note like :query", query: "%#{query}%") end + + private + + # Prepend the mentioner's namespaced project path to the GFM reference for + # cross-project references. For same-project references, return the + # unmodified GFM reference. + def mentioner_gfm_ref(noteable, mentioner, project = nil) + if mentioner.is_a?(Commit) + if project.nil? + return mentioner.gfm_reference.sub('commit ', 'commit %') + else + mentioning_project = project + end + else + mentioning_project = mentioner.project + end + + noteable_project_id = noteable_project_id(noteable, mentioning_project) + + full_gfm_reference(mentioning_project, noteable_project_id, mentioner) + end + + # Return the ID of the project that +noteable+ belongs to, or nil if + # +noteable+ is a commit and is not part of the project that owns + # +mentioner+. + def noteable_project_id(noteable, mentioning_project) + if noteable.is_a?(Commit) + if mentioning_project.repository.commit(noteable.id) + # The noteable commit belongs to the mentioner's project + mentioning_project.id + else + nil + end + else + noteable.project.id + end + end + + # Return the +mentioner+ GFM reference. If the mentioner and noteable + # projects are not the same, add the mentioning project's path to the + # returned value. + def full_gfm_reference(mentioning_project, noteable_project_id, mentioner) + if mentioning_project.id == noteable_project_id + mentioner.gfm_reference + else + if mentioner.is_a?(Commit) + mentioner.gfm_reference.sub( + /(commit )/, + "\\1#{mentioning_project.path_with_namespace}@" + ) + else + mentioner.gfm_reference.sub( + /(issue |merge request )/, + "\\1#{mentioning_project.path_with_namespace}" + ) + end + end + end end def commit_author diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index 1673184cbe4..6f201adc4e8 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -53,11 +53,23 @@ eos describe '#closes_issues' do let(:issue) { create :issue, project: project } + let(:other_project) { create :project, :public } + let(:other_issue) { create :issue, project: other_project } it 'detects issues that this commit is marked as closing' do - commit.stub(issue_closing_regex: /^([Cc]loses|[Ff]ixes) #\d+/, safe_message: "Fixes ##{issue.iid}") + stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX', + /Fixes #\d+/) + commit.stub(safe_message: "Fixes ##{issue.iid}") commit.closes_issues(project).should == [issue] end + + it 'does not detect issues from other projects' do + ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}" + stub_const('Gitlab::ClosingIssueExtractor::ISSUE_CLOSING_REGEX', + /^([Cc]loses|[Ff]ixes)/) + commit.stub(safe_message: "Fixes #{ext_ref}") + commit.closes_issues(project).should be_empty + end end it_behaves_like 'a mentionable' do diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index da51100e0d7..c88a03beb0c 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -264,8 +264,8 @@ describe Note do let(:project) { create :project } let(:author) { create :user } let(:issue) { create :issue } - let(:commit0) { double 'commit0', gfm_reference: 'commit 123456' } - let(:commit1) { double 'commit1', gfm_reference: 'commit 654321' } + let(:commit0) { project.repository.commit } + let(:commit1) { project.repository.commit('HEAD~2') } before do Note.create_cross_reference_note(issue, commit0, author, project) diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb index 0d67e7ee4e6..692834c9f29 100644 --- a/spec/support/mentionable_shared_examples.rb +++ b/spec/support/mentionable_shared_examples.rb @@ -14,13 +14,23 @@ def common_mentionable_setup let(:mentioned_mr) { create :merge_request, :simple, source_project: mproject } let(:mentioned_commit) { double('commit', sha: '1234567890abcdef').as_null_object } + let(:ext_proj) { create :project, :public } + let(:ext_issue) { create :issue, project: ext_proj } + let(:other_ext_issue) { create :issue, project: ext_proj } + let(:ext_mr) { create :merge_request, :simple, source_project: ext_proj } + let(:ext_commit) { ext_proj.repository.commit } + # Override to add known commits to the repository stub. let(:extra_commits) { [] } # A string that mentions each of the +mentioned_.*+ objects above. Mentionables should add a self-reference # to this string and place it in their +mentionable_text+. let(:ref_string) do - "mentions ##{mentioned_issue.iid} twice ##{mentioned_issue.iid}, !#{mentioned_mr.iid}, " + + "mentions ##{mentioned_issue.iid} twice ##{mentioned_issue.iid}, " + + "!#{mentioned_mr.iid}, " + + "#{ext_proj.path_with_namespace}##{ext_issue.iid}, " + + "#{ext_proj.path_with_namespace}!#{ext_mr.iid}, " + + "#{ext_proj.path_with_namespace}@#{ext_commit.id[0..5]}, " + "#{mentioned_commit.sha[0..5]} and itself as #{backref_text}" end @@ -45,14 +55,20 @@ shared_examples 'a mentionable' do # De-duplicate and omit itself refs = subject.references(mproject) - refs.should have(3).items + refs.should have(6).items refs.should include(mentioned_issue) refs.should include(mentioned_mr) refs.should include(mentioned_commit) + refs.should include(ext_issue) + refs.should include(ext_mr) + refs.should include(ext_commit) end it 'creates cross-reference notes' do - [mentioned_issue, mentioned_mr, mentioned_commit].each do |referenced| + mentioned_objects = [mentioned_issue, mentioned_mr, mentioned_commit, + ext_issue, ext_mr, ext_commit] + + mentioned_objects.each do |referenced| Note.should_receive(:create_cross_reference_note).with(referenced, subject.local_reference, mauthor, mproject) end @@ -73,15 +89,25 @@ shared_examples 'an editable mentionable' do it_behaves_like 'a mentionable' it 'creates new cross-reference notes when the mentionable text is edited' do - new_text = "this text still mentions ##{mentioned_issue.iid} and #{mentioned_commit.sha[0..5]}, " + - "but now it mentions ##{other_issue.iid}, too." + new_text = "still mentions ##{mentioned_issue.iid}, " + + "#{mentioned_commit.sha[0..5]}, " + + "#{ext_issue.iid}, " + + "new refs: ##{other_issue.iid}, " + + "#{ext_proj.path_with_namespace}##{other_ext_issue.iid}" - [mentioned_issue, mentioned_commit].each do |oldref| + [mentioned_issue, mentioned_commit, ext_issue].each do |oldref| Note.should_not_receive(:create_cross_reference_note).with(oldref, subject.local_reference, mauthor, mproject) end - Note.should_receive(:create_cross_reference_note).with(other_issue, subject.local_reference, mauthor, mproject) + [other_issue, other_ext_issue].each do |newref| + Note.should_receive(:create_cross_reference_note).with( + newref, + subject.local_reference, + mauthor, + mproject + ) + end subject.save set_mentionable_text.call(new_text) -- cgit v1.2.1 From 4adcd5113386e30edb7993f36bb009f472b36262 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 3 Oct 2014 21:44:16 +0300 Subject: Improve subnavigation style --- app/assets/stylesheets/sections/nav.scss | 39 +++++--------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss index 778953984d6..fca15950200 100644 --- a/app/assets/stylesheets/sections/nav.scss +++ b/app/assets/stylesheets/sections/nav.scss @@ -8,8 +8,6 @@ ul { padding: 0; margin: auto; - height: 40px; - overflow: hidden; .count { font-weight: normal; display: inline-block; @@ -37,40 +35,14 @@ a { color: $link_color; font-weight: bold; - &:after { - content: ''; - display: block; - position: relative; - bottom: -1px; - border-color: $link_color; - border-style: solid; - border-width: 2px; - } + border-bottom: 3px solid $link_color; } } &:hover { a { color: $link_hover_color; - &:after { - content: ''; - display: block; - position: relative; - bottom: -1px; - border-color: $link_hover_color; - border-style: solid; - border-width: 2px; - } - } - } - - &.home { - a { - i { - font-size: 20px; - position: relative; - top: 4px; - } + border-bottom: 3px solid $link_hover_color; } } } @@ -78,12 +50,13 @@ display: block; text-align: center; font-weight: 500; - height: 38px; - line-height: 34px; + height: 42px; + line-height: 39px; color: #777; text-shadow: 0 1px 1px white; text-decoration: none; - padding-top: 2px; + overflow: hidden; + margin-bottom: -1px; } } -- cgit v1.2.1 From b2a45a1d35254a8142c7e0c9c511615db2228097 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 3 Oct 2014 22:01:23 +0300 Subject: Make nav links bold since some desktops does not render 500 properly --- app/assets/stylesheets/sections/nav.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss index fca15950200..31c0a0835db 100644 --- a/app/assets/stylesheets/sections/nav.scss +++ b/app/assets/stylesheets/sections/nav.scss @@ -49,7 +49,7 @@ a { display: block; text-align: center; - font-weight: 500; + font-weight: bold; height: 42px; line-height: 39px; color: #777; -- cgit v1.2.1 From c0e2eee38bc0315a623219d716c724a7e4c98c77 Mon Sep 17 00:00:00 2001 From: Sullivan SENECHAL Date: Sat, 4 Oct 2014 16:58:59 +0200 Subject: Fix fa-download icon --- app/views/projects/blob/_download.html.haml | 2 +- app/views/projects/commit/_commit_box.html.haml | 2 +- app/views/projects/merge_requests/show/_mr_title.html.haml | 2 +- .../projects/repositories/_download_archive.html.haml | 14 +++++++------- app/views/projects/wikis/_nav.html.haml | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/views/projects/blob/_download.html.haml b/app/views/projects/blob/_download.html.haml index 74a45cd8ae3..c24eeea4931 100644 --- a/app/views/projects/blob/_download.html.haml +++ b/app/views/projects/blob/_download.html.haml @@ -2,6 +2,6 @@ .center = link_to project_raw_path(@project, @id) do %h1.light - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %h4 Download (#{number_to_human_size blob.size}) diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 80ead5b96a8..0b6b6af4f90 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -6,7 +6,7 @@ = @notes_count .pull-left.btn-group %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download Download as %span.caret %ul.dropdown-menu diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index 276c980966a..6fe765248e4 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -6,7 +6,7 @@ - if @merge_request.open? .btn-group.pull-left %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download Download as %span.caret %ul.dropdown-menu diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml index 3b4f1a4298d..ce69adeb48c 100644 --- a/app/views/projects/repositories/_download_archive.html.haml +++ b/app/views/projects/repositories/_download_archive.html.haml @@ -4,7 +4,7 @@ - if split_button == true %span.btn-group{class: btn_class} = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn', rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span Download zip %a.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' } %span.caret @@ -13,25 +13,25 @@ %ul.dropdown-menu{ role: 'menu' } %li = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span Download zip %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span Download tar.gz %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.bz2'), rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span Download tar.bz2 %li = link_to archive_project_repository_path(@project, ref: ref, format: 'tar'), rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span Download tar - else %span.btn-group{class: btn_class} = link_to archive_project_repository_path(@project, ref: ref, format: 'zip'), class: 'btn', rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span zip = link_to archive_project_repository_path(@project, ref: ref, format: 'tar.gz'), class: 'btn', rel: 'nofollow' do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download %span tar.gz diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml index a2010f3794f..90539fde583 100644 --- a/app/views/projects/wikis/_nav.html.haml +++ b/app/views/projects/wikis/_nav.html.haml @@ -7,7 +7,7 @@ = nav_link(path: 'wikis#git_access') do = link_to git_access_project_wikis_path(@project) do - %i.fa.fa-arrow-circle-o-down-alt + %i.fa.fa-download Git Access - if can?(current_user, :write_wiki, @project) -- cgit v1.2.1 From 07e9cb6b77b35ed92d0d9a8e5bcdf92884024dbf Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Sat, 4 Oct 2014 17:56:12 +0200 Subject: Factor markup? || gitlab_markdown? into new method --- app/helpers/tree_helper.rb | 2 +- app/models/tree.rb | 2 +- lib/gitlab/markdown_helper.rb | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index c3b537eac47..9c611a1c147 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -90,7 +90,7 @@ module TreeHelper end def editing_preview_title(filename) - if gitlab_markdown?(filename) || markup?(filename) + if Gitlab::MarkdownHelper.previewable?(filename) 'Preview' else 'Diff' diff --git a/app/models/tree.rb b/app/models/tree.rb index 07c9a825e24..4f5d81f0a5e 100644 --- a/app/models/tree.rb +++ b/app/models/tree.rb @@ -15,7 +15,7 @@ class Tree # by markup renderer. if available_readmes.length > 1 supported_readmes = available_readmes.select do |readme| - gitlab_markdown?(readme.name) || markup?(readme.name) + previewable?(readme.name) end # Take the first supported readme, or the first available readme, if we diff --git a/lib/gitlab/markdown_helper.rb b/lib/gitlab/markdown_helper.rb index abed12fe570..5e3cfc0585b 100644 --- a/lib/gitlab/markdown_helper.rb +++ b/lib/gitlab/markdown_helper.rb @@ -21,5 +21,9 @@ module Gitlab def gitlab_markdown?(filename) filename.downcase.end_with?(*%w(.mdown .md .markdown)) end + + def previewable?(filename) + gitlab_markdown?(filename) || markup?(filename) + end end end -- cgit v1.2.1 From bcf88c85597d8a40a209f4aa24cd6015f66d97c6 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 5 Oct 2014 10:12:53 -0500 Subject: Fix external issue links Display the project path in links to issues in other projects that use an external issue tracker. --- lib/gitlab/markdown.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 51c33f7cb1d..9b3e34653af 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -210,7 +210,8 @@ module Gitlab config = Gitlab.config external_issue_tracker = config.issues_tracker[project.issues_tracker] if external_issue_tracker.present? - reference_external_issue(identifier, external_issue_tracker, project) + reference_external_issue(identifier, external_issue_tracker, project, + prefix_text) end end end @@ -253,7 +254,7 @@ module Gitlab end def reference_external_issue(identifier, issue_tracker, project = @project, - _ = nil) + prefix_text = nil) url = url_for_issue(identifier, project) title = issue_tracker['title'] @@ -261,7 +262,7 @@ module Gitlab title: "Issue in #{title}", class: "gfm gfm-issue #{html_options[:class]}" ) - link_to("##{identifier}", url, options) + link_to("#{prefix_text}##{identifier}", url, options) end end end -- cgit v1.2.1 From a9cd3bfaeefcdc9eee594aeca062bb9f0663aaf1 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 5 Oct 2014 10:16:12 -0500 Subject: Fix external commit links Display the '@' character for links to commits in other projects. --- lib/gitlab/markdown.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 9b3e34653af..709a74fe21e 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -245,6 +245,7 @@ module Gitlab title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}" ) + prefix_text = "#{prefix_text}@" if prefix_text link_to( "#{prefix_text}#{identifier}", project_commit_url(project, commit), -- cgit v1.2.1 From 8dce0cd215b657d11b3e183e361fc86ae9314ecd Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 5 Oct 2014 10:46:52 -0500 Subject: Fix cross-project reference test Test for the correct link text in cross-project references. --- spec/helpers/gitlab_markdown_helper_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index da246ff1e0d..73b3d91e96e 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -203,7 +203,9 @@ describe GitlabMarkdownHelper do end it 'should link using a valid id' do - gfm(actual).should match(expected) + gfm(actual).should match( + /#{expected}.*#{Regexp.escape(full_reference)}/ + ) end it 'should link with adjacent text' do -- cgit v1.2.1 From fa34901237cc244fe8b828d079af891e63de1c8f Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Thu, 2 Oct 2014 18:42:54 +0200 Subject: Make Spinach test names consistent - do not add Feature to feature titles - titleize feature titles - put steps on the same path as .feature files - make feature titles match their path --- features/dashboard/active_tab.feature | 2 +- features/dashboard/archived_projects.feature | 2 +- features/dashboard/event_filters.feature | 2 +- features/dashboard/help.feature | 2 +- features/dashboard/projects.feature | 2 +- features/dashboard/shortcuts.feature | 2 +- features/explore/groups.feature | 151 +++++++++++ features/explore/projects.feature | 2 +- features/explore/public_groups.feature | 151 ----------- features/group.feature | 143 ---------- features/groups.feature | 143 ++++++++++ features/profile/active_tab.feature | 2 +- features/project/active_tab.feature | 2 +- features/project/commits/branches.feature | 2 +- features/project/commits/comments.feature | 2 +- features/project/commits/commits.feature | 2 +- features/project/commits/diff_comments.feature | 2 +- features/project/commits/tags.feature | 2 +- features/project/commits/user_lookup.feature | 2 +- features/project/create.feature | 2 +- features/project/fork.feature | 2 +- features/project/issues/filter_labels.feature | 2 +- features/project/issues/labels.feature | 2 +- features/project/issues/milestones.feature | 2 +- features/project/network.feature | 40 --- features/project/network_graph.feature | 40 +++ features/project/project.feature | 2 +- features/project/shortcuts.feature | 2 +- features/project/source/browse_files.feature | 2 +- features/project/source/git_blame.feature | 2 +- features/project/source/markdown_render.feature | 2 +- features/project/source/multiselect_blob.feature | 2 +- features/project/source/search_code.feature | 2 +- features/project/team_management.feature | 2 +- features/snippets/discover.feature | 2 +- features/snippets/snippets.feature | 2 +- features/snippets/user.feature | 2 +- features/steps/dashboard/archived_projects.rb | 22 ++ features/steps/dashboard/help.rb | 21 ++ features/steps/dashboard/with_archived_projects.rb | 22 -- features/steps/explore/groups.rb | 92 +++++++ features/steps/explore/groups_feature.rb | 92 ------- features/steps/explore/projects.rb | 2 +- features/steps/group.rb | 277 -------------------- features/steps/groups.rb | 277 ++++++++++++++++++++ features/steps/help.rb | 21 -- features/steps/project/browse_branches.rb | 85 ------ features/steps/project/browse_commits.rb | 91 ------- .../steps/project/browse_commits_user_lookup.rb | 48 ---- features/steps/project/browse_files.rb | 176 ------------- features/steps/project/browse_git_repo.rb | 19 -- features/steps/project/browse_tags.rb | 82 ------ features/steps/project/comments_on_commit_diffs.rb | 6 - features/steps/project/comments_on_commits.rb | 6 - features/steps/project/commits/branches.rb | 85 ++++++ features/steps/project/commits/comments.rb | 6 + features/steps/project/commits/commits.rb | 91 +++++++ features/steps/project/commits/diff_comments.rb | 6 + features/steps/project/commits/tags.rb | 82 ++++++ features/steps/project/commits/user_lookup.rb | 48 ++++ features/steps/project/create.rb | 2 +- features/steps/project/filter_labels.rb | 79 ------ features/steps/project/fork.rb | 2 +- features/steps/project/issues.rb | 236 ----------------- features/steps/project/issues/filter_labels.rb | 79 ++++++ features/steps/project/issues/issues.rb | 236 +++++++++++++++++ features/steps/project/issues/labels.rb | 101 ++++++++ features/steps/project/issues/milestones.rb | 59 +++++ features/steps/project/labels.rb | 101 -------- features/steps/project/markdown_render.rb | 288 --------------------- features/steps/project/milestones.rb | 59 ----- features/steps/project/multiselect_blob.rb | 58 ----- features/steps/project/project.rb | 2 +- features/steps/project/search_code.rb | 19 -- features/steps/project/source/browse_files.rb | 176 +++++++++++++ features/steps/project/source/git_blame.rb | 19 ++ features/steps/project/source/markdown_render.rb | 288 +++++++++++++++++++++ features/steps/project/source/multiselect_blob.rb | 58 +++++ features/steps/project/source/search_code.rb | 19 ++ features/steps/snippets/discover.rb | 2 +- features/steps/snippets/snippets.rb | 2 +- features/steps/snippets/user.rb | 2 +- 82 files changed, 2137 insertions(+), 2137 deletions(-) create mode 100644 features/explore/groups.feature delete mode 100644 features/explore/public_groups.feature delete mode 100644 features/group.feature create mode 100644 features/groups.feature delete mode 100644 features/project/network.feature create mode 100644 features/project/network_graph.feature create mode 100644 features/steps/dashboard/archived_projects.rb create mode 100644 features/steps/dashboard/help.rb delete mode 100644 features/steps/dashboard/with_archived_projects.rb create mode 100644 features/steps/explore/groups.rb delete mode 100644 features/steps/explore/groups_feature.rb delete mode 100644 features/steps/group.rb create mode 100644 features/steps/groups.rb delete mode 100644 features/steps/help.rb delete mode 100644 features/steps/project/browse_branches.rb delete mode 100644 features/steps/project/browse_commits.rb delete mode 100644 features/steps/project/browse_commits_user_lookup.rb delete mode 100644 features/steps/project/browse_files.rb delete mode 100644 features/steps/project/browse_git_repo.rb delete mode 100644 features/steps/project/browse_tags.rb delete mode 100644 features/steps/project/comments_on_commit_diffs.rb delete mode 100644 features/steps/project/comments_on_commits.rb create mode 100644 features/steps/project/commits/branches.rb create mode 100644 features/steps/project/commits/comments.rb create mode 100644 features/steps/project/commits/commits.rb create mode 100644 features/steps/project/commits/diff_comments.rb create mode 100644 features/steps/project/commits/tags.rb create mode 100644 features/steps/project/commits/user_lookup.rb delete mode 100644 features/steps/project/filter_labels.rb delete mode 100644 features/steps/project/issues.rb create mode 100644 features/steps/project/issues/filter_labels.rb create mode 100644 features/steps/project/issues/issues.rb create mode 100644 features/steps/project/issues/labels.rb create mode 100644 features/steps/project/issues/milestones.rb delete mode 100644 features/steps/project/labels.rb delete mode 100644 features/steps/project/markdown_render.rb delete mode 100644 features/steps/project/milestones.rb delete mode 100644 features/steps/project/multiselect_blob.rb delete mode 100644 features/steps/project/search_code.rb create mode 100644 features/steps/project/source/browse_files.rb create mode 100644 features/steps/project/source/git_blame.rb create mode 100644 features/steps/project/source/markdown_render.rb create mode 100644 features/steps/project/source/multiselect_blob.rb create mode 100644 features/steps/project/source/search_code.rb diff --git a/features/dashboard/active_tab.feature b/features/dashboard/active_tab.feature index 22dfa2f7840..08b87808f33 100644 --- a/features/dashboard/active_tab.feature +++ b/features/dashboard/active_tab.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Dashboard active tab +Feature: Dashboard Active Tab Background: Given I sign in as a user diff --git a/features/dashboard/archived_projects.feature b/features/dashboard/archived_projects.feature index e23238d225c..3af93bc373c 100644 --- a/features/dashboard/archived_projects.feature +++ b/features/dashboard/archived_projects.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Dashboard with archived projects +Feature: Dashboard Archived Projects Background: Given I sign in as a user And I own project "Shop" diff --git a/features/dashboard/event_filters.feature b/features/dashboard/event_filters.feature index 41de0ae8317..ec5680caba6 100644 --- a/features/dashboard/event_filters.feature +++ b/features/dashboard/event_filters.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Event filters +Feature: Event Filters Background: Given I sign in as a user And I own a project diff --git a/features/dashboard/help.feature b/features/dashboard/help.feature index 56a0a860ab9..bca2772897b 100644 --- a/features/dashboard/help.feature +++ b/features/dashboard/help.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Help +Feature: Dashboard Help Background: Given I sign in as a user And I visit the "Rake Tasks" help page diff --git a/features/dashboard/projects.feature b/features/dashboard/projects.feature index 5214cfc28ef..bb4e84f0159 100644 --- a/features/dashboard/projects.feature +++ b/features/dashboard/projects.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Dashboard projects +Feature: Dashboard Projects Background: Given I sign in as a user And I own project "Shop" diff --git a/features/dashboard/shortcuts.feature b/features/dashboard/shortcuts.feature index 7c25b3926c9..41d79aa6ec8 100644 --- a/features/dashboard/shortcuts.feature +++ b/features/dashboard/shortcuts.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Dashboard shortcuts +Feature: Dashboard Shortcuts Background: Given I sign in as a user And I visit dashboard page diff --git a/features/explore/groups.feature b/features/explore/groups.feature new file mode 100644 index 00000000000..b50a3e766c6 --- /dev/null +++ b/features/explore/groups.feature @@ -0,0 +1,151 @@ +@public +Feature: Explore Groups + Background: + Given group "TestGroup" has private project "Enterprise" + + Scenario: I should not see group with private projects as visitor + When I visit group "TestGroup" page + Then I should be redirected to sign in page + + Scenario: I should not see group with private projects group as user + When I sign in as a user + And I visit group "TestGroup" page + Then page status code should be 404 + + Scenario: I should not see group with private and internal projects as visitor + Given group "TestGroup" has internal project "Internal" + When I visit group "TestGroup" page + Then I should be redirected to sign in page + + Scenario: I should see group with private and internal projects as user + Given group "TestGroup" has internal project "Internal" + When I sign in as a user + And I visit group "TestGroup" page + Then I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group issues for internal project as user + Given group "TestGroup" has internal project "Internal" + When I sign in as a user + And I visit group "TestGroup" issues page + And I change filter to Everyone's + Then I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group merge requests for internal project as user + Given group "TestGroup" has internal project "Internal" + When I sign in as a user + And I visit group "TestGroup" merge requests page + And I change filter to Everyone's + Then I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group's members as user + Given group "TestGroup" has internal project "Internal" + And "John Doe" is owner of group "TestGroup" + When I sign in as a user + And I visit group "TestGroup" members page + Then I should see group member "John Doe" + And I should not see member roles + + Scenario: I should see group with private, internal and public projects as visitor + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I visit group "TestGroup" page + Then I should see project "Community" items + And I should not see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group issues for public project as visitor + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I visit group "TestGroup" issues page + Then I should see project "Community" items + And I should not see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group merge requests for public project as visitor + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I visit group "TestGroup" merge requests page + Then I should see project "Community" items + And I should not see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group's members as visitor + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + And "John Doe" is owner of group "TestGroup" + When I visit group "TestGroup" members page + Then I should see group member "John Doe" + And I should not see member roles + + Scenario: I should see group with private, internal and public projects as user + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I sign in as a user + And I visit group "TestGroup" page + Then I should see project "Community" items + And I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group issues for internal and public projects as user + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I sign in as a user + And I visit group "TestGroup" issues page + And I change filter to Everyone's + Then I should see project "Community" items + And I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group merge requests for internal and public projects as user + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + When I sign in as a user + And I visit group "TestGroup" merge requests page + And I change filter to Everyone's + Then I should see project "Community" items + And I should see project "Internal" items + And I should not see project "Enterprise" items + + Scenario: I should see group's members as user + Given group "TestGroup" has internal project "Internal" + Given group "TestGroup" has public project "Community" + And "John Doe" is owner of group "TestGroup" + When I sign in as a user + And I visit group "TestGroup" members page + Then I should see group member "John Doe" + And I should not see member roles + + Scenario: I should see group with public project in public groups area + Given group "TestGroup" has public project "Community" + When I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should not see group with internal project in public groups area + Given group "TestGroup" has internal project "Internal" + When I visit the public groups area + Then I should not see group "TestGroup" + + Scenario: I should not see group with private project in public groups area + When I visit the public groups area + Then I should not see group "TestGroup" + + Scenario: I should see group with public project in public groups area as user + Given group "TestGroup" has public project "Community" + When I sign in as a user + And I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should see group with internal project in public groups area as user + Given group "TestGroup" has internal project "Internal" + When I sign in as a user + And I visit the public groups area + Then I should see group "TestGroup" + + Scenario: I should not see group with private project in public groups area as user + When I sign in as a user + And I visit the public groups area + Then I should not see group "TestGroup" + diff --git a/features/explore/projects.feature b/features/explore/projects.feature index 9827ebe3e57..a1b29722678 100644 --- a/features/explore/projects.feature +++ b/features/explore/projects.feature @@ -1,5 +1,5 @@ @public -Feature: Explore Projects Feature +Feature: Explore Projects Background: Given public project "Community" And internal project "Internal" diff --git a/features/explore/public_groups.feature b/features/explore/public_groups.feature deleted file mode 100644 index 825e3da934e..00000000000 --- a/features/explore/public_groups.feature +++ /dev/null @@ -1,151 +0,0 @@ -@public -Feature: Explore Groups Feature - Background: - Given group "TestGroup" has private project "Enterprise" - - Scenario: I should not see group with private projects as visitor - When I visit group "TestGroup" page - Then I should be redirected to sign in page - - Scenario: I should not see group with private projects group as user - When I sign in as a user - And I visit group "TestGroup" page - Then page status code should be 404 - - Scenario: I should not see group with private and internal projects as visitor - Given group "TestGroup" has internal project "Internal" - When I visit group "TestGroup" page - Then I should be redirected to sign in page - - Scenario: I should see group with private and internal projects as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" page - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for internal project as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" issues page - And I change filter to Everyone's - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for internal project as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" merge requests page - And I change filter to Everyone's - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as user - Given group "TestGroup" has internal project "Internal" - And "John Doe" is owner of group "TestGroup" - When I sign in as a user - And I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with private, internal and public projects as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for public project as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" issues page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for public project as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" merge requests page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - And "John Doe" is owner of group "TestGroup" - When I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with private, internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" page - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" issues page - And I change filter to Everyone's - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" merge requests page - And I change filter to Everyone's - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - And "John Doe" is owner of group "TestGroup" - When I sign in as a user - And I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with public project in public groups area - Given group "TestGroup" has public project "Community" - When I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should not see group with internal project in public groups area - Given group "TestGroup" has internal project "Internal" - When I visit the public groups area - Then I should not see group "TestGroup" - - Scenario: I should not see group with private project in public groups area - When I visit the public groups area - Then I should not see group "TestGroup" - - Scenario: I should see group with public project in public groups area as user - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should see group with internal project in public groups area as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should not see group with private project in public groups area as user - When I sign in as a user - And I visit the public groups area - Then I should not see group "TestGroup" - diff --git a/features/group.feature b/features/group.feature deleted file mode 100644 index b5ff03db844..00000000000 --- a/features/group.feature +++ /dev/null @@ -1,143 +0,0 @@ -Feature: Groups - Background: - Given I sign in as "John Doe" - And "John Doe" is owner of group "Owned" - And "John Doe" is guest of group "Guest" - - @javascript - Scenario: I should see group "Owned" dashboard list - When I visit group "Owned" page - Then I should see group "Owned" projects list - And I should see projects activity feed - - Scenario: Create a group from dasboard - When I visit group "Owned" page - And I visit dashboard page - And I click new group link - And submit form with new group "Samurai" info - Then I should be redirected to group "Samurai" page - And I should see newly created group "Samurai" - - Scenario: I should see group "Owned" issues list - Given project from group "Owned" has issues assigned to me - When I visit group "Owned" issues page - Then I should see issues from group "Owned" assigned to me - - Scenario: I should see group "Owned" merge requests list - Given project from group "Owned" has merge requests assigned to me - When I visit group "Owned" merge requests page - Then I should see merge requests from group "Owned" assigned to me - - @javascript - Scenario: I should add user to projects in group "Owned" - Given User "Mary Jane" exists - When I visit group "Owned" members page - And I select user "Mary Jane" from list with role "Reporter" - Then I should see user "Mary Jane" in team list - - Scenario: I should see edit group "Owned" page - When I visit group "Owned" settings page - And I change group "Owned" name to "new-name" - Then I should see new group "Owned" name - - Scenario: I edit group "Owned" avatar - When I visit group "Owned" settings page - And I change group "Owned" avatar - And I visit group "Owned" settings page - Then I should see new group "Owned" avatar - And I should see the "Remove avatar" button - - Scenario: I remove group "Owned" avatar - When I visit group "Owned" settings page - And I have group "Owned" avatar - And I visit group "Owned" settings page - And I remove group "Owned" avatar - Then I should not see group "Owned" avatar - And I should not see the "Remove avatar" button - - # Leave - - @javascript - Scenario: Owner should be able to remove himself from group if he is not the last owner - Given "Mary Jane" is owner of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "John Doe" - And I visit group "Owned" members page - Then I should not see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - - @javascript - Scenario: Owner should not be able to remove himself from group if he is the last owner - Given "Mary Jane" is guest of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - Then I should not see the "Remove User From Group" button for "John Doe" - - @javascript - Scenario: Guest should be able to remove himself from group - Given "Mary Jane" is guest of group "Guest" - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "John Doe" - When I visit group "Guest" members page - Then I should not see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - - @javascript - Scenario: Guest should be able to remove himself from group even if he is the only user in the group - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - When I click on the "Remove User From Group" button for "John Doe" - When I visit group "Guest" members page - Then I should not see user "John Doe" in team list - - # Remove others - - Scenario: Owner should be able to remove other users from group - Given "Mary Jane" is owner of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "Mary Jane" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should not see user "Mary Jane" in team list - - Scenario: Guest should not be able to remove other users from group - Given "Mary Jane" is guest of group "Guest" - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - Then I should not see the "Remove User From Group" button for "Mary Jane" - - Scenario: Search member by name - Given "Mary Jane" is guest of group "Guest" - And I visit group "Guest" members page - When I search for 'Mary' member - Then I should see user "Mary Jane" in team list - Then I should not see user "John Doe" in team list - - # Group milestones - - Scenario: I should see group "Owned" milestone index page with no milestones - When I visit group "Owned" page - And I click on group milestones - Then I should see group milestones index page has no milestones - - Scenario: I should see group "Owned" milestone index page with milestones - Given Group has projects with milestones - When I visit group "Owned" page - And I click on group milestones - Then I should see group milestones index page with milestones - - Scenario: I should see group "Owned" milestone show page - Given Group has projects with milestones - When I visit group "Owned" page - And I click on group milestones - And I click on one group milestone - Then I should see group milestone with descriptions and expiry date - And I should see group milestone with all issues and MRs assigned to that milestone diff --git a/features/groups.feature b/features/groups.feature new file mode 100644 index 00000000000..b5ff03db844 --- /dev/null +++ b/features/groups.feature @@ -0,0 +1,143 @@ +Feature: Groups + Background: + Given I sign in as "John Doe" + And "John Doe" is owner of group "Owned" + And "John Doe" is guest of group "Guest" + + @javascript + Scenario: I should see group "Owned" dashboard list + When I visit group "Owned" page + Then I should see group "Owned" projects list + And I should see projects activity feed + + Scenario: Create a group from dasboard + When I visit group "Owned" page + And I visit dashboard page + And I click new group link + And submit form with new group "Samurai" info + Then I should be redirected to group "Samurai" page + And I should see newly created group "Samurai" + + Scenario: I should see group "Owned" issues list + Given project from group "Owned" has issues assigned to me + When I visit group "Owned" issues page + Then I should see issues from group "Owned" assigned to me + + Scenario: I should see group "Owned" merge requests list + Given project from group "Owned" has merge requests assigned to me + When I visit group "Owned" merge requests page + Then I should see merge requests from group "Owned" assigned to me + + @javascript + Scenario: I should add user to projects in group "Owned" + Given User "Mary Jane" exists + When I visit group "Owned" members page + And I select user "Mary Jane" from list with role "Reporter" + Then I should see user "Mary Jane" in team list + + Scenario: I should see edit group "Owned" page + When I visit group "Owned" settings page + And I change group "Owned" name to "new-name" + Then I should see new group "Owned" name + + Scenario: I edit group "Owned" avatar + When I visit group "Owned" settings page + And I change group "Owned" avatar + And I visit group "Owned" settings page + Then I should see new group "Owned" avatar + And I should see the "Remove avatar" button + + Scenario: I remove group "Owned" avatar + When I visit group "Owned" settings page + And I have group "Owned" avatar + And I visit group "Owned" settings page + And I remove group "Owned" avatar + Then I should not see group "Owned" avatar + And I should not see the "Remove avatar" button + + # Leave + + @javascript + Scenario: Owner should be able to remove himself from group if he is not the last owner + Given "Mary Jane" is owner of group "Owned" + When I visit group "Owned" members page + Then I should see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + When I click on the "Remove User From Group" button for "John Doe" + And I visit group "Owned" members page + Then I should not see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + + @javascript + Scenario: Owner should not be able to remove himself from group if he is the last owner + Given "Mary Jane" is guest of group "Owned" + When I visit group "Owned" members page + Then I should see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + Then I should not see the "Remove User From Group" button for "John Doe" + + @javascript + Scenario: Guest should be able to remove himself from group + Given "Mary Jane" is guest of group "Guest" + When I visit group "Guest" members page + Then I should see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + When I click on the "Remove User From Group" button for "John Doe" + When I visit group "Guest" members page + Then I should not see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + + @javascript + Scenario: Guest should be able to remove himself from group even if he is the only user in the group + When I visit group "Guest" members page + Then I should see user "John Doe" in team list + When I click on the "Remove User From Group" button for "John Doe" + When I visit group "Guest" members page + Then I should not see user "John Doe" in team list + + # Remove others + + Scenario: Owner should be able to remove other users from group + Given "Mary Jane" is owner of group "Owned" + When I visit group "Owned" members page + Then I should see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + When I click on the "Remove User From Group" button for "Mary Jane" + When I visit group "Owned" members page + Then I should see user "John Doe" in team list + Then I should not see user "Mary Jane" in team list + + Scenario: Guest should not be able to remove other users from group + Given "Mary Jane" is guest of group "Guest" + When I visit group "Guest" members page + Then I should see user "John Doe" in team list + Then I should see user "Mary Jane" in team list + Then I should not see the "Remove User From Group" button for "Mary Jane" + + Scenario: Search member by name + Given "Mary Jane" is guest of group "Guest" + And I visit group "Guest" members page + When I search for 'Mary' member + Then I should see user "Mary Jane" in team list + Then I should not see user "John Doe" in team list + + # Group milestones + + Scenario: I should see group "Owned" milestone index page with no milestones + When I visit group "Owned" page + And I click on group milestones + Then I should see group milestones index page has no milestones + + Scenario: I should see group "Owned" milestone index page with milestones + Given Group has projects with milestones + When I visit group "Owned" page + And I click on group milestones + Then I should see group milestones index page with milestones + + Scenario: I should see group "Owned" milestone show page + Given Group has projects with milestones + When I visit group "Owned" page + And I click on group milestones + And I click on one group milestone + Then I should see group milestone with descriptions and expiry date + And I should see group milestone with all issues and MRs assigned to that milestone diff --git a/features/profile/active_tab.feature b/features/profile/active_tab.feature index a99409d9fd7..7801ae5b8ca 100644 --- a/features/profile/active_tab.feature +++ b/features/profile/active_tab.feature @@ -1,5 +1,5 @@ @profile -Feature: Profile active tab +Feature: Profile Active Tab Background: Given I sign in as a user diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature index ce90a086688..8d3e0bd967f 100644 --- a/features/project/active_tab.feature +++ b/features/project/active_tab.feature @@ -1,4 +1,4 @@ -Feature: Project active tab +Feature: Project Active Tab Background: Given I sign in as a user And I own a project diff --git a/features/project/commits/branches.feature b/features/project/commits/branches.feature index d124cb7eecd..65d8e48b9b3 100644 --- a/features/project/commits/branches.feature +++ b/features/project/commits/branches.feature @@ -1,4 +1,4 @@ -Feature: Project Browse branches +Feature: Project Commits Branches Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/commits/comments.feature b/features/project/commits/comments.feature index a1aa745a681..e176752cfbf 100644 --- a/features/project/commits/comments.feature +++ b/features/project/commits/comments.feature @@ -1,4 +1,4 @@ -Feature: Comments on commits +Feature: Project Commits Comments Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature index 8a213067548..46076b6f3e6 100644 --- a/features/project/commits/commits.feature +++ b/features/project/commits/commits.feature @@ -1,4 +1,4 @@ -Feature: Project Browse commits +Feature: Project Commits Background: Given I sign in as a user And I own a project diff --git a/features/project/commits/diff_comments.feature b/features/project/commits/diff_comments.feature index b26019f832f..a145ec84b78 100644 --- a/features/project/commits/diff_comments.feature +++ b/features/project/commits/diff_comments.feature @@ -1,4 +1,4 @@ -Feature: Comments on commit diffs +Feature: Project Commits Diff Comments Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/commits/tags.feature b/features/project/commits/tags.feature index bea463cb786..02f399f7cad 100644 --- a/features/project/commits/tags.feature +++ b/features/project/commits/tags.feature @@ -1,4 +1,4 @@ -Feature: Project Browse tags +Feature: Project Commits Tags Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/commits/user_lookup.feature b/features/project/commits/user_lookup.feature index 7b194ab9206..db51d4a6cfa 100644 --- a/features/project/commits/user_lookup.feature +++ b/features/project/commits/user_lookup.feature @@ -1,4 +1,4 @@ -Feature: Project Browse Commits User Lookup +Feature: Project Commits User Lookup Background: Given I sign in as a user And I own a project diff --git a/features/project/create.feature b/features/project/create.feature index bb8e3a368ed..e9dc4fe6b3c 100644 --- a/features/project/create.feature +++ b/features/project/create.feature @@ -1,4 +1,4 @@ -Feature: Create Project +Feature: Project Create In order to get access to project sections A user with ability to create a project Should be able to create a new one diff --git a/features/project/fork.feature b/features/project/fork.feature index dc477ca3bf3..d3d1180db04 100644 --- a/features/project/fork.feature +++ b/features/project/fork.feature @@ -1,4 +1,4 @@ -Feature: Fork Project +Feature: Project Fork Background: Given I sign in as a user And I am a member of project "Shop" diff --git a/features/project/issues/filter_labels.feature b/features/project/issues/filter_labels.feature index f4a0a7977cc..2c69a78a749 100644 --- a/features/project/issues/filter_labels.feature +++ b/features/project/issues/filter_labels.feature @@ -1,4 +1,4 @@ -Feature: Project Filter Labels +Feature: Project Issues Filter Labels Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/issues/labels.feature b/features/project/issues/labels.feature index a9fe1595fc5..039a7d83cb1 100644 --- a/features/project/issues/labels.feature +++ b/features/project/issues/labels.feature @@ -1,4 +1,4 @@ -Feature: Project Labels +Feature: Project Issues Labels Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/issues/milestones.feature b/features/project/issues/milestones.feature index e67b5d2d860..9ac65b1257c 100644 --- a/features/project/issues/milestones.feature +++ b/features/project/issues/milestones.feature @@ -1,4 +1,4 @@ -Feature: Project Milestones +Feature: Project Issues Milestones Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/network.feature b/features/project/network.feature deleted file mode 100644 index 8beb6043aff..00000000000 --- a/features/project/network.feature +++ /dev/null @@ -1,40 +0,0 @@ -Feature: Project Network Graph - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project "Shop" network page - - @javascript - Scenario: I should see project network - Then page should have network graph - And page should select "master" in select box - And page should have "master" on graph - - @javascript - Scenario: I should switch "branch" and "tag" - When I switch ref to "feature" - Then page should select "feature" in select box - And page should have "feature" on graph - When I switch ref to "v1.0.0" - Then page should select "v1.0.0" in select box - And page should have "v1.0.0" on graph - - @javascript - Scenario: I should looking for a commit by SHA - When I looking for a commit by SHA of "v1.0.0" - Then page should have network graph - And page should select "master" in select box - And page should have "v1.0.0" on graph - - @javascript - Scenario: I should filter selected tag - When I switch ref to "v1.0.0" - Then page should have content not containing "v1.0.0" - When click "Show only selected branch" checkbox - Then page should not have content not containing "v1.0.0" - When click "Show only selected branch" checkbox - Then page should have content not containing "v1.0.0" - - Scenario: I should fail to look for a commit - When I look for a commit by ";" - Then page status code should be 404 diff --git a/features/project/network_graph.feature b/features/project/network_graph.feature new file mode 100644 index 00000000000..8beb6043aff --- /dev/null +++ b/features/project/network_graph.feature @@ -0,0 +1,40 @@ +Feature: Project Network Graph + Background: + Given I sign in as a user + And I own project "Shop" + And I visit project "Shop" network page + + @javascript + Scenario: I should see project network + Then page should have network graph + And page should select "master" in select box + And page should have "master" on graph + + @javascript + Scenario: I should switch "branch" and "tag" + When I switch ref to "feature" + Then page should select "feature" in select box + And page should have "feature" on graph + When I switch ref to "v1.0.0" + Then page should select "v1.0.0" in select box + And page should have "v1.0.0" on graph + + @javascript + Scenario: I should looking for a commit by SHA + When I looking for a commit by SHA of "v1.0.0" + Then page should have network graph + And page should select "master" in select box + And page should have "v1.0.0" on graph + + @javascript + Scenario: I should filter selected tag + When I switch ref to "v1.0.0" + Then page should have content not containing "v1.0.0" + When click "Show only selected branch" checkbox + Then page should not have content not containing "v1.0.0" + When click "Show only selected branch" checkbox + Then page should have content not containing "v1.0.0" + + Scenario: I should fail to look for a commit + When I look for a commit by ";" + Then page status code should be 404 diff --git a/features/project/project.feature b/features/project/project.feature index 47e9600c051..7bb24e013a9 100644 --- a/features/project/project.feature +++ b/features/project/project.feature @@ -1,4 +1,4 @@ -Feature: Project Feature +Feature: Project Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature index e5f9c103fb1..cfb68bf1f50 100644 --- a/features/project/shortcuts.feature +++ b/features/project/shortcuts.feature @@ -1,5 +1,5 @@ @dashboard -Feature: Project shortcuts +Feature: Project Shortcuts Background: Given I sign in as a user And I own a project diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index 1cd3a91667f..20ef7ac5702 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -1,4 +1,4 @@ -Feature: Project Browse files +Feature: Project Source Browse files Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/source/git_blame.feature b/features/project/source/git_blame.feature index cb993ffc639..48b1077dc6b 100644 --- a/features/project/source/git_blame.feature +++ b/features/project/source/git_blame.feature @@ -1,4 +1,4 @@ -Feature: Project Browse git repo +Feature: Project Source Git Blame Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/source/markdown_render.feature b/features/project/source/markdown_render.feature index fce351317c6..ecbd721c281 100644 --- a/features/project/source/markdown_render.feature +++ b/features/project/source/markdown_render.feature @@ -1,4 +1,4 @@ -Feature: Project markdown render +Feature: Project Source Markdown Render Background: Given I sign in as a user And I own project "Delta" diff --git a/features/project/source/multiselect_blob.feature b/features/project/source/multiselect_blob.feature index f60b646a8d9..63b7cb77a93 100644 --- a/features/project/source/multiselect_blob.feature +++ b/features/project/source/multiselect_blob.feature @@ -1,4 +1,4 @@ -Feature: Project Multiselect Blob +Feature: Project Source Multiselect Blob Background: Given I sign in as a user And I own project "Shop" diff --git a/features/project/source/search_code.feature b/features/project/source/search_code.feature index 93b326696d0..4f9dcea249f 100644 --- a/features/project/source/search_code.feature +++ b/features/project/source/search_code.feature @@ -1,4 +1,4 @@ -Feature: Project Search code +Feature: Project Source Search Code Background: Given I sign in as a user diff --git a/features/project/team_management.feature b/features/project/team_management.feature index e153978e043..86ea6cd6e91 100644 --- a/features/project/team_management.feature +++ b/features/project/team_management.feature @@ -1,4 +1,4 @@ -Feature: Project Team management +Feature: Project Team Management Background: Given I sign in as a user And I own project "Shop" diff --git a/features/snippets/discover.feature b/features/snippets/discover.feature index f0b8d3a408a..5094062c8c3 100644 --- a/features/snippets/discover.feature +++ b/features/snippets/discover.feature @@ -1,5 +1,5 @@ @snippets -Feature: Discover Snippets +Feature: Snippets Discover Background: Given I sign in as a user And I have public "Personal snippet one" snippet diff --git a/features/snippets/snippets.feature b/features/snippets/snippets.feature index 38216dd5b7b..4c4e3ee2cff 100644 --- a/features/snippets/snippets.feature +++ b/features/snippets/snippets.feature @@ -1,5 +1,5 @@ @snippets -Feature: Snippets Feature +Feature: Snippets Background: Given I sign in as a user And I have public "Personal snippet one" snippet diff --git a/features/snippets/user.feature b/features/snippets/user.feature index d032a33686b..424794f73fd 100644 --- a/features/snippets/user.feature +++ b/features/snippets/user.feature @@ -1,5 +1,5 @@ @snippets -Feature: User Snippets +Feature: Snippets User Background: Given I sign in as a user And I have public "Personal snippet one" snippet diff --git a/features/steps/dashboard/archived_projects.rb b/features/steps/dashboard/archived_projects.rb new file mode 100644 index 00000000000..969baf92287 --- /dev/null +++ b/features/steps/dashboard/archived_projects.rb @@ -0,0 +1,22 @@ +class Spinach::Features::DashboardArchivedProjects < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedProject + + When 'project "Forum" is archived' do + project = Project.find_by(name: "Forum") + project.update_attribute(:archived, true) + end + + step 'I should see "Shop" project link' do + page.should have_link "Shop" + end + + step 'I should not see "Forum" project link' do + page.should_not have_link "Forum" + end + + step 'I should see "Forum" project link' do + page.should have_link "Forum" + end +end diff --git a/features/steps/dashboard/help.rb b/features/steps/dashboard/help.rb new file mode 100644 index 00000000000..ef433c57c6e --- /dev/null +++ b/features/steps/dashboard/help.rb @@ -0,0 +1,21 @@ +class Spinach::Features::DashboardHelp < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedMarkdown + + step 'I visit the help page' do + visit help_path + end + + step 'I visit the "Rake Tasks" help page' do + visit help_page_path("raketasks", "maintenance") + 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" + end + + step 'Header "Rebuild project satellites" should have correct ids and links' do + header_should_have_correct_id_and_link(2, '(Re-)Create satellite repositories', 're-create-satellite-repositories', '.documentation') + end +end diff --git a/features/steps/dashboard/with_archived_projects.rb b/features/steps/dashboard/with_archived_projects.rb deleted file mode 100644 index 256629382a7..00000000000 --- a/features/steps/dashboard/with_archived_projects.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Spinach::Features::DashboardWithArchivedProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - When 'project "Forum" is archived' do - project = Project.find_by(name: "Forum") - project.update_attribute(:archived, true) - end - - step 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - step 'I should not see "Forum" project link' do - page.should_not have_link "Forum" - end - - step 'I should see "Forum" project link' do - page.should have_link "Forum" - end -end diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb new file mode 100644 index 00000000000..ccbf6cda07e --- /dev/null +++ b/features/steps/explore/groups.rb @@ -0,0 +1,92 @@ +class Spinach::Features::ExploreGroups < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedGroup + include SharedProject + + step 'group "TestGroup" has private project "Enterprise"' do + group_has_project("TestGroup", "Enterprise", Gitlab::VisibilityLevel::PRIVATE) + end + + step 'group "TestGroup" has internal project "Internal"' do + group_has_project("TestGroup", "Internal", Gitlab::VisibilityLevel::INTERNAL) + end + + step 'group "TestGroup" has public project "Community"' do + group_has_project("TestGroup", "Community", Gitlab::VisibilityLevel::PUBLIC) + end + + step '"John Doe" is owner of group "TestGroup"' do + group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup") + user = create(:user, name: "John Doe") + group.add_user(user, Gitlab::Access::OWNER) + end + + step 'I visit group "TestGroup" page' do + visit group_path(Group.find_by(name: "TestGroup")) + end + + step 'I visit group "TestGroup" issues page' do + visit issues_group_path(Group.find_by(name: "TestGroup")) + end + + step 'I visit group "TestGroup" merge requests page' do + visit merge_requests_group_path(Group.find_by(name: "TestGroup")) + end + + step 'I visit group "TestGroup" members page' do + visit members_group_path(Group.find_by(name: "TestGroup")) + end + + step 'I should not see project "Enterprise" items' do + page.should_not have_content "Enterprise" + end + + step 'I should see project "Internal" items' do + page.should have_content "Internal" + end + + step 'I should not see project "Internal" items' do + page.should_not have_content "Internal" + end + + step 'I should see project "Community" items' do + page.should have_content "Community" + end + + step 'I change filter to Everyone\'s' do + click_link "Everyone's" + end + + step 'I should see group member "John Doe"' do + page.should have_content "John Doe" + end + + step 'I should not see member roles' do + body.should_not match(%r{owner|developer|reporter|guest}i) + end + + protected + + def group_has_project(groupname, projectname, visibility_level) + group = Group.find_by(name: groupname) || create(:group, name: groupname) + project = create(:project, + namespace: group, + name: projectname, + path: "#{groupname}-#{projectname}", + visibility_level: visibility_level + ) + create(:issue, + title: "#{projectname} feature", + project: project + ) + create(:merge_request, + title: "#{projectname} feature implemented", + source_project: project, + target_project: project + ) + create(:closed_issue_event, + project: project + ) + end +end diff --git a/features/steps/explore/groups_feature.rb b/features/steps/explore/groups_feature.rb deleted file mode 100644 index 94c918d932b..00000000000 --- a/features/steps/explore/groups_feature.rb +++ /dev/null @@ -1,92 +0,0 @@ -class Spinach::Features::ExploreGroupsFeature < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedGroup - include SharedProject - - step 'group "TestGroup" has private project "Enterprise"' do - group_has_project("TestGroup", "Enterprise", Gitlab::VisibilityLevel::PRIVATE) - end - - step 'group "TestGroup" has internal project "Internal"' do - group_has_project("TestGroup", "Internal", Gitlab::VisibilityLevel::INTERNAL) - end - - step 'group "TestGroup" has public project "Community"' do - group_has_project("TestGroup", "Community", Gitlab::VisibilityLevel::PUBLIC) - end - - step '"John Doe" is owner of group "TestGroup"' do - group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup") - user = create(:user, name: "John Doe") - group.add_user(user, Gitlab::Access::OWNER) - end - - step 'I visit group "TestGroup" page' do - visit group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" issues page' do - visit issues_group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" merge requests page' do - visit merge_requests_group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" members page' do - visit members_group_path(Group.find_by(name: "TestGroup")) - end - - step 'I should not see project "Enterprise" items' do - page.should_not have_content "Enterprise" - end - - step 'I should see project "Internal" items' do - page.should have_content "Internal" - end - - step 'I should not see project "Internal" items' do - page.should_not have_content "Internal" - end - - step 'I should see project "Community" items' do - page.should have_content "Community" - end - - step 'I change filter to Everyone\'s' do - click_link "Everyone's" - end - - step 'I should see group member "John Doe"' do - page.should have_content "John Doe" - end - - step 'I should not see member roles' do - body.should_not match(%r{owner|developer|reporter|guest}i) - end - - protected - - def group_has_project(groupname, projectname, visibility_level) - group = Group.find_by(name: groupname) || create(:group, name: groupname) - project = create(:project, - namespace: group, - name: projectname, - path: "#{groupname}-#{projectname}", - visibility_level: visibility_level - ) - create(:issue, - title: "#{projectname} feature", - project: project - ) - create(:merge_request, - title: "#{projectname} feature implemented", - source_project: project, - target_project: project - ) - create(:closed_issue_event, - project: project - ) - end -end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 7248b2e8d8c..8172f7922cc 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -1,4 +1,4 @@ -class Spinach::Features::ExploreProjectsFeature < Spinach::FeatureSteps +class Spinach::Features::ExploreProjects < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject diff --git a/features/steps/group.rb b/features/steps/group.rb deleted file mode 100644 index 616a297db99..00000000000 --- a/features/steps/group.rb +++ /dev/null @@ -1,277 +0,0 @@ -class Spinach::Features::Groups < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedGroup - include SharedUser - include Select2Helper - - step 'I should see group "Owned" projects list' do - Group.find_by(name: "Owned").projects.each do |project| - page.should have_link project.name - end - end - - step 'I should see projects activity feed' do - page.should 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 - 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] - end - end - - 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_link 'Add members' - within ".users-group-form" do - select2(user.id, from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - click_button "Add users into group" - end - - 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") - 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") - 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") - 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") - end - - step 'project from group "Owned" has issues assigned to me' do - create :issue, - project: project, - assignee: current_user, - author: current_user - end - - step 'project from group "Owned" has merge requests assigned to me' do - create :merge_request, - source_project: project, - target_project: project, - assignee: current_user, - author: current_user - end - - When 'I click new group link' do - click_link "New group" - end - - step 'submit form with new group "Samurai" info' do - fill_in 'group_name', with: 'Samurai' - fill_in 'group_description', with: 'Tokugawa Shogunate' - click_button "Create group" - end - - step 'I should be redirected to group "Samurai" page' do - current_path.should == group_path(Group.last) - end - - step 'I should see newly created group "Samurai"' do - page.should have_content "Samurai" - page.should have_content "Tokugawa Shogunate" - page.should have_content "Currently you are only seeing events from the" - end - - step 'I change group "Owned" name to "new-name"' do - fill_in 'group_name', with: 'new-name' - click_button "Save group" - end - - step 'I should see new group "Owned" name' do - within ".navbar-gitlab" do - page.should have_content "group: new-name" - end - end - - step 'I change group "Owned" avatar' do - attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save group" - Group.find_by(name: "Owned").reload - end - - step 'I should see new group "Owned" avatar' do - Group.find_by(name: "Owned").avatar.should be_instance_of AttachmentUploader - Group.find_by(name: "Owned").avatar.url.should == "/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") - end - - step 'I have group "Owned" avatar' do - attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save group" - Group.find_by(name: "Owned").reload - end - - step 'I remove group "Owned" avatar' do - click_link "Remove avatar" - Group.find_by(name: "Owned").reload - end - - step 'I should not see group "Owned" avatar' do - Group.find_by(name: "Owned").avatar?.should be_false - end - - step 'I should not see the "Remove avatar" button' do - page.should_not have_link("Remove avatar") - end - - step 'I click on the "Remove User From Group" button for "John Doe"' do - find(:css, 'li', text: "John Doe").find(:css, 'a.btn-remove').click - # poltergeist always confirms popups. - end - - step 'I click on the "Remove User From Group" button for "Mary Jane"' do - find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click - # poltergeist always confirms popups. - 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') - # 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') - # poltergeist always confirms popups. - end - - step 'I search for \'Mary\' member' do - within '.member-search-form' do - fill_in 'search', with: 'Mary' - click_button 'Search' - end - end - - step 'I click on group milestones' do - click_link 'Milestones' - end - - step 'I should see group milestones index page has no milestones' do - page.should have_content('No milestones to show') - end - - step 'Group has projects with milestones' do - group_milestone - 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: group_milestone_path("owned", "version-7-2", title: "Version 7.2")) - page.should have_link('3 Merge Requests', href: group_milestone_path("owned", "gl-113", title: "GL-113")) - end - - step 'I click on one group milestone' do - click_link 'GL-113' - end - - step 'I should see group milestone with descriptions and expiry date' do - page.should have_content('Lorem Ipsum is simply dummy text of the printing and typesetting industry') - page.should 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: project_issue_path(@project1, @issue1)) - page.should have_link(@mr3.title, href: project_merge_request_path(@project3, @mr3)) - end - - protected - - def assigned_to_me(key) - project.send(key).where(assignee_id: current_user.id) - end - - def project - Group.find_by(name: "Owned").projects.first - end - - def group_milestone - group = Group.find_by(name: "Owned") - - @project1 = create :project, - group: group - project2 = create :project, - path: 'gitlab-ci', - group: group - @project3 = create :project, - path: 'cookbook-gitlab', - group: group - milestone1_project1 = create :milestone, - title: "Version 7.2", - project: @project1 - milestone1_project2 = create :milestone, - title: "Version 7.2", - project: project2 - milestone1_project3 = create :milestone, - title: "Version 7.2", - project: @project3 - milestone2_project1 = create :milestone, - title: "GL-113", - project: @project1 - milestone2_project2 = create :milestone, - title: "GL-113", - project: project2 - milestone2_project3 = create :milestone, - title: "GL-113", - project: @project3, - due_date: '2114-08-20', - description: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry' - @issue1 = create :issue, - project: @project1, - assignee: current_user, - author: current_user, - milestone: milestone2_project1 - issue2 = create :issue, - project: project2, - assignee: current_user, - author: current_user, - milestone: milestone1_project2 - issue3 = create :issue, - project: @project3, - assignee: current_user, - author: current_user, - milestone: milestone1_project1 - mr1 = create :merge_request, - source_project: @project1, - target_project: @project1, - assignee: current_user, - author: current_user, - milestone: milestone2_project1 - mr2 = create :merge_request, - source_project: project2, - target_project: project2, - assignee: current_user, - author: current_user, - milestone: milestone2_project2 - @mr3 = create :merge_request, - source_project: @project3, - target_project: @project3, - assignee: current_user, - author: current_user, - milestone: milestone2_project3 - end -end diff --git a/features/steps/groups.rb b/features/steps/groups.rb new file mode 100644 index 00000000000..616a297db99 --- /dev/null +++ b/features/steps/groups.rb @@ -0,0 +1,277 @@ +class Spinach::Features::Groups < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedGroup + include SharedUser + include Select2Helper + + step 'I should see group "Owned" projects list' do + Group.find_by(name: "Owned").projects.each do |project| + page.should have_link project.name + end + end + + step 'I should see projects activity feed' do + page.should 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 + 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] + end + end + + 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_link 'Add members' + within ".users-group-form" do + select2(user.id, from: "#user_ids", multiple: true) + select "Reporter", from: "access_level" + end + click_button "Add users into group" + end + + 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") + 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") + 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") + 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") + end + + step 'project from group "Owned" has issues assigned to me' do + create :issue, + project: project, + assignee: current_user, + author: current_user + end + + step 'project from group "Owned" has merge requests assigned to me' do + create :merge_request, + source_project: project, + target_project: project, + assignee: current_user, + author: current_user + end + + When 'I click new group link' do + click_link "New group" + end + + step 'submit form with new group "Samurai" info' do + fill_in 'group_name', with: 'Samurai' + fill_in 'group_description', with: 'Tokugawa Shogunate' + click_button "Create group" + end + + step 'I should be redirected to group "Samurai" page' do + current_path.should == group_path(Group.last) + end + + step 'I should see newly created group "Samurai"' do + page.should have_content "Samurai" + page.should have_content "Tokugawa Shogunate" + page.should have_content "Currently you are only seeing events from the" + end + + step 'I change group "Owned" name to "new-name"' do + fill_in 'group_name', with: 'new-name' + click_button "Save group" + end + + step 'I should see new group "Owned" name' do + within ".navbar-gitlab" do + page.should have_content "group: new-name" + end + end + + step 'I change group "Owned" avatar' do + attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) + click_button "Save group" + Group.find_by(name: "Owned").reload + end + + step 'I should see new group "Owned" avatar' do + Group.find_by(name: "Owned").avatar.should be_instance_of AttachmentUploader + Group.find_by(name: "Owned").avatar.url.should == "/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") + end + + step 'I have group "Owned" avatar' do + attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) + click_button "Save group" + Group.find_by(name: "Owned").reload + end + + step 'I remove group "Owned" avatar' do + click_link "Remove avatar" + Group.find_by(name: "Owned").reload + end + + step 'I should not see group "Owned" avatar' do + Group.find_by(name: "Owned").avatar?.should be_false + end + + step 'I should not see the "Remove avatar" button' do + page.should_not have_link("Remove avatar") + end + + step 'I click on the "Remove User From Group" button for "John Doe"' do + find(:css, 'li', text: "John Doe").find(:css, 'a.btn-remove').click + # poltergeist always confirms popups. + end + + step 'I click on the "Remove User From Group" button for "Mary Jane"' do + find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click + # poltergeist always confirms popups. + 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') + # 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') + # poltergeist always confirms popups. + end + + step 'I search for \'Mary\' member' do + within '.member-search-form' do + fill_in 'search', with: 'Mary' + click_button 'Search' + end + end + + step 'I click on group milestones' do + click_link 'Milestones' + end + + step 'I should see group milestones index page has no milestones' do + page.should have_content('No milestones to show') + end + + step 'Group has projects with milestones' do + group_milestone + 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: group_milestone_path("owned", "version-7-2", title: "Version 7.2")) + page.should have_link('3 Merge Requests', href: group_milestone_path("owned", "gl-113", title: "GL-113")) + end + + step 'I click on one group milestone' do + click_link 'GL-113' + end + + step 'I should see group milestone with descriptions and expiry date' do + page.should have_content('Lorem Ipsum is simply dummy text of the printing and typesetting industry') + page.should 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: project_issue_path(@project1, @issue1)) + page.should have_link(@mr3.title, href: project_merge_request_path(@project3, @mr3)) + end + + protected + + def assigned_to_me(key) + project.send(key).where(assignee_id: current_user.id) + end + + def project + Group.find_by(name: "Owned").projects.first + end + + def group_milestone + group = Group.find_by(name: "Owned") + + @project1 = create :project, + group: group + project2 = create :project, + path: 'gitlab-ci', + group: group + @project3 = create :project, + path: 'cookbook-gitlab', + group: group + milestone1_project1 = create :milestone, + title: "Version 7.2", + project: @project1 + milestone1_project2 = create :milestone, + title: "Version 7.2", + project: project2 + milestone1_project3 = create :milestone, + title: "Version 7.2", + project: @project3 + milestone2_project1 = create :milestone, + title: "GL-113", + project: @project1 + milestone2_project2 = create :milestone, + title: "GL-113", + project: project2 + milestone2_project3 = create :milestone, + title: "GL-113", + project: @project3, + due_date: '2114-08-20', + description: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry' + @issue1 = create :issue, + project: @project1, + assignee: current_user, + author: current_user, + milestone: milestone2_project1 + issue2 = create :issue, + project: project2, + assignee: current_user, + author: current_user, + milestone: milestone1_project2 + issue3 = create :issue, + project: @project3, + assignee: current_user, + author: current_user, + milestone: milestone1_project1 + mr1 = create :merge_request, + source_project: @project1, + target_project: @project1, + assignee: current_user, + author: current_user, + milestone: milestone2_project1 + mr2 = create :merge_request, + source_project: project2, + target_project: project2, + assignee: current_user, + author: current_user, + milestone: milestone2_project2 + @mr3 = create :merge_request, + source_project: @project3, + target_project: @project3, + assignee: current_user, + author: current_user, + milestone: milestone2_project3 + end +end diff --git a/features/steps/help.rb b/features/steps/help.rb deleted file mode 100644 index 0d1c9c00376..00000000000 --- a/features/steps/help.rb +++ /dev/null @@ -1,21 +0,0 @@ -class Spinach::Features::Help < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedMarkdown - - step 'I visit the help page' do - visit help_path - end - - step 'I visit the "Rake Tasks" help page' do - visit help_page_path("raketasks", "maintenance") - 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" - end - - step 'Header "Rebuild project satellites" should have correct ids and links' do - header_should_have_correct_id_and_link(2, '(Re-)Create satellite repositories', 're-create-satellite-repositories', '.documentation') - end -end diff --git a/features/steps/project/browse_branches.rb b/features/steps/project/browse_branches.rb deleted file mode 100644 index 3b1e51f179a..00000000000 --- a/features/steps/project/browse_branches.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Spinach::Features::ProjectBrowseBranches < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click link "All"' do - click_link "All" - end - - step 'I should see "Shop" all branches list' do - page.should have_content "Branches" - page.should have_content "master" - end - - step 'I click link "Protected"' do - click_link "Protected" - end - - 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" - end - end - - step 'project "Shop" has protected branches' do - project = Project.find_by(name: "Shop") - project.protected_branches.create(name: "stable") - end - - step 'I click new branch link' do - click_link "New branch" - end - - step 'I submit new branch form' do - fill_in 'branch_name', with: 'deploy_keys' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I submit new branch form with invalid name' do - fill_in 'branch_name', with: '1.0 stable' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I submit new branch form with invalid reference' do - fill_in 'branch_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create branch' - end - - step 'I submit new branch form with branch that already exists' do - fill_in 'branch_name', with: 'master' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I should see new branch created' do - page.should have_content 'deploy_keys' - end - - step 'I should see new an error that branch is invalid' do - page.should 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' - end - - step 'I should see new an error that branch already exists' do - page.should have_content 'Branch already exists' - end - - step "I click branch 'improve/awesome' delete link" do - within '.js-branch-improve\/awesome' do - find('.btn-remove').click - sleep 0.05 - end - end - - step "I should not see branch 'improve/awesome'" do - all(visible: true).should_not have_content 'improve/awesome' - end -end diff --git a/features/steps/project/browse_commits.rb b/features/steps/project/browse_commits.rb deleted file mode 100644 index 2048818e88c..00000000000 --- a/features/steps/project/browse_commits.rb +++ /dev/null @@ -1,91 +0,0 @@ -class Spinach::Features::ProjectBrowseCommits < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include RepoHelpers - - 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.id.to_s[0..5]) - end - - step 'I click atom feed link' do - click_link "Feed" - end - - 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: "Recent commits to #{@project.name}") - body.should have_selector("author email", text: commit.author_email) - body.should have_selector("entry summary", text: commit.description[0..10]) - end - - step 'I click on commit link' do - visit project_commit_path(@project, sample_commit.id) - 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" - end - - step 'I fill compare fields with refs' do - fill_in "from", with: sample_commit.parent_id - fill_in "to", with: sample_commit.id - click_button "Compare" - 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" - end - - step 'I see breadcrumb links' do - page.should have_selector('ul.breadcrumb') - page.should 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' - end - - step 'I visit big commit page' do - Commit::DIFF_SAFE_FILES = 20 - visit project_commit_path(@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 - visit project_commit_path(@project, sample_image_commit.id) - end - - 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}} - end - - step 'I click side-by-side diff button' do - click_link "Side-by-side Diff" - end - - step 'I see side-by-side diff button' do - page.should have_content "Side-by-side Diff" - end - - step 'I see inline diff button' do - page.should have_content "Inline Diff" - end -end diff --git a/features/steps/project/browse_commits_user_lookup.rb b/features/steps/project/browse_commits_user_lookup.rb deleted file mode 100644 index 196c69eda65..00000000000 --- a/features/steps/project/browse_commits_user_lookup.rb +++ /dev/null @@ -1,48 +0,0 @@ -class Spinach::Features::ProjectBrowseCommitsUserLookup < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click on commit link' do - visit project_commit_path(@project, sample_commit.id) - end - - step 'I click on another commit link' do - visit project_commit_path(@project, sample_commit.parent_id) - end - - step 'I have user with primary email' do - user_primary - end - - step 'I have user with secondary email' do - user_secondary - end - - step 'I see author based on primary email' do - check_author_link(sample_commit.author_email, user_primary) - end - - step 'I see author based on secondary email' do - check_author_link(sample_commit.author_email, user_secondary) - end - - 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 - end - - def user_primary - @user_primary ||= create(:user, email: 'dmitriy.zaporozhets@gmail.com') - end - - def user_secondary - @user_secondary ||= begin - user = create(:user, email: 'dzaporozhets@example.com') - create(:email, { user: user, email: 'dmitriy.zaporozhets@gmail.com' }) - user - end - end -end diff --git a/features/steps/project/browse_files.rb b/features/steps/project/browse_files.rb deleted file mode 100644 index 4310f519032..00000000000 --- a/features/steps/project/browse_files.rb +++ /dev/null @@ -1,176 +0,0 @@ -class Spinach::Features::ProjectBrowseFiles < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - 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" - end - - step 'I should see files from repository for "6d39438"' do - current_path.should == project_tree_path(@project, "6d39438") - page.should have_content ".gitignore" - page.should have_content "LICENSE" - end - - step 'I see the ".gitignore"' do - page.should have_content '.gitignore' - end - - step 'I don\'t see the ".gitignore"' do - page.should_not have_content '.gitignore' - end - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end - - step 'I should see its content' do - page.should have_content old_gitignore_content - end - - step 'I should see its new content' do - page.should have_content new_gitignore_content - end - - step 'I click link "Raw"' do - click_link 'Raw' - end - - step 'I should see raw file content' do - source.should == sample_blob.data - end - - step 'I click button "Edit"' do - click_link 'Edit' - end - - step 'I can edit code' do - set_new_content - evaluate_script('editor.getValue()').should == new_gitignore_content - end - - step 'I edit code' do - set_new_content - end - - step 'I fill the new file name' do - fill_in :file_name, with: new_file_name - end - - step 'I fill the commit message' do - fill_in :commit_message, with: 'Not yet a commit message.' - end - - step 'I click link "Diff"' do - click_link 'Diff' - end - - step 'I click on "Commit changes"' do - click_button 'Commit changes' - end - - step 'I click on "Remove"' do - click_link 'Remove' - end - - step 'I click on "Remove file"' do - click_button 'Remove file' - end - - step 'I see diff' do - page.should have_css '.line_holder.new' - end - - step 'I click on "new file" link in repo' do - click_link 'new-file-link' - end - - step 'I can see new file page' do - page.should have_content "New file" - page.should have_content "File name" - page.should have_content "Commit message" - end - - step 'I click on files directory' do - click_link 'files' - end - - step 'I click on History link' do - click_link 'History' - end - - step 'I see Browse dir link' do - page.should have_link 'Browse Dir »' - page.should_not have_link 'Browse Code »' - end - - step 'I click on readme file' do - within '.tree-table' do - click_link 'README.md' - end - end - - step 'I see Browse file link' do - page.should have_link 'Browse File »' - page.should_not 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 »' - end - - step 'I click on Permalink' do - click_link 'Permalink' - end - - step 'I am redirected to the files URL' do - current_path.should == project_tree_path(@project, 'master') - end - - step 'I am redirected to the ".gitignore"' do - expect(current_path).to eq(project_blob_path(@project, 'master/.gitignore')) - end - - step 'I am redirected to the permalink URL' do - expect(current_path).to eq(project_blob_path( - @project, @project.repository.commit.sha + '/.gitignore')) - end - - step 'I am redirected to the new file' do - expect(current_path).to eq(project_blob_path( - @project, 'master/' + new_file_name)) - end - - step "I don't see the permalink link" do - expect(page).not_to have_link('permalink') - end - - private - - def set_new_content - execute_script("editor.setValue('#{new_gitignore_content}')") - end - - # Content of the gitignore file on the seed repository. - def old_gitignore_content - '*.rbc' - end - - # Constant value that differs from the content - # of the gitignore of the seed repository. - def new_gitignore_content - old_gitignore_content + 'a' - end - - # Constant value that is a valid filename and - # not a filename present at root of the seed repository. - def new_file_name - 'not_a_file.md' - end -end diff --git a/features/steps/project/browse_git_repo.rb b/features/steps/project/browse_git_repo.rb deleted file mode 100644 index d8703aadb81..00000000000 --- a/features/steps/project/browse_git_repo.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Spinach::Features::ProjectBrowseGitRepo < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end - - step 'I click Blame button' do - click_link 'Blame' - 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" - end -end diff --git a/features/steps/project/browse_tags.rb b/features/steps/project/browse_tags.rb deleted file mode 100644 index 722c0a91076..00000000000 --- a/features/steps/project/browse_tags.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Spinach::Features::ProjectBrowseTags < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see "Shop" all tags list' do - page.should have_content "Tags" - page.should have_content "v1.0.0" - end - - step 'I click new tag link' do - click_link 'New tag' - end - - step 'I submit new tag form' do - fill_in 'tag_name', with: 'v7.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid name' do - fill_in 'tag_name', with: 'v 1.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid reference' do - fill_in 'tag_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create tag' - end - - step 'I submit new tag form with tag that already exists' do - fill_in 'tag_name', with: 'v1.0.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I should see new tag created' do - page.should have_content 'v7.0' - end - - step 'I should see new an error that tag is invalid' do - page.should 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' - end - - step 'I should see new an error that tag already exists' do - page.should have_content 'Tag already exists' - end - - step "I delete tag 'v1.1.0'" do - 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 - all(visible: true).should_not have_content 'v1.1.0' - end - end - - step 'I delete all tags' do - within '.tags' do - all('.btn-remove').each do |remove| - remove.click - sleep 0.05 - end - end - end - - step 'I should see tags info message' do - within '.tags' do - page.should have_content 'Repository has no tags yet.' - end - end -end diff --git a/features/steps/project/comments_on_commit_diffs.rb b/features/steps/project/comments_on_commit_diffs.rb deleted file mode 100644 index 50b978a5d23..00000000000 --- a/features/steps/project/comments_on_commit_diffs.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Spinach::Features::CommentsOnCommitDiffs < Spinach::FeatureSteps - include SharedAuthentication - include SharedDiffNote - include SharedPaths - include SharedProject -end diff --git a/features/steps/project/comments_on_commits.rb b/features/steps/project/comments_on_commits.rb deleted file mode 100644 index 03e6867c7b1..00000000000 --- a/features/steps/project/comments_on_commits.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Spinach::Features::CommentsOnCommits < Spinach::FeatureSteps - include SharedAuthentication - include SharedNote - include SharedPaths - include SharedProject -end diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb new file mode 100644 index 00000000000..07f7e5796a3 --- /dev/null +++ b/features/steps/project/commits/branches.rb @@ -0,0 +1,85 @@ +class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I click link "All"' do + click_link "All" + end + + step 'I should see "Shop" all branches list' do + page.should have_content "Branches" + page.should have_content "master" + end + + step 'I click link "Protected"' do + click_link "Protected" + end + + 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" + end + end + + step 'project "Shop" has protected branches' do + project = Project.find_by(name: "Shop") + project.protected_branches.create(name: "stable") + end + + step 'I click new branch link' do + click_link "New branch" + end + + step 'I submit new branch form' do + fill_in 'branch_name', with: 'deploy_keys' + fill_in 'ref', with: 'master' + click_button 'Create branch' + end + + step 'I submit new branch form with invalid name' do + fill_in 'branch_name', with: '1.0 stable' + fill_in 'ref', with: 'master' + click_button 'Create branch' + end + + step 'I submit new branch form with invalid reference' do + fill_in 'branch_name', with: 'foo' + fill_in 'ref', with: 'foo' + click_button 'Create branch' + end + + step 'I submit new branch form with branch that already exists' do + fill_in 'branch_name', with: 'master' + fill_in 'ref', with: 'master' + click_button 'Create branch' + end + + step 'I should see new branch created' do + page.should have_content 'deploy_keys' + end + + step 'I should see new an error that branch is invalid' do + page.should 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' + end + + step 'I should see new an error that branch already exists' do + page.should have_content 'Branch already exists' + end + + step "I click branch 'improve/awesome' delete link" do + within '.js-branch-improve\/awesome' do + find('.btn-remove').click + sleep 0.05 + end + end + + step "I should not see branch 'improve/awesome'" do + all(visible: true).should_not have_content 'improve/awesome' + end +end diff --git a/features/steps/project/commits/comments.rb b/features/steps/project/commits/comments.rb new file mode 100644 index 00000000000..3d4d8ad6368 --- /dev/null +++ b/features/steps/project/commits/comments.rb @@ -0,0 +1,6 @@ +class Spinach::Features::ProjectCommitsComments < Spinach::FeatureSteps + include SharedAuthentication + include SharedNote + include SharedPaths + include SharedProject +end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb new file mode 100644 index 00000000000..c054e0e8282 --- /dev/null +++ b/features/steps/project/commits/commits.rb @@ -0,0 +1,91 @@ +class Spinach::Features::ProjectCommits < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include RepoHelpers + + 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.id.to_s[0..5]) + end + + step 'I click atom feed link' do + click_link "Feed" + end + + 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: "Recent commits to #{@project.name}") + body.should have_selector("author email", text: commit.author_email) + body.should have_selector("entry summary", text: commit.description[0..10]) + end + + step 'I click on commit link' do + visit project_commit_path(@project, sample_commit.id) + 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" + end + + step 'I fill compare fields with refs' do + fill_in "from", with: sample_commit.parent_id + fill_in "to", with: sample_commit.id + click_button "Compare" + 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" + end + + step 'I see breadcrumb links' do + page.should have_selector('ul.breadcrumb') + page.should 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' + end + + step 'I visit big commit page' do + Commit::DIFF_SAFE_FILES = 20 + visit project_commit_path(@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 + visit project_commit_path(@project, sample_image_commit.id) + end + + 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}} + end + + step 'I click side-by-side diff button' do + click_link "Side-by-side Diff" + end + + step 'I see side-by-side diff button' do + page.should have_content "Side-by-side Diff" + end + + step 'I see inline diff button' do + page.should have_content "Inline Diff" + end +end diff --git a/features/steps/project/commits/diff_comments.rb b/features/steps/project/commits/diff_comments.rb new file mode 100644 index 00000000000..b9d8cf2c5a5 --- /dev/null +++ b/features/steps/project/commits/diff_comments.rb @@ -0,0 +1,6 @@ +class Spinach::Features::ProjectCommitsDiffComments < Spinach::FeatureSteps + include SharedAuthentication + include SharedDiffNote + include SharedPaths + include SharedProject +end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb new file mode 100644 index 00000000000..3465fcbfd07 --- /dev/null +++ b/features/steps/project/commits/tags.rb @@ -0,0 +1,82 @@ +class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I should see "Shop" all tags list' do + page.should have_content "Tags" + page.should have_content "v1.0.0" + end + + step 'I click new tag link' do + click_link 'New tag' + end + + step 'I submit new tag form' do + fill_in 'tag_name', with: 'v7.0' + fill_in 'ref', with: 'master' + click_button 'Create tag' + end + + step 'I submit new tag form with invalid name' do + fill_in 'tag_name', with: 'v 1.0' + fill_in 'ref', with: 'master' + click_button 'Create tag' + end + + step 'I submit new tag form with invalid reference' do + fill_in 'tag_name', with: 'foo' + fill_in 'ref', with: 'foo' + click_button 'Create tag' + end + + step 'I submit new tag form with tag that already exists' do + fill_in 'tag_name', with: 'v1.0.0' + fill_in 'ref', with: 'master' + click_button 'Create tag' + end + + step 'I should see new tag created' do + page.should have_content 'v7.0' + end + + step 'I should see new an error that tag is invalid' do + page.should 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' + end + + step 'I should see new an error that tag already exists' do + page.should have_content 'Tag already exists' + end + + step "I delete tag 'v1.1.0'" do + 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 + all(visible: true).should_not have_content 'v1.1.0' + end + end + + step 'I delete all tags' do + within '.tags' do + all('.btn-remove').each do |remove| + remove.click + sleep 0.05 + end + end + end + + step 'I should see tags info message' do + within '.tags' do + page.should 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 new file mode 100644 index 00000000000..0622fef43bb --- /dev/null +++ b/features/steps/project/commits/user_lookup.rb @@ -0,0 +1,48 @@ +class Spinach::Features::ProjectCommitsUserLookup < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I click on commit link' do + visit project_commit_path(@project, sample_commit.id) + end + + step 'I click on another commit link' do + visit project_commit_path(@project, sample_commit.parent_id) + end + + step 'I have user with primary email' do + user_primary + end + + step 'I have user with secondary email' do + user_secondary + end + + step 'I see author based on primary email' do + check_author_link(sample_commit.author_email, user_primary) + end + + step 'I see author based on secondary email' do + check_author_link(sample_commit.author_email, user_secondary) + end + + 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 + end + + def user_primary + @user_primary ||= create(:user, email: 'dmitriy.zaporozhets@gmail.com') + end + + def user_secondary + @user_secondary ||= begin + user = create(:user, email: 'dzaporozhets@example.com') + create(:email, { user: user, email: 'dmitriy.zaporozhets@gmail.com' }) + user + end + end +end diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb index bcd2524c205..e1062a6ce39 100644 --- a/features/steps/project/create.rb +++ b/features/steps/project/create.rb @@ -1,4 +1,4 @@ -class Spinach::Features::CreateProject < Spinach::FeatureSteps +class Spinach::Features::ProjectCreate < Spinach::FeatureSteps include SharedAuthentication include SharedPaths diff --git a/features/steps/project/filter_labels.rb b/features/steps/project/filter_labels.rb deleted file mode 100644 index aaa0cfe3379..00000000000 --- a/features/steps/project/filter_labels.rb +++ /dev/null @@ -1,79 +0,0 @@ -class Spinach::Features::ProjectFilterLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see "bug" in labels filter' do - within ".labels-filter" do - page.should have_content "bug" - end - end - - step 'I should see "feature" in labels filter' do - within ".labels-filter" do - page.should have_content "feature" - end - end - - step 'I should see "enhancement" in labels filter' do - within ".labels-filter" do - page.should have_content "enhancement" - end - end - - step 'I should see "Bugfix1" in issues list' do - within ".issues-list" do - page.should have_content "Bugfix1" - end - end - - step 'I should see "Bugfix2" in issues list' do - within ".issues-list" do - page.should 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" - end - end - - step 'I should not see "Feature1" in issues list' do - within ".issues-list" do - page.should_not have_content "Feature1" - end - end - - step 'I click link "bug"' do - within ".labels-filter" do - click_link "bug" - end - end - - step 'I click link "feature"' do - within ".labels-filter" do - click_link "feature" - end - end - - step 'project "Shop" has issue "Bugfix1" with labels: "bug", "feature"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Bugfix1", project: project) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'feature') - end - - step 'project "Shop" has issue "Bugfix2" with labels: "bug", "enhancement"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Bugfix2", project: project) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'enhancement') - end - - step 'project "Shop" has issue "Feature1" with labels: "feature"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Feature1", project: project) - issue.labels << project.labels.find_by(title: 'feature') - end -end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 791c6b1ffb9..da50ba9ced0 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -1,4 +1,4 @@ -class Spinach::Features::ForkProject < Spinach::FeatureSteps +class Spinach::Features::ProjectFork < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject diff --git a/features/steps/project/issues.rb b/features/steps/project/issues.rb deleted file mode 100644 index b55b3c6c8a2..00000000000 --- a/features/steps/project/issues.rb +++ /dev/null @@ -1,236 +0,0 @@ -class Spinach::Features::ProjectIssues < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include SharedMarkdown - - step 'I should see "Release 0.4" in issues' do - page.should 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" - end - - step 'I should not see "Tweet control" in issues' do - page.should_not have_content "Tweet control" - end - - step 'I click link "Closed"' do - click_link "Closed" - end - - step 'I should see "Release 0.3" in issues' do - page.should 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" - end - - step 'I click link "All"' do - click_link "All" - end - - step 'I click link "Release 0.4"' do - click_link "Release 0.4" - end - - step 'I should see issue "Release 0.4"' do - page.should have_content "Release 0.4" - end - - step 'I click link "New Issue"' do - click_link "New Issue" - end - - step 'I submit new issue "500 error on profile"' do - fill_in "issue_title", with: "500 error on profile" - click_button "Submit new issue" - end - - step 'I submit new issue "500 error on profile" with label \'bug\'' do - fill_in "issue_title", with: "500 error on profile" - select 'bug', from: "Labels" - click_button "Submit new issue" - end - - step 'I click link "500 error on profile"' do - click_link "500 error on profile" - end - - step 'I should see label \'bug\' with issue' do - within '.issue-show-labels' do - page.should 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 - end - - step 'I fill in issue search with "Re"' do - filter_issue "Re" - end - - step 'I fill in issue search with "Bu"' do - filter_issue "Bu" - end - - step 'I fill in issue search with ".3"' do - filter_issue ".3" - end - - step 'I fill in issue search with "Something"' do - filter_issue "Something" - end - - step 'I fill in issue search with ""' do - filter_issue "" - end - - step 'project "Shop" has milestone "v2.2"' do - - milestone = create(:milestone, title: "v2.2", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - step 'project "Shop" has milestone "v3.0"' do - - milestone = create(:milestone, title: "v3.0", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - When 'I select milestone "v3.0"' do - select "v3.0", from: "milestone_id" - end - - 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") - end - - When 'I select first assignee from "Shop" project' do - - first_assignee = project.users.first - select first_assignee.name, from: "assignee_id" - end - - step 'I should see first assignee from "Shop" as selected assignee' do - issues_assignee_selector = "#issue_assignee_id_chzn > a" - - assignee_name = project.users.first.name - find(issues_assignee_selector).should have_content(assignee_name) - end - - step 'project "Shop" have "Release 0.4" open issue' do - - create(:issue, - title: "Release 0.4", - project: project, - author: project.users.first, - description: "# Description header" - ) - end - - step 'project "Shop" have "Tweet control" open issue' do - create(:issue, - title: "Tweet control", - project: project, - author: project.users.first) - end - - step 'project "Shop" have "Release 0.3" closed issue' do - create(:closed_issue, - title: "Release 0.3", - project: project, - author: project.users.first) - end - - step 'empty project "Empty Project"' do - create :empty_project, name: 'Empty Project', namespace: @user.namespace - end - - When 'I visit empty project page' do - project = Project.find_by(name: 'Empty Project') - visit project_path(project) - end - - 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) - end - end - - When "I visit empty project's issues page" do - project = Project.find_by(name: 'Empty Project') - visit project_issues_path(project) - end - - step 'I leave a comment with code block' do - 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 - end - end - - step 'The code block should be unchanged' do - page.should 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 - issue = create(:issue, title: 'Bugfix1', description: 'Description for issue1', project: project) - end - - step 'project \'Shop\' has issue \'Feature1\' with description: \'Feature submitted for issue1\'' do - issue = create(:issue, title: 'Feature1', description: 'Feature submitted for issue1', project: project) - end - - step 'I fill in issue search with \'Description for issue1\'' do - filter_issue 'Description for issue' - end - - step 'I fill in issue search with \'issue1\'' do - filter_issue 'issue1' - end - - step 'I fill in issue search with \'Rock and roll\'' do - filter_issue 'Description for issue' - end - - step 'I should see \'Bugfix1\' in issues' do - page.should have_content 'Bugfix1' - end - - step 'I should see \'Feature1\' in issues' do - page.should have_content 'Feature1' - end - - step 'I should not see \'Bugfix1\' in issues' do - page.should_not have_content 'Bugfix1' - end - - step 'issue \'Release 0.4\' has label \'bug\'' do - label = project.labels.create!(name: 'bug', color: '#990000') - issue = Issue.find_by!(title: 'Release 0.4') - issue.labels << label - end - - step 'I click label \'bug\'' do - within ".issues-list" do - click_link 'bug' - end - end - - def filter_issue(text) - fill_in 'issue_search', with: text - end -end diff --git a/features/steps/project/issues/filter_labels.rb b/features/steps/project/issues/filter_labels.rb new file mode 100644 index 00000000000..e62fa9c84c8 --- /dev/null +++ b/features/steps/project/issues/filter_labels.rb @@ -0,0 +1,79 @@ +class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I should see "bug" in labels filter' do + within ".labels-filter" do + page.should have_content "bug" + end + end + + step 'I should see "feature" in labels filter' do + within ".labels-filter" do + page.should have_content "feature" + end + end + + step 'I should see "enhancement" in labels filter' do + within ".labels-filter" do + page.should have_content "enhancement" + end + end + + step 'I should see "Bugfix1" in issues list' do + within ".issues-list" do + page.should have_content "Bugfix1" + end + end + + step 'I should see "Bugfix2" in issues list' do + within ".issues-list" do + page.should 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" + end + end + + step 'I should not see "Feature1" in issues list' do + within ".issues-list" do + page.should_not have_content "Feature1" + end + end + + step 'I click link "bug"' do + within ".labels-filter" do + click_link "bug" + end + end + + step 'I click link "feature"' do + within ".labels-filter" do + click_link "feature" + end + end + + step 'project "Shop" has issue "Bugfix1" with labels: "bug", "feature"' do + project = Project.find_by(name: "Shop") + issue = create(:issue, title: "Bugfix1", project: project) + issue.labels << project.labels.find_by(title: 'bug') + issue.labels << project.labels.find_by(title: 'feature') + end + + step 'project "Shop" has issue "Bugfix2" with labels: "bug", "enhancement"' do + project = Project.find_by(name: "Shop") + issue = create(:issue, title: "Bugfix2", project: project) + issue.labels << project.labels.find_by(title: 'bug') + issue.labels << project.labels.find_by(title: 'enhancement') + end + + step 'project "Shop" has issue "Feature1" with labels: "feature"' do + project = Project.find_by(name: "Shop") + issue = create(:issue, title: "Feature1", project: project) + issue.labels << project.labels.find_by(title: 'feature') + end +end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb new file mode 100644 index 00000000000..b55b3c6c8a2 --- /dev/null +++ b/features/steps/project/issues/issues.rb @@ -0,0 +1,236 @@ +class Spinach::Features::ProjectIssues < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedNote + include SharedPaths + include SharedMarkdown + + step 'I should see "Release 0.4" in issues' do + page.should 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" + end + + step 'I should not see "Tweet control" in issues' do + page.should_not have_content "Tweet control" + end + + step 'I click link "Closed"' do + click_link "Closed" + end + + step 'I should see "Release 0.3" in issues' do + page.should 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" + end + + step 'I click link "All"' do + click_link "All" + end + + step 'I click link "Release 0.4"' do + click_link "Release 0.4" + end + + step 'I should see issue "Release 0.4"' do + page.should have_content "Release 0.4" + end + + step 'I click link "New Issue"' do + click_link "New Issue" + end + + step 'I submit new issue "500 error on profile"' do + fill_in "issue_title", with: "500 error on profile" + click_button "Submit new issue" + end + + step 'I submit new issue "500 error on profile" with label \'bug\'' do + fill_in "issue_title", with: "500 error on profile" + select 'bug', from: "Labels" + click_button "Submit new issue" + end + + step 'I click link "500 error on profile"' do + click_link "500 error on profile" + end + + step 'I should see label \'bug\' with issue' do + within '.issue-show-labels' do + page.should 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 + end + + step 'I fill in issue search with "Re"' do + filter_issue "Re" + end + + step 'I fill in issue search with "Bu"' do + filter_issue "Bu" + end + + step 'I fill in issue search with ".3"' do + filter_issue ".3" + end + + step 'I fill in issue search with "Something"' do + filter_issue "Something" + end + + step 'I fill in issue search with ""' do + filter_issue "" + end + + step 'project "Shop" has milestone "v2.2"' do + + milestone = create(:milestone, title: "v2.2", project: project) + + 3.times { create(:issue, project: project, milestone: milestone) } + end + + step 'project "Shop" has milestone "v3.0"' do + + milestone = create(:milestone, title: "v3.0", project: project) + + 3.times { create(:issue, project: project, milestone: milestone) } + end + + When 'I select milestone "v3.0"' do + select "v3.0", from: "milestone_id" + end + + 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") + end + + When 'I select first assignee from "Shop" project' do + + first_assignee = project.users.first + select first_assignee.name, from: "assignee_id" + end + + step 'I should see first assignee from "Shop" as selected assignee' do + issues_assignee_selector = "#issue_assignee_id_chzn > a" + + assignee_name = project.users.first.name + find(issues_assignee_selector).should have_content(assignee_name) + end + + step 'project "Shop" have "Release 0.4" open issue' do + + create(:issue, + title: "Release 0.4", + project: project, + author: project.users.first, + description: "# Description header" + ) + end + + step 'project "Shop" have "Tweet control" open issue' do + create(:issue, + title: "Tweet control", + project: project, + author: project.users.first) + end + + step 'project "Shop" have "Release 0.3" closed issue' do + create(:closed_issue, + title: "Release 0.3", + project: project, + author: project.users.first) + end + + step 'empty project "Empty Project"' do + create :empty_project, name: 'Empty Project', namespace: @user.namespace + end + + When 'I visit empty project page' do + project = Project.find_by(name: 'Empty Project') + visit project_path(project) + end + + 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) + end + end + + When "I visit empty project's issues page" do + project = Project.find_by(name: 'Empty Project') + visit project_issues_path(project) + end + + step 'I leave a comment with code block' do + 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 + end + end + + step 'The code block should be unchanged' do + page.should 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 + issue = create(:issue, title: 'Bugfix1', description: 'Description for issue1', project: project) + end + + step 'project \'Shop\' has issue \'Feature1\' with description: \'Feature submitted for issue1\'' do + issue = create(:issue, title: 'Feature1', description: 'Feature submitted for issue1', project: project) + end + + step 'I fill in issue search with \'Description for issue1\'' do + filter_issue 'Description for issue' + end + + step 'I fill in issue search with \'issue1\'' do + filter_issue 'issue1' + end + + step 'I fill in issue search with \'Rock and roll\'' do + filter_issue 'Description for issue' + end + + step 'I should see \'Bugfix1\' in issues' do + page.should have_content 'Bugfix1' + end + + step 'I should see \'Feature1\' in issues' do + page.should have_content 'Feature1' + end + + step 'I should not see \'Bugfix1\' in issues' do + page.should_not have_content 'Bugfix1' + end + + step 'issue \'Release 0.4\' has label \'bug\'' do + label = project.labels.create!(name: 'bug', color: '#990000') + issue = Issue.find_by!(title: 'Release 0.4') + issue.labels << label + end + + step 'I click label \'bug\'' do + within ".issues-list" do + click_link 'bug' + end + end + + def filter_issue(text) + fill_in 'issue_search', with: text + end +end diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb new file mode 100644 index 00000000000..3e3e90824b4 --- /dev/null +++ b/features/steps/project/issues/labels.rb @@ -0,0 +1,101 @@ +class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I visit \'bug\' label edit page' do + visit edit_project_label_path(project, bug_label) + end + + step 'I remove label \'bug\'' do + within "#label_#{bug_label.id}" do + click_link 'Remove' + end + end + + step 'I delete all labels' do + within '.labels' do + all('.btn-remove').each do |remove| + remove.click + sleep 0.05 + end + end + end + + step 'I should see labels help message' do + within '.labels' do + page.should have_content 'Create first label or generate default set of '\ + 'labels' + end + end + + step 'I submit new label \'support\'' do + fill_in 'Title', with: 'support' + fill_in 'Background Color', with: '#F95610' + click_button 'Save' + end + + step 'I submit new label \'bug\'' do + fill_in 'Title', with: 'bug' + fill_in 'Background Color', with: '#F95610' + click_button 'Save' + end + + step 'I submit new label with invalid color' do + fill_in 'Title', with: 'support' + fill_in 'Background Color', with: '#12' + click_button 'Save' + end + + step 'I should see label label exist error message' do + within '.label-form' do + page.should 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' + end + end + + step 'I should see label \'feature\'' do + within '.manage-labels-list' do + page.should have_content 'feature' + end + end + + step 'I should see label \'bug\'' do + within '.manage-labels-list' do + page.should have_content 'bug' + end + end + + step 'I should not see label \'bug\'' do + within '.manage-labels-list' do + page.should_not have_content 'bug' + end + end + + step 'I should see label \'support\'' do + within '.manage-labels-list' do + page.should have_content 'support' + end + end + + step 'I change label \'bug\' to \'fix\'' do + fill_in 'Title', with: 'fix' + fill_in 'Background Color', with: '#F15610' + click_button 'Save' + end + + step 'I should see label \'fix\'' do + within '.manage-labels-list' do + page.should have_content 'fix' + end + end + + def bug_label + project.labels.find_or_create_by(title: 'bug') + end +end diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb new file mode 100644 index 00000000000..89d7af3c9ee --- /dev/null +++ b/features/steps/project/issues/milestones.rb @@ -0,0 +1,59 @@ +class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + include SharedMarkdown + + 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("Browse Issues") + end + + step 'I click link "v2.2"' do + click_link "v2.2" + end + + step 'I click link "New Milestone"' do + click_link "New Milestone" + end + + step 'I submit new milestone "v2.3"' do + fill_in "milestone_title", with: "v2.3" + click_button "Create milestone" + end + + 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("Browse Issues") + end + + step 'project "Shop" has milestone "v2.2"' do + project = Project.find_by(name: "Shop") + milestone = create(:milestone, + title: "v2.2", + project: project, + description: "# Description header" + ) + 3.times { create(:issue, project: project, milestone: milestone) } + end + + step 'the milestone has open and closed issues' do + project = Project.find_by(name: "Shop") + milestone = project.milestones.find_by(title: 'v2.2') + + # 3 Open issues created above; create one closed issue + create(:closed_issue, project: project, milestone: milestone) + end + + When 'I click link "All Issues"' do + click_link 'All Issues' + end + + step 'I should see 3 issues' do + page.should have_selector('#tab-issues li.issue-row', count: 4) + end +end diff --git a/features/steps/project/labels.rb b/features/steps/project/labels.rb deleted file mode 100644 index b287e183b91..00000000000 --- a/features/steps/project/labels.rb +++ /dev/null @@ -1,101 +0,0 @@ -class Spinach::Features::ProjectLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I visit \'bug\' label edit page' do - visit edit_project_label_path(project, bug_label) - end - - step 'I remove label \'bug\'' do - within "#label_#{bug_label.id}" do - click_link 'Remove' - end - end - - step 'I delete all labels' do - within '.labels' do - all('.btn-remove').each do |remove| - remove.click - sleep 0.05 - end - end - end - - step 'I should see labels help message' do - within '.labels' do - page.should have_content 'Create first label or generate default set of '\ - 'labels' - end - end - - step 'I submit new label \'support\'' do - fill_in 'Title', with: 'support' - fill_in 'Background Color', with: '#F95610' - click_button 'Save' - end - - step 'I submit new label \'bug\'' do - fill_in 'Title', with: 'bug' - fill_in 'Background Color', with: '#F95610' - click_button 'Save' - end - - step 'I submit new label with invalid color' do - fill_in 'Title', with: 'support' - fill_in 'Background Color', with: '#12' - click_button 'Save' - end - - step 'I should see label label exist error message' do - within '.label-form' do - page.should 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' - end - end - - step 'I should see label \'feature\'' do - within '.manage-labels-list' do - page.should have_content 'feature' - end - end - - step 'I should see label \'bug\'' do - within '.manage-labels-list' do - page.should have_content 'bug' - end - end - - step 'I should not see label \'bug\'' do - within '.manage-labels-list' do - page.should_not have_content 'bug' - end - end - - step 'I should see label \'support\'' do - within '.manage-labels-list' do - page.should have_content 'support' - end - end - - step 'I change label \'bug\' to \'fix\'' do - fill_in 'Title', with: 'fix' - fill_in 'Background Color', with: '#F15610' - click_button 'Save' - end - - step 'I should see label \'fix\'' do - within '.manage-labels-list' do - page.should have_content 'fix' - end - end - - def bug_label - project.labels.find_or_create_by(title: 'bug') - end -end diff --git a/features/steps/project/markdown_render.rb b/features/steps/project/markdown_render.rb deleted file mode 100644 index a8631af2e05..00000000000 --- a/features/steps/project/markdown_render.rb +++ /dev/null @@ -1,288 +0,0 @@ -# If you need to modify the existing seed repository for your tests, -# it is recommended that you make the changes on the `markdown` branch of the seed project repository, -# which should only be used by tests in this file. See `/spec/factories.rb#project` for more info. -class Spinach::Features::ProjectMarkdownRender < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedMarkdown - - step 'I own project "Delta"' do - @project = Project.find_by(name: "Delta") - @project ||= create(:project, name: "Delta", namespace: @user.namespace) - @project.team << [@user, :master] - end - - step 'I should see files from repository in markdown' do - current_path.should == project_tree_path(@project, "markdown") - page.should have_content "README.md" - page.should 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" - end - - step 'I click on Gitlab API in README' do - click_link "GitLab API doc" - end - - step 'I should see correct document rendered' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - step 'I click on Rake tasks in README' do - click_link "Rake tasks" - end - - step 'I should see correct directory rendered' do - current_path.should == project_tree_path(@project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - step 'I click on GitLab API doc directory in README' do - click_link "GitLab API doc directory" - end - - step 'I should see correct doc/api directory rendered' do - current_path.should == project_tree_path(@project, "markdown/doc/api") - page.should have_content "README.md" - page.should have_content "users.md" - end - - step 'I click on Maintenance in README' do - click_link "Maintenance" - end - - step 'I should see correct maintenance file rendered' do - current_path.should == project_blob_path(@project, "markdown/doc/raketasks/maintenance.md") - page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" - end - - step 'I click on link "empty" in the README' do - within('.readme-holder') do - click_link "empty" - end - end - - step 'I click on link "id" in the README' do - within('.readme-holder') do - click_link "#id" - end - end - - step 'I navigate to the doc/api/README' do - within '.tree-table' do - click_link "doc" - end - - within '.tree-table' do - click_link "api" - end - - within '.tree-table' do - click_link "README.md" - end - end - - step 'I see correct file rendered' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - step 'I click on users in doc/api/README' do - click_link "Users" - end - - step 'I should see the correct document file' do - current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." - end - - step 'I click on raketasks in doc/api/README' do - click_link "Rake tasks" - end - - # Markdown branch - - When 'I visit markdown branch' do - visit project_tree_path(@project, "markdown") - end - - When 'I visit markdown branch "README.md" blob' do - visit project_blob_path(@project, "markdown/README.md") - end - - When 'I visit markdown branch "d" tree' do - visit project_tree_path(@project, "markdown/d") - end - - When 'I visit markdown branch "d/README.md" blob' do - visit project_blob_path(@project, "markdown/d/README.md") - end - - step 'I should see files from repository in markdown branch' do - current_path.should == project_tree_path(@project, "markdown") - page.should have_content "README.md" - page.should have_content "CHANGELOG" - end - - step 'I see correct file rendered in markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - step 'I should see correct document rendered for markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - step 'I should see correct directory rendered for markdown branch' do - current_path.should == project_tree_path(@project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - step 'I should see the users document file in markdown branch' do - current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." - end - - # Expected link contents - - step 'The link with text "empty" should have url "tree/markdown"' do - find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown") - end - - step 'The link with text "empty" should have url "blob/markdown/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") - end - - step 'The link with text "empty" should have url "tree/markdown/d"' do - find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown/d") - end - - step 'The link with text "empty" should have '\ - 'url "blob/markdown/d/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/d/README.md") - end - - step 'The link with text "ID" should have url "tree/markdownID"' do - find('a', text: /^#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' - end - - step 'The link with text "/ID" should have url "tree/markdownID"' do - find('a', text: /^\/#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' - end - - step 'The link with text "README.mdID" '\ - 'should have url "blob/markdown/README.mdID"' do - find('a', text: /^README.md#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' - end - - step 'The link with text "d/README.mdID" should have '\ - 'url "blob/markdown/d/README.mdID"' do - find('a', text: /^d\/README.md#id$/)['href'] == current_host + project_blob_path(@project, "d/markdown/README.md") + '#id' - end - - step 'The link with text "ID" should have url "blob/markdown/README.mdID"' do - find('a', text: /^#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' - end - - step 'The link with text "/ID" should have url "blob/markdown/README.mdID"' do - find('a', text: /^\/#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' - end - - # Wiki - - step 'I go to wiki page' do - click_link "Wiki" - current_path.should == project_wiki_path(@project, "home") - end - - step 'I add various links to the wiki page' do - fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n" - fill_in "wiki[message]", with: "Adding links to wiki" - click_button "Create page" - end - - step 'Wiki page should have added links' do - current_path.should == project_wiki_path(@project, "home") - page.should have_content "test GitLab API doc Rake tasks" - end - - step 'I add a header to the wiki page' do - fill_in "wiki[content]", with: "# Wiki header\n" - fill_in "wiki[message]", with: "Add header to wiki" - click_button "Create page" - end - - step 'Wiki header should have correct id and link' do - header_should_have_correct_id_and_link(1, 'Wiki header', 'wiki-header') - end - - step 'I click on test link' do - click_link "test" - end - - step 'I see new wiki page named test' do - current_path.should == project_wiki_path(@project, "test") - page.should have_content "Editing" - end - - When 'I go back to wiki page home' do - visit project_wiki_path(@project, "home") - current_path.should == project_wiki_path(@project, "home") - end - - step 'I click on GitLab API doc link' do - click_link "GitLab API" - end - - step 'I see Gitlab API document' do - current_path.should == project_wiki_path(@project, "api") - page.should have_content "Editing" - end - - step 'I click on Rake tasks link' do - click_link "Rake tasks" - end - - step 'I see Rake tasks directory' do - current_path.should == project_wiki_path(@project, "raketasks") - page.should have_content "Editing" - end - - step 'I go directory which contains README file' do - visit project_tree_path(@project, "markdown/doc/api") - current_path.should == project_tree_path(@project, "markdown/doc/api") - end - - step 'I click on a relative link in README' do - click_link "Users" - end - - step 'I should see the correct markdown' do - current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") - page.should have_content "List users" - end - - step 'Header "Application details" should have correct id and link' do - header_should_have_correct_id_and_link(2, 'Application details', 'application-details') - end - - step 'Header "GitLab API" should have correct id and link' do - header_should_have_correct_id_and_link(1, 'GitLab API', 'gitlab-api') - end -end diff --git a/features/steps/project/milestones.rb b/features/steps/project/milestones.rb deleted file mode 100644 index 13f917a6279..00000000000 --- a/features/steps/project/milestones.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Spinach::Features::ProjectMilestones < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include SharedMarkdown - - 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("Browse Issues") - end - - step 'I click link "v2.2"' do - click_link "v2.2" - end - - step 'I click link "New Milestone"' do - click_link "New Milestone" - end - - step 'I submit new milestone "v2.3"' do - fill_in "milestone_title", with: "v2.3" - click_button "Create milestone" - end - - 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("Browse Issues") - end - - step 'project "Shop" has milestone "v2.2"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, - title: "v2.2", - project: project, - description: "# Description header" - ) - 3.times { create(:issue, project: project, milestone: milestone) } - end - - step 'the milestone has open and closed issues' do - project = Project.find_by(name: "Shop") - milestone = project.milestones.find_by(title: 'v2.2') - - # 3 Open issues created above; create one closed issue - create(:closed_issue, project: project, milestone: milestone) - end - - When 'I click link "All Issues"' do - click_link 'All Issues' - end - - step 'I should see 3 issues' do - page.should have_selector('#tab-issues li.issue-row', count: 4) - end -end diff --git a/features/steps/project/multiselect_blob.rb b/features/steps/project/multiselect_blob.rb deleted file mode 100644 index 611289a6162..00000000000 --- a/features/steps/project/multiselect_blob.rb +++ /dev/null @@ -1,58 +0,0 @@ -class Spinach::Features::ProjectMultiselectBlob < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - class << self - def click_line_steps(*line_numbers) - line_numbers.each do |line_number| - step "I click line #{line_number} in file" do - find("#L#{line_number}").click - end - - step "I shift-click line #{line_number} in file" do - script = "$('#L#{line_number}').trigger($.Event('click', { shiftKey: true }));" - execute_script(script) - end - end - end - - def check_state_steps(*ranges) - ranges.each do |range| - fragment = range.kind_of?(Array) ? "L#{range.first}-#{range.last}" : "L#{range}" - pluralization = range.kind_of?(Array) ? "s" : "" - - step "I should see \"#{fragment}\" as URI fragment" do - URI.parse(current_url).fragment.should == fragment - end - - step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do - ids = Array(range).map { |n| "LC#{n}" } - extra = false - - highlighted = all("#tree-content-holder .highlight .line.hll") - highlighted.each do |element| - extra ||= ids.delete(element[:id]).nil? - end - - extra.should be_false and ids.should be_empty - end - end - end - end - - click_line_steps *Array(1..5) - check_state_steps *Array(1..5), Array(1..2), Array(1..3), Array(1..4), Array(1..5), Array(3..5) - - step 'I go back in history' do - go_back - end - - step 'I go forward in history' do - go_forward - end - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end -end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index f543e47b4c2..f7fff8e64f9 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -1,4 +1,4 @@ -class Spinach::Features::ProjectFeature < Spinach::FeatureSteps +class Spinach::Features::Project < Spinach::FeatureSteps include SharedAuthentication include SharedProject include SharedPaths diff --git a/features/steps/project/search_code.rb b/features/steps/project/search_code.rb deleted file mode 100644 index 5753296251f..00000000000 --- a/features/steps/project/search_code.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Spinach::Features::ProjectSearchCode < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I search for term "coffee"' do - fill_in "search", with: "coffee" - click_button "Go" - end - - step 'I should see files from repository containing "coffee"' do - page.should have_content 'coffee' - page.should have_content 'CONTRIBUTING.md' - end - - step 'I should see empty result' do - page.should have_content "We couldn't find any matching" - end -end diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb new file mode 100644 index 00000000000..0642302e797 --- /dev/null +++ b/features/steps/project/source/browse_files.rb @@ -0,0 +1,176 @@ +class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + 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" + end + + step 'I should see files from repository for "6d39438"' do + current_path.should == project_tree_path(@project, "6d39438") + page.should have_content ".gitignore" + page.should have_content "LICENSE" + end + + step 'I see the ".gitignore"' do + page.should have_content '.gitignore' + end + + step 'I don\'t see the ".gitignore"' do + page.should_not have_content '.gitignore' + end + + step 'I click on ".gitignore" file in repo' do + click_link ".gitignore" + end + + step 'I should see its content' do + page.should have_content old_gitignore_content + end + + step 'I should see its new content' do + page.should have_content new_gitignore_content + end + + step 'I click link "Raw"' do + click_link 'Raw' + end + + step 'I should see raw file content' do + source.should == sample_blob.data + end + + step 'I click button "Edit"' do + click_link 'Edit' + end + + step 'I can edit code' do + set_new_content + evaluate_script('editor.getValue()').should == new_gitignore_content + end + + step 'I edit code' do + set_new_content + end + + step 'I fill the new file name' do + fill_in :file_name, with: new_file_name + end + + step 'I fill the commit message' do + fill_in :commit_message, with: 'Not yet a commit message.' + end + + step 'I click link "Diff"' do + click_link 'Diff' + end + + step 'I click on "Commit changes"' do + click_button 'Commit changes' + end + + step 'I click on "Remove"' do + click_link 'Remove' + end + + step 'I click on "Remove file"' do + click_button 'Remove file' + end + + step 'I see diff' do + page.should have_css '.line_holder.new' + end + + step 'I click on "new file" link in repo' do + click_link 'new-file-link' + end + + step 'I can see new file page' do + page.should have_content "New file" + page.should have_content "File name" + page.should have_content "Commit message" + end + + step 'I click on files directory' do + click_link 'files' + end + + step 'I click on History link' do + click_link 'History' + end + + step 'I see Browse dir link' do + page.should have_link 'Browse Dir »' + page.should_not have_link 'Browse Code »' + end + + step 'I click on readme file' do + within '.tree-table' do + click_link 'README.md' + end + end + + step 'I see Browse file link' do + page.should have_link 'Browse File »' + page.should_not 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 »' + end + + step 'I click on Permalink' do + click_link 'Permalink' + end + + step 'I am redirected to the files URL' do + current_path.should == project_tree_path(@project, 'master') + end + + step 'I am redirected to the ".gitignore"' do + expect(current_path).to eq(project_blob_path(@project, 'master/.gitignore')) + end + + step 'I am redirected to the permalink URL' do + expect(current_path).to eq(project_blob_path( + @project, @project.repository.commit.sha + '/.gitignore')) + end + + step 'I am redirected to the new file' do + expect(current_path).to eq(project_blob_path( + @project, 'master/' + new_file_name)) + end + + step "I don't see the permalink link" do + expect(page).not_to have_link('permalink') + end + + private + + def set_new_content + execute_script("editor.setValue('#{new_gitignore_content}')") + end + + # Content of the gitignore file on the seed repository. + def old_gitignore_content + '*.rbc' + end + + # Constant value that differs from the content + # of the gitignore of the seed repository. + def new_gitignore_content + old_gitignore_content + 'a' + end + + # Constant value that is a valid filename and + # not a filename present at root of the seed repository. + def new_file_name + 'not_a_file.md' + end +end diff --git a/features/steps/project/source/git_blame.rb b/features/steps/project/source/git_blame.rb new file mode 100644 index 00000000000..e29a816c51b --- /dev/null +++ b/features/steps/project/source/git_blame.rb @@ -0,0 +1,19 @@ +class Spinach::Features::ProjectSourceGitBlame < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I click on ".gitignore" file in repo' do + click_link ".gitignore" + end + + step 'I click Blame button' do + click_link 'Blame' + 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" + end +end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb new file mode 100644 index 00000000000..53578ee5970 --- /dev/null +++ b/features/steps/project/source/markdown_render.rb @@ -0,0 +1,288 @@ +# If you need to modify the existing seed repository for your tests, +# it is recommended that you make the changes on the `markdown` branch of the seed project repository, +# which should only be used by tests in this file. See `/spec/factories.rb#project` for more info. +class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps + include SharedAuthentication + include SharedPaths + include SharedMarkdown + + step 'I own project "Delta"' do + @project = Project.find_by(name: "Delta") + @project ||= create(:project, name: "Delta", namespace: @user.namespace) + @project.team << [@user, :master] + end + + step 'I should see files from repository in markdown' do + current_path.should == project_tree_path(@project, "markdown") + page.should have_content "README.md" + page.should 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" + end + + step 'I click on Gitlab API in README' do + click_link "GitLab API doc" + end + + step 'I should see correct document rendered' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "All API requests require authentication" + end + + step 'I click on Rake tasks in README' do + click_link "Rake tasks" + end + + step 'I should see correct directory rendered' do + current_path.should == project_tree_path(@project, "markdown/doc/raketasks") + page.should have_content "backup_restore.md" + page.should have_content "maintenance.md" + end + + step 'I click on GitLab API doc directory in README' do + click_link "GitLab API doc directory" + end + + step 'I should see correct doc/api directory rendered' do + current_path.should == project_tree_path(@project, "markdown/doc/api") + page.should have_content "README.md" + page.should have_content "users.md" + end + + step 'I click on Maintenance in README' do + click_link "Maintenance" + end + + step 'I should see correct maintenance file rendered' do + current_path.should == project_blob_path(@project, "markdown/doc/raketasks/maintenance.md") + page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" + end + + step 'I click on link "empty" in the README' do + within('.readme-holder') do + click_link "empty" + end + end + + step 'I click on link "id" in the README' do + within('.readme-holder') do + click_link "#id" + end + end + + step 'I navigate to the doc/api/README' do + within '.tree-table' do + click_link "doc" + end + + within '.tree-table' do + click_link "api" + end + + within '.tree-table' do + click_link "README.md" + end + end + + step 'I see correct file rendered' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "Contents" + page.should have_link "Users" + page.should have_link "Rake tasks" + end + + step 'I click on users in doc/api/README' do + click_link "Users" + end + + step 'I should see the correct document file' do + current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") + page.should have_content "Get a list of users." + end + + step 'I click on raketasks in doc/api/README' do + click_link "Rake tasks" + end + + # Markdown branch + + When 'I visit markdown branch' do + visit project_tree_path(@project, "markdown") + end + + When 'I visit markdown branch "README.md" blob' do + visit project_blob_path(@project, "markdown/README.md") + end + + When 'I visit markdown branch "d" tree' do + visit project_tree_path(@project, "markdown/d") + end + + When 'I visit markdown branch "d/README.md" blob' do + visit project_blob_path(@project, "markdown/d/README.md") + end + + step 'I should see files from repository in markdown branch' do + current_path.should == project_tree_path(@project, "markdown") + page.should have_content "README.md" + page.should have_content "CHANGELOG" + end + + step 'I see correct file rendered in markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "Contents" + page.should have_link "Users" + page.should have_link "Rake tasks" + end + + step 'I should see correct document rendered for markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/README.md") + page.should have_content "All API requests require authentication" + end + + step 'I should see correct directory rendered for markdown branch' do + current_path.should == project_tree_path(@project, "markdown/doc/raketasks") + page.should have_content "backup_restore.md" + page.should have_content "maintenance.md" + end + + step 'I should see the users document file in markdown branch' do + current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") + page.should have_content "Get a list of users." + end + + # Expected link contents + + step 'The link with text "empty" should have url "tree/markdown"' do + find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown") + end + + step 'The link with text "empty" should have url "blob/markdown/README.md"' do + find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + end + + step 'The link with text "empty" should have url "tree/markdown/d"' do + find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown/d") + end + + step 'The link with text "empty" should have '\ + 'url "blob/markdown/d/README.md"' do + find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/d/README.md") + end + + step 'The link with text "ID" should have url "tree/markdownID"' do + find('a', text: /^#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' + end + + step 'The link with text "/ID" should have url "tree/markdownID"' do + find('a', text: /^\/#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' + end + + step 'The link with text "README.mdID" '\ + 'should have url "blob/markdown/README.mdID"' do + find('a', text: /^README.md#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' + end + + step 'The link with text "d/README.mdID" should have '\ + 'url "blob/markdown/d/README.mdID"' do + find('a', text: /^d\/README.md#id$/)['href'] == current_host + project_blob_path(@project, "d/markdown/README.md") + '#id' + end + + step 'The link with text "ID" should have url "blob/markdown/README.mdID"' do + find('a', text: /^#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' + end + + step 'The link with text "/ID" should have url "blob/markdown/README.mdID"' do + find('a', text: /^\/#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' + end + + # Wiki + + step 'I go to wiki page' do + click_link "Wiki" + current_path.should == project_wiki_path(@project, "home") + end + + step 'I add various links to the wiki page' do + fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n" + fill_in "wiki[message]", with: "Adding links to wiki" + click_button "Create page" + end + + step 'Wiki page should have added links' do + current_path.should == project_wiki_path(@project, "home") + page.should have_content "test GitLab API doc Rake tasks" + end + + step 'I add a header to the wiki page' do + fill_in "wiki[content]", with: "# Wiki header\n" + fill_in "wiki[message]", with: "Add header to wiki" + click_button "Create page" + end + + step 'Wiki header should have correct id and link' do + header_should_have_correct_id_and_link(1, 'Wiki header', 'wiki-header') + end + + step 'I click on test link' do + click_link "test" + end + + step 'I see new wiki page named test' do + current_path.should == project_wiki_path(@project, "test") + page.should have_content "Editing" + end + + When 'I go back to wiki page home' do + visit project_wiki_path(@project, "home") + current_path.should == project_wiki_path(@project, "home") + end + + step 'I click on GitLab API doc link' do + click_link "GitLab API" + end + + step 'I see Gitlab API document' do + current_path.should == project_wiki_path(@project, "api") + page.should have_content "Editing" + end + + step 'I click on Rake tasks link' do + click_link "Rake tasks" + end + + step 'I see Rake tasks directory' do + current_path.should == project_wiki_path(@project, "raketasks") + page.should have_content "Editing" + end + + step 'I go directory which contains README file' do + visit project_tree_path(@project, "markdown/doc/api") + current_path.should == project_tree_path(@project, "markdown/doc/api") + end + + step 'I click on a relative link in README' do + click_link "Users" + end + + step 'I should see the correct markdown' do + current_path.should == project_blob_path(@project, "markdown/doc/api/users.md") + page.should have_content "List users" + end + + step 'Header "Application details" should have correct id and link' do + header_should_have_correct_id_and_link(2, 'Application details', 'application-details') + end + + step 'Header "GitLab API" should have correct id and link' do + header_should_have_correct_id_and_link(1, 'GitLab API', 'gitlab-api') + end +end diff --git a/features/steps/project/source/multiselect_blob.rb b/features/steps/project/source/multiselect_blob.rb new file mode 100644 index 00000000000..b749ba49371 --- /dev/null +++ b/features/steps/project/source/multiselect_blob.rb @@ -0,0 +1,58 @@ +class Spinach::Features::ProjectSourceMultiselectBlob < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + class << self + def click_line_steps(*line_numbers) + line_numbers.each do |line_number| + step "I click line #{line_number} in file" do + find("#L#{line_number}").click + end + + step "I shift-click line #{line_number} in file" do + script = "$('#L#{line_number}').trigger($.Event('click', { shiftKey: true }));" + execute_script(script) + end + end + end + + def check_state_steps(*ranges) + ranges.each do |range| + fragment = range.kind_of?(Array) ? "L#{range.first}-#{range.last}" : "L#{range}" + pluralization = range.kind_of?(Array) ? "s" : "" + + step "I should see \"#{fragment}\" as URI fragment" do + URI.parse(current_url).fragment.should == fragment + end + + step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do + ids = Array(range).map { |n| "LC#{n}" } + extra = false + + highlighted = all("#tree-content-holder .highlight .line.hll") + highlighted.each do |element| + extra ||= ids.delete(element[:id]).nil? + end + + extra.should be_false and ids.should be_empty + end + end + end + end + + click_line_steps *Array(1..5) + check_state_steps *Array(1..5), Array(1..2), Array(1..3), Array(1..4), Array(1..5), Array(3..5) + + step 'I go back in history' do + go_back + end + + step 'I go forward in history' do + go_forward + end + + step 'I click on ".gitignore" file in repo' do + click_link ".gitignore" + end +end diff --git a/features/steps/project/source/search_code.rb b/features/steps/project/source/search_code.rb new file mode 100644 index 00000000000..9c2864cc936 --- /dev/null +++ b/features/steps/project/source/search_code.rb @@ -0,0 +1,19 @@ +class Spinach::Features::ProjectSourceSearchCode < Spinach::FeatureSteps + include SharedAuthentication + include SharedProject + include SharedPaths + + step 'I search for term "coffee"' do + fill_in "search", with: "coffee" + click_button "Go" + end + + step 'I should see files from repository containing "coffee"' do + page.should have_content 'coffee' + page.should have_content 'CONTRIBUTING.md' + end + + step 'I should see empty result' do + page.should have_content "We couldn't find any matching" + end +end diff --git a/features/steps/snippets/discover.rb b/features/steps/snippets/discover.rb index da73dfc68be..42bccafcc84 100644 --- a/features/steps/snippets/discover.rb +++ b/features/steps/snippets/discover.rb @@ -1,4 +1,4 @@ -class Spinach::Features::DiscoverSnippets < Spinach::FeatureSteps +class Spinach::Features::SnippetsDiscover < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedSnippet diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index e8154c8ce57..dedbdd2c4f0 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -1,4 +1,4 @@ -class Spinach::Features::SnippetsFeature < Spinach::FeatureSteps +class Spinach::Features::Snippets < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedProject diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index 71a1952926f..ca9aa64bee6 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -1,4 +1,4 @@ -class Spinach::Features::UserSnippets < Spinach::FeatureSteps +class Spinach::Features::SnippetsUser < Spinach::FeatureSteps include SharedAuthentication include SharedPaths include SharedSnippet -- cgit v1.2.1 From 9f0083a96c03ec22b1d9442a9c7530899e633301 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 5 Oct 2014 00:53:44 -0500 Subject: Add task lists to issues and merge requests Make the Markdown parser recognize "[x]" or "[ ]" at the beginning of a list item and turn it into a checkbox input. Users who can modify the issue or MR can toggle the checkboxes directly or edit the Markdown to manage the tasks. Task status is also displayed in the MR and issue lists. --- app/assets/javascripts/issue.js.coffee | 24 ++++++++++ app/assets/javascripts/merge_request.js.coffee | 23 ++++++++++ app/assets/stylesheets/generic/common.scss | 3 ++ app/assets/stylesheets/generic/lists.scss | 4 ++ app/controllers/projects/issues_controller.rb | 2 +- .../projects/merge_requests_controller.rb | 2 +- app/models/concerns/taskable.rb | 51 ++++++++++++++++++++++ app/models/issue.rb | 1 + app/models/merge_request.rb | 1 + app/services/issues/update_service.rb | 14 +++++- app/services/merge_requests/update_service.rb | 8 +++- app/views/projects/issues/_issue.html.haml | 4 ++ app/views/projects/issues/show.html.haml | 2 +- .../merge_requests/_merge_request.html.haml | 4 +- .../projects/merge_requests/show/_mr_box.html.haml | 2 +- lib/gitlab/markdown.rb | 24 ++++++++++ lib/redcarpet/render/gitlab_html.rb | 6 ++- 17 files changed, 167 insertions(+), 8 deletions(-) create mode 100644 app/models/concerns/taskable.rb diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index 36935a0a159..f2b531fb2b1 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -6,4 +6,28 @@ class Issue $(".issue-box .inline-update").on "change", "#issue_assignee_id", -> $(this).submit() + if $("a.btn-close").length + $("li.task-list-item input:checkbox").prop("disabled", false) + + $(".task-list-item input:checkbox").on "click", -> + is_checked = $(this).prop("checked") + if $(this).is(":checked") + state_event = "task_check" + else + state_event = "task_uncheck" + + mr_url = $("form.edit-issue").first().attr("action") + mr_num = mr_url.match(/\d+$/) + task_num = 0 + $("li.task-list-item input:checkbox").each( (index, e) => + if e == this + task_num = index + 1 + ) + + $.ajax + type: "PATCH" + url: mr_url + data: "issue[state_event]=" + state_event + + "&issue[task_num]=" + task_num + @Issue = Issue diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index 4c9f20ae6fa..203c721c30c 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -17,6 +17,8 @@ class MergeRequest disableButtonIfEmptyField '#commit_message', '.accept_merge_request' + if $("a.close-mr-link").length + $("li.task-list-item input:checkbox").prop("disabled", false) # Local jQuery finder $: (selector) -> @@ -72,6 +74,27 @@ class MergeRequest this.$('.remove_source_branch_in_progress').hide() this.$('.remove_source_branch_widget.failed').show() + this.$(".task-list-item input:checkbox").on "click", -> + is_checked = $(this).prop("checked") + if $(this).is(":checked") + state_event = "task_check" + else + state_event = "task_uncheck" + + mr_url = $("form.edit-merge_request").first().attr("action") + mr_num = mr_url.match(/\d+$/) + task_num = 0 + $("li.task-list-item input:checkbox").each( (index, e) => + if e == this + task_num = index + 1 + ) + + $.ajax + type: "PATCH" + url: mr_url + data: "merge_request[state_event]=" + state_event + + "&merge_request[task_num]=" + task_num + activateTab: (action) -> this.$('.merge-request-tabs li').removeClass 'active' this.$('.tab-content').hide() diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index 803219a2e86..cd2f4e45e3c 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -356,3 +356,6 @@ table { font-size: 42px; } +.task-status { + margin-left: 10px; +} diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss index d347ab2c2e4..2653bfbf831 100644 --- a/app/assets/stylesheets/generic/lists.scss +++ b/app/assets/stylesheets/generic/lists.scss @@ -122,3 +122,7 @@ ul.bordered-list { } } } + +li.task-list-item { + list-style-type: none; +} diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 9e7a55b23fd..c6d526f05c5 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -152,7 +152,7 @@ class Projects::IssuesController < Projects::ApplicationController def issue_params params.require(:issue).permit( :title, :assignee_id, :position, :description, - :milestone_id, :state_event, label_ids: [] + :milestone_id, :state_event, :task_num, label_ids: [] ) end end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index e13773d6465..20a733b10e1 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -250,7 +250,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController params.require(:merge_request).permit( :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, - :state_event, :description, label_ids: [] + :state_event, :description, :task_num, label_ids: [] ) end end diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb new file mode 100644 index 00000000000..410e8dc820b --- /dev/null +++ b/app/models/concerns/taskable.rb @@ -0,0 +1,51 @@ +# Contains functionality for objects that can have task lists in their +# descriptions. Task list items can be added with Markdown like "* [x] Fix +# bugs". +# +# Used by MergeRequest and Issue +module Taskable + TASK_PATTERN_MD = /^(? *[*-] *)\[(?[ xX])\]/.freeze + TASK_PATTERN_HTML = /^
  • \[(?[ xX])\]/.freeze + + # Change the state of a task list item for this Taskable. Edit the object's + # description by finding the nth task item and changing its checkbox + # placeholder to "[x]" if +checked+ is true, or "[ ]" if it's false. + # Note: task numbering starts with 1 + def update_nth_task(n, checked) + index = 0 + check_char = checked ? 'x' : ' ' + + # Do this instead of using #gsub! so that ActiveRecord detects that a field + # has changed. + self.description = self.description.gsub(TASK_PATTERN_MD) do |match| + index += 1 + case index + when n then "#{$LAST_MATCH_INFO[:bullet]}[#{check_char}]" + else match + end + end + + save + end + + # Return true if this object's description has any task list items. + def tasks? + description && description.match(TASK_PATTERN_MD) + end + + # Return a string that describes the current state of this Taskable's task + # list items, e.g. "20 tasks (12 done, 8 unfinished)" + def task_status + return nil unless description + + num_tasks = 0 + num_done = 0 + + description.scan(TASK_PATTERN_MD) do + num_tasks += 1 + num_done += 1 unless $LAST_MATCH_INFO[:checked] == ' ' + end + + "#{num_tasks} tasks (#{num_done} done, #{num_tasks - num_done} unfinished)" + end +end diff --git a/app/models/issue.rb b/app/models/issue.rb index 13152fdf94e..8a9e969248c 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -23,6 +23,7 @@ require 'file_size_validator' class Issue < ActiveRecord::Base include Issuable include InternalId + include Taskable ActsAsTaggableOn.strict_case_match = true diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index e0358c1889c..7c525b02f48 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -25,6 +25,7 @@ require Rails.root.join("lib/static_model") class MergeRequest < ActiveRecord::Base include Issuable + include Taskable include InternalId belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index a0e57144435..5b2746ffecf 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -8,9 +8,14 @@ module Issues Issues::ReopenService.new(project, current_user, {}).execute(issue) when 'close' Issues::CloseService.new(project, current_user, {}).execute(issue) + when 'task_check' + issue.update_nth_task(params[:task_num].to_i, true) + when 'task_uncheck' + issue.update_nth_task(params[:task_num].to_i, false) end - if params.present? && issue.update_attributes(params.except(:state_event)) + if params.present? && issue.update_attributes(params.except(:state_event, + :task_num)) issue.reset_events_cache if issue.previous_changes.include?('milestone_id') @@ -28,5 +33,12 @@ module Issues issue end + + private + + def update_task(issue, params, checked) + issue.update_nth_task(params[:task_num].to_i, checked) + params.except!(:task_num) + end end end diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 6e416a0080c..fc26619cd17 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -17,9 +17,15 @@ module MergeRequests MergeRequests::ReopenService.new(project, current_user, {}).execute(merge_request) when 'close' MergeRequests::CloseService.new(project, current_user, {}).execute(merge_request) + when 'task_check' + merge_request.update_nth_task(params[:task_num].to_i, true) + when 'task_uncheck' + merge_request.update_nth_task(params[:task_num].to_i, false) end - if params.present? && merge_request.update_attributes(params.except(:state_event)) + if params.present? && merge_request.update_attributes( + params.except(:state_event, :task_num) + ) merge_request.reset_events_cache if merge_request.previous_changes.include?('milestone_id') diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index e089b5fa1cf..b125706781c 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -26,6 +26,10 @@ %span %i.fa.fa-clock-o = issue.milestone.title + - if issue.tasks? + %span.task-status + = issue.task_status + .pull-right %small updated #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_update_ago')} diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 4c1ea098d98..e1849b3f8b8 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -48,7 +48,7 @@ .description .wiki = preserve do - = markdown @issue.description + = markdown(@issue.description, parse_tasks: true) .context %cite.cgray = render partial: 'issue_context', locals: { issue: @issue } diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 647e8873e9e..1ee2e1bdae8 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -27,7 +27,9 @@ %span %i.fa.fa-clock-o = merge_request.milestone.title - + - if merge_request.tasks? + %span.task-status + = merge_request.task_status .pull-right %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')} diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index f1aaba2010d..7e5a4eda508 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -18,7 +18,7 @@ .description .wiki = preserve do - = markdown @merge_request.description + = markdown(@merge_request.description, parse_tasks: true) .context %cite.cgray diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 709a74fe21e..17512a51658 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -33,6 +33,11 @@ module Gitlab attr_reader :html_options + def gfm_with_tasks(text, project = @project, html_options = {}) + text = gfm(text, project, html_options) + parse_tasks(text) + end + # Public: Parse the provided text with GitLab-Flavored Markdown # # text - the source text @@ -265,5 +270,24 @@ module Gitlab ) link_to("#{prefix_text}##{identifier}", url, options) end + + # Turn list items that start with "[ ]" into HTML checkbox inputs. + def parse_tasks(text) + li_tag = '
  • ' + unchecked_box = '' + checked_box = unchecked_box.sub(/\/>$/, 'checked="checked" />') + + # Regexp captures don't seem to work when +text+ is an + # ActiveSupport::SafeBuffer, hence the `String.new` + String.new(text).gsub(Taskable::TASK_PATTERN_HTML) do + checked = $LAST_MATCH_INFO[:checked].downcase == 'x' + + if checked + "#{li_tag}#{checked_box}" + else + "#{li_tag}#{unchecked_box}" + end + end + end end end diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index bb225f1acd8..c3378d6a18f 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -47,6 +47,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML unless @template.instance_variable_get("@project_wiki") || @project.nil? full_document = h.create_relative_links(full_document) end - h.gfm(full_document) + if @options[:parse_tasks] + h.gfm_with_tasks(full_document) + else + h.gfm(full_document) + end end end -- cgit v1.2.1 From fecd9c0cb22eda0a208042c568d8d833a1bd6292 Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Sun, 5 Oct 2014 21:17:28 -0500 Subject: Add specs for tasks Add tests for the new task list functionality in the Markdown parser and in issues and merge requests. --- spec/helpers/gitlab_markdown_helper_spec.rb | 101 +++++++++++++++++++++++++++- spec/models/issue_spec.rb | 4 ++ spec/models/merge_request_spec.rb | 4 ++ spec/support/taskable_shared_examples.rb | 42 ++++++++++++ 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 spec/support/taskable_shared_examples.rb diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 73b3d91e96e..15033f07432 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -616,7 +616,7 @@ describe GitlabMarkdownHelper do end end - describe "markdwon for empty repository" do + describe 'markdown for empty repository' do before do @project = empty_project @repository = empty_project.repository @@ -652,4 +652,103 @@ describe GitlabMarkdownHelper do helper.render_wiki_content(@wiki) end end + + describe '#gfm_with_tasks' do + before(:all) do + @source_text_asterisk = <(txt){ subject.description = txt } } end + + it_behaves_like 'a Taskable' do + let(:subject) { create :issue } + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index c40f75290ed..7b0d261d72f 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -119,4 +119,8 @@ describe MergeRequest do let(:backref_text) { "merge request !#{subject.iid}" } let(:set_mentionable_text) { ->(txt){ subject.title = txt } } end + + it_behaves_like 'a Taskable' do + let(:subject) { create :merge_request, :simple } + end end diff --git a/spec/support/taskable_shared_examples.rb b/spec/support/taskable_shared_examples.rb new file mode 100644 index 00000000000..42252675683 --- /dev/null +++ b/spec/support/taskable_shared_examples.rb @@ -0,0 +1,42 @@ +# Specs for task state functionality for issues and merge requests. +# +# Requires a context containing: +# let(:subject) { Issue or MergeRequest } +shared_examples 'a Taskable' do + before do + subject.description = < Date: Sun, 5 Oct 2014 22:04:58 -0500 Subject: Update docs for task lists --- CHANGELOG | 1 + doc/markdown/markdown.md | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 857a5bc9234..14bb88f22a5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,7 @@ v 7.4.0 - Add Pushover service integration (Sullivan Senechal) - Add select field type for services options (Sullivan Senechal) - Add cross-project references to the Markdown parser (Vinnie Okada) + - Add task lists to issue and merge request descriptions (Vinnie Okada) v 7.3.2 - Fix creating new file via web editor diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md index 5c095ed1487..6d96da76ad7 100644 --- a/doc/markdown/markdown.md +++ b/doc/markdown/markdown.md @@ -10,6 +10,7 @@ * [Code and Syntax Highlighting](#code-and-syntax-highlighting) * [Emoji](#emoji) * [Special GitLab references](#special-gitlab-references) +* [Task lists](#task-lists) **[Standard Markdown](#standard-markdown)** @@ -183,6 +184,18 @@ GFM also recognizes references to commits, issues, and merge requests in other p - namespace/project!123 : for merge requests - namespace/project@1234567 : for commits +## Task Lists + +You can add task lists to merge request and issue descriptions to keep track of to-do items. To create a task, add an unordered list to the description in an issue or merge request, formatted like so: + +```no-highlight +* [x] Completed task +* [ ] Unfinished task + * [x] Nested task +``` + +Task lists can only be created in descriptions, not in titles or comments. Task item state can be managed by editing the description's Markdown or by clicking the rendered checkboxes. + # Standard Markdown ## Headers -- cgit v1.2.1 From 31bc42de57b3cfd7bf068df06d15372307b8661b Mon Sep 17 00:00:00 2001 From: Vinnie Okada Date: Mon, 6 Oct 2014 01:59:03 -0500 Subject: Add Spinach tests for task lists --- features/project/issues/issues.feature | 33 ++++++++++++++++++++++++++++++++ features/project/merge_requests.feature | 33 ++++++++++++++++++++++++++++++++ features/steps/project/issues/issues.rb | 26 +++++++++++++++++++++++++ features/steps/project/merge_requests.rb | 14 ++++++++++++++ features/steps/shared/markdown.rb | 30 +++++++++++++++++++++++++++++ features/steps/shared/note.rb | 14 ++++++++++++++ features/steps/shared/paths.rb | 20 +++++++++++++++++++ 7 files changed, 170 insertions(+) diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature index ae6a03ce865..e989569ccd4 100644 --- a/features/project/issues/issues.feature +++ b/features/project/issues/issues.feature @@ -126,3 +126,36 @@ Feature: Project Issues When I click label 'bug' And I should see "Release 0.4" in issues And I should not see "Tweet control" in issues + + Scenario: Issue description should render task checkboxes + Given project "Shop" has "Tasks-open" open issue with task markdown + When I visit issue page "Tasks-open" + Then I should see task checkboxes in the description + + @javascript + Scenario: Issue notes should not render task checkboxes + Given project "Shop" has "Tasks-open" open issue with task markdown + When I visit issue page "Tasks-open" + And I leave a comment with task markdown + Then I should not see task checkboxes in the comment + + # Task status in issues list + + Scenario: Issues list should display task status + Given project "Shop" has "Tasks-open" open issue with task markdown + When I visit project "Shop" issues page + Then I should see the task status for issue "Tasks-open" + + # Toggling task items + + @javascript + Scenario: Task checkboxes should be enabled for an open issue + Given project "Shop" has "Tasks-open" open issue with task markdown + When I visit issue page "Tasks-open" + Then Task checkboxes should be enabled + + @javascript + Scenario: Task checkboxes should be disabled for a closed issue + Given project "Shop" has "Tasks-closed" closed issue with task markdown + When I visit issue page "Tasks-closed" + Then Task checkboxes should be disabled diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index f8dccc15c0e..bad83191371 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -96,6 +96,16 @@ Feature: Project Merge Requests And I leave a comment with a header containing "Comment with a header" Then The comment with the header should not have an ID + Scenario: Merge request description should render task checkboxes + Given project "Shop" has "MR-task-open" open MR with task markdown + When I visit merge request page "MR-task-open" + Then I should see task checkboxes in the description + + Scenario: Merge request notes should not render task checkboxes + Given project "Shop" has "MR-task-open" open MR with task markdown + When I visit merge request page "MR-task-open" + Then I should not see task checkboxes in the comment + # Toggling inline comments @javascript @@ -157,3 +167,26 @@ Feature: Project Merge Requests And I leave a comment like "Line is wrong" on line 39 of the second file And I click Side-by-side Diff tab Then I should see comments on the side-by-side diff page + + # Task status in issues list + + @now + Scenario: Merge requests list should display task status + Given project "Shop" has "MR-task-open" open MR with task markdown + When I visit project "Shop" merge requests page + Then I should see the task status for merge request "MR-task-open" + + # Toggling task items + + @javascript + Scenario: Task checkboxes should be enabled for an open merge request + Given project "Shop" has "MR-task-open" open MR with task markdown + When I visit merge request page "MR-task-open" + Then Task checkboxes should be enabled + + @javascript + Scenario: Task checkboxes should be disabled for a closed merge request + Given project "Shop" has "MR-task-open" open MR with task markdown + And I visit merge request page "MR-task-open" + And I click link "Close" + Then Task checkboxes should be disabled diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index b55b3c6c8a2..26c3c7c14bc 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -153,6 +153,32 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps author: project.users.first) end + step 'project "Shop" has "Tasks-open" open issue with task markdown' do + desc_text = < Date: Mon, 6 Oct 2014 10:19:11 +0200 Subject: Fix failing api specs. --- spec/requests/api/namespaces_spec.rb | 3 +-- spec/requests/api/projects_spec.rb | 11 +++++++++-- spec/requests/api/users_spec.rb | 5 ++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb index d9d52468b15..b8943ea0762 100644 --- a/spec/requests/api/namespaces_spec.rb +++ b/spec/requests/api/namespaces_spec.rb @@ -20,8 +20,7 @@ describe API::API, api: true do response.status.should == 200 json_response.should be_an Array - # Admin namespace + 2 group namespaces - json_response.length.should == 3 + json_response.length.should == Namespace.count end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 571d8506277..aa1437c71aa 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -54,8 +54,15 @@ describe API::API, api: true do get api("/projects/all", admin) response.status.should == 200 json_response.should be_an Array - json_response.first['name'].should == project.name - json_response.first['owner']['username'].should == user.username + project_name = project.name + + json_response.detect { + |project| project['name'] == project_name + }['name'].should == project_name + + json_response.detect { + |project| project['owner']['username'] == user.username + }['owner']['username'].should == user.username end end end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index b0752ebe43c..bc1598273be 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -20,7 +20,10 @@ describe API::API, api: true do get api("/users", user) response.status.should == 200 json_response.should be_an Array - json_response.first['username'].should == user.username + username = user.username + json_response.detect { + |user| user['username'] == username + }['username'].should == username end end -- cgit v1.2.1 From 20179772140ff0bdc2d61852c0a4f48ee6e4a2d0 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 3 Oct 2014 16:24:11 +0200 Subject: Use only webhook for slack service integration. --- app/controllers/projects/services_controller.rb | 2 +- app/models/project_services/slack_service.rb | 15 ++++++--------- features/steps/project/services.rb | 8 ++------ 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 4c558e137ea..31ce9581e5f 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -40,7 +40,7 @@ class Projects::ServicesController < Projects::ApplicationController def service_params params.require(:service).permit( :title, :token, :type, :active, :api_key, :subdomain, - :room, :recipients, :project_url, + :room, :recipients, :project_url, :webhook :user_key, :device, :priority, :sound ) end diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 4bda93f6006..2174919346d 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -13,10 +13,8 @@ # class SlackService < Service - prop_accessor :room, :subdomain, :token - validates :room, presence: true, if: :activated? - validates :subdomain, presence: true, if: :activated? - validates :token, presence: true, if: :activated? + prop_accessor :webhook + validates :webhook, presence: true, if: :activated? def title 'Slack' @@ -32,9 +30,7 @@ class SlackService < Service def fields [ - { type: 'text', name: 'subdomain', placeholder: '' }, - { type: 'text', name: 'token', placeholder: '' }, - { type: 'text', name: 'room', placeholder: 'Ex. #general' }, + { type: 'text', name: 'webhook', placeholder: '' } ] end @@ -44,9 +40,10 @@ class SlackService < Service project_name: project_name )) + credentials = webhook.match(/(\w*).slack.com.*token=(\w*)/) + subdomain = credentials[1] + token = credentials[2] notifier = Slack::Notifier.new(subdomain, token) - notifier.channel = room - notifier.username = 'GitLab' notifier.ping(message.pretext, attachments: message.attachments) end diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb index d816fcafbaa..5bd60f99c84 100644 --- a/features/steps/project/services.rb +++ b/features/steps/project/services.rb @@ -108,16 +108,12 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps step 'I fill Slack settings' do check 'Active' - fill_in 'Subdomain', with: 'gitlab' - fill_in 'Room', with: '#gitlab' - fill_in 'Token', with: 'verySecret' + fill_in 'Webhook', with: 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' click_button 'Save' end step 'I should see Slack service settings saved' do - find_field('Subdomain').value.should == 'gitlab' - find_field('Room').value.should == '#gitlab' - find_field('Token').value.should == 'verySecret' + find_field('Webhook').value.should == 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' end step 'I click Pushover service link' do -- cgit v1.2.1 From 216fb6ee07b80c2cb6cd78fdcb52c898fa2f41ea Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 3 Oct 2014 18:59:57 +0200 Subject: Fix slack service speck. --- spec/models/slack_service_spec.rb | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb index 4576913b473..5f919d97300 100644 --- a/spec/models/slack_service_spec.rb +++ b/spec/models/slack_service_spec.rb @@ -26,9 +26,7 @@ describe SlackService do subject.active = true end - it { should validate_presence_of :room } - it { should validate_presence_of :subdomain } - it { should validate_presence_of :token } + it { should validate_presence_of :webhook } end end @@ -37,20 +35,17 @@ describe SlackService do let(:user) { create(:user) } let(:project) { create(:project) } let(:sample_data) { GitPushService.new.sample_data(project, user) } - let(:subdomain) { 'gitlab' } - let(:token) { 'verySecret' } + let(:webhook) { 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' } let(:api_url) { - "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}" + 'https://gitlabhq.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI' } before do slack.stub( project: project, project_id: project.id, - room: '#gitlab', service_hook: true, - subdomain: subdomain, - token: token + webhook: webhook ) WebMock.stub_request(:post, api_url) -- cgit v1.2.1 From e5998adc26f66b2b84cbcc28e98f3fc8f89b4696 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 6 Oct 2014 10:42:03 +0200 Subject: Accommodate new webhook url format. --- app/models/project_services/slack_service.rb | 12 +++++++----- spec/models/slack_service_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 2174919346d..dfa1e9c9820 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -40,11 +40,13 @@ class SlackService < Service project_name: project_name )) - credentials = webhook.match(/(\w*).slack.com.*token=(\w*)/) - subdomain = credentials[1] - token = credentials[2] - notifier = Slack::Notifier.new(subdomain, token) - notifier.ping(message.pretext, attachments: message.attachments) + credentials = webhook.match(/(\w*).slack.com.*services\/(.*)/) + if credentials.present? + subdomain = credentials[1] + token = credentials[2].split("token=").last + notifier = Slack::Notifier.new(subdomain, token) + notifier.ping(message.pretext, attachments: message.attachments) + end end private diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb index 5f919d97300..3e555193b32 100644 --- a/spec/models/slack_service_spec.rb +++ b/spec/models/slack_service_spec.rb @@ -32,10 +32,12 @@ describe SlackService do describe "Execute" do let(:slack) { SlackService.new } + let(:slack_service) { SlackService.new } let(:user) { create(:user) } let(:project) { create(:project) } let(:sample_data) { GitPushService.new.sample_data(project, user) } let(:webhook) { 'https://gitlabhq.slack.com/services/hooks?token=cdIj4r4LfXUOySDUjp0tk3OI' } + let(:new_webhook) { 'https://hooks.gitlabhq.slack.com/services/cdIj4r4LfXUOySDUjp0tk3OI' } let(:api_url) { 'https://gitlabhq.slack.com/services/hooks/incoming-webhook?token=cdIj4r4LfXUOySDUjp0tk3OI' } @@ -56,5 +58,24 @@ describe SlackService do WebMock.should have_requested(:post, api_url).once end + + context 'with new webhook syntax' do + before do + slack_service.stub( + project: project, + project_id: project.id, + service_hook: true, + webhook: new_webhook + ) + + WebMock.stub_request(:post, api_url) + end + + it "should call Slack API" do + slack_service.execute(sample_data) + + WebMock.should have_requested(:post, api_url).once + end + end end end -- cgit v1.2.1 From 1e7e1d52b1945b7a854e2242b72af3f419bcda76 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 6 Oct 2014 10:45:17 +0200 Subject: Changes to slack service structure added to changelog. --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 857a5bc9234..c33600888df 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,7 @@ v 7.4.0 - API: Add support for forking a project via the API (Bernhard Kaindl) - API: filter project issues by milestone (Julien Bianchi) - Fail harder in the backup script + - Changes to Slack service structure, only webhook url needed - Zen mode for wiki and milestones (Robert Schilling) - Move Emoji parsing to html-pipeline-gitlab (Robert Schilling) - Font Awesome 4.2 integration (Sullivan Senechal) -- cgit v1.2.1 From ce3fb02ea0bab3530bcca116e389c2dd98ba1a68 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 6 Oct 2014 12:27:13 +0300 Subject: Bump gitlab_git Signed-off-by: Dmitriy Zaporozhets --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 72b19549896..c6be76f4ecc 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,7 @@ gem 'omniauth-shibboleth' # Extracting information from a git repository # Provide access to Gitlab::Git library -gem "gitlab_git", '7.0.0.rc8' +gem "gitlab_git", '7.0.0.rc9' # Ruby/Rack Git Smart-HTTP Server Handler gem 'gitlab-grack', '~> 2.0.0.pre', require: 'grack' diff --git a/Gemfile.lock b/Gemfile.lock index 30e89e90d8f..babb23ed606 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,7 +179,7 @@ GEM mime-types (~> 1.19) gitlab_emoji (0.0.1.1) emoji (~> 1.0.1) - gitlab_git (7.0.0.rc8) + gitlab_git (7.0.0.rc9) activesupport (~> 4.0) charlock_holmes (~> 0.6) gitlab-linguist (~> 3.0) @@ -622,7 +622,7 @@ DEPENDENCIES gitlab-grack (~> 2.0.0.pre) gitlab-linguist (~> 3.0.0) gitlab_emoji (~> 0.0.1.1) - gitlab_git (= 7.0.0.rc8) + gitlab_git (= 7.0.0.rc9) gitlab_meta (= 7.0) gitlab_omniauth-ldap (= 1.1.0) gollum-lib (~> 3.0.0) -- cgit v1.2.1 From 1db8d3104cfab111771a7afbaa015e989640fde4 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 6 Oct 2014 11:51:15 +0200 Subject: Add missing comma. --- app/controllers/projects/services_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 31ce9581e5f..b50f6286459 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -40,7 +40,7 @@ class Projects::ServicesController < Projects::ApplicationController def service_params params.require(:service).permit( :title, :token, :type, :active, :api_key, :subdomain, - :room, :recipients, :project_url, :webhook + :room, :recipients, :project_url, :webhook, :user_key, :device, :priority, :sound ) end -- cgit v1.2.1 From 46b7a3f8f550bce35a206ef8e36c9d1072eac746 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 6 Oct 2014 15:07:36 +0300 Subject: Prevent PG::Error exception when check commit reference on commit Signed-off-by: Dmitriy Zaporozhets --- app/models/note.rb | 13 +++++++++---- spec/models/note_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/models/note.rb b/app/models/note.rb index 0c1d792ca9a..6f1b1a4da94 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -47,7 +47,7 @@ class Note < ActiveRecord::Base scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) } scope :inline, ->{ where("line_code IS NOT NULL") } scope :not_inline, ->{ where(line_code: [nil, '']) } - + scope :system, ->{ where(system: true) } scope :common, ->{ where(noteable_type: ["", nil]) } scope :fresh, ->{ order("created_at ASC, id ASC") } scope :inc_author_project, ->{ includes(:project, :author) } @@ -168,9 +168,14 @@ class Note < ActiveRecord::Base # Determine whether or not a cross-reference note already exists. def cross_reference_exists?(noteable, mentioner) gfm_reference = mentioner_gfm_ref(noteable, mentioner) - - where(['noteable_id = ? and system = ? and note like ?', - noteable.id, true, "_mentioned in #{gfm_reference}_"]).any? + notes = if noteable.is_a?(Commit) + where(commit_id: noteable.id) + else + where(noteable_id: noteable.id) + end + + notes.where('note like ?', "_mentioned in #{gfm_reference}_"). + system.any? end def search(query) diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index c88a03beb0c..eeecd714a28 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -258,6 +258,17 @@ describe Note do its(:commit_id) { should == commit.id } its(:note) { should == "_mentioned in issue ##{issue.iid}_" } end + + context 'commit from commit' do + let(:parent_commit) { commit.parents.first } + subject { Note.create_cross_reference_note(commit, parent_commit, author, project) } + + it { should be_valid } + its(:noteable_type) { should == "Commit" } + its(:noteable_id) { should be_nil } + its(:commit_id) { should == commit.id } + its(:note) { should == "_mentioned in commit #{parent_commit.id[0...6]}_" } + end end describe '#cross_reference_exists?' do @@ -278,6 +289,15 @@ describe Note do it 'detects if a mentionable has not already been mentioned' do Note.cross_reference_exists?(issue, commit1).should be_false end + + context 'commit on commit' do + before do + Note.create_cross_reference_note(commit0, commit1, author, project) + end + + it { Note.cross_reference_exists?(commit0, commit1).should be_true } + it { Note.cross_reference_exists?(commit1, commit0).should be_false } + end end describe '#system?' do -- cgit v1.2.1 From 299114948bc12c92fb182e739b7cbb47d310d9e6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 6 Oct 2014 15:15:39 +0300 Subject: Use only escaped auto_link Signed-off-by: Dmitriy Zaporozhets --- app/helpers/application_helper.rb | 4 ++++ app/views/groups/show.html.haml | 2 +- app/views/projects/_home_panel.html.haml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 34d312b4100..e8a9c2efadf 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -259,4 +259,8 @@ module ApplicationHelper super end + + def escaped_autolink(text) + auto_link ERB::Util.html_escape(text), link: :urls + end end diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 4f4fc537d34..d876e87852c 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -24,7 +24,7 @@ = @group.name - if @group.description.present? %p - = auto_link @group.description, link: :urls + = escaped_autolink(@group.description) = render "projects", projects: @projects - if current_user .prepend-top-20 diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index cdbdec698fa..672a91e0eef 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -3,7 +3,7 @@ .project-home-row .project-home-desc - if @project.description.present? - = auto_link ERB::Util.html_escape(@project.description), link: :urls + = escaped_autolink(@project.description) - if can?(current_user, :admin_project, @project) – = link_to 'Edit', edit_project_path -- cgit v1.2.1 From f815115de69c0bd746031e3389acfcdf2a306a75 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 6 Oct 2014 16:18:25 +0300 Subject: Protect from forgery with exception Signed-off-by: Dmitriy Zaporozhets --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1a5215ca309..13d8d2a3e0a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -13,7 +13,7 @@ class ApplicationController < ActionController::Base before_filter :configure_permitted_parameters, if: :devise_controller? before_filter :require_email, unless: :devise_controller? - protect_from_forgery + protect_from_forgery with: :exception helper_method :abilities, :can? -- cgit v1.2.1 From 9535ce2caa7122e3f1be8932660c3d53e0457bbc Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 6 Oct 2014 15:07:48 +0200 Subject: Preventing some duplication in MR feature tests by adding a different comment. --- features/project/merge_requests.feature | 6 ++---- features/steps/project/merge_requests.rb | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature index f8dccc15c0e..60302c44ddb 100644 --- a/features/project/merge_requests.feature +++ b/features/project/merge_requests.feature @@ -105,7 +105,7 @@ Feature: Project Merge Requests And I switch to the diff tab And I leave a comment like "Line is wrong" on line 39 of the second file And I click link "Hide inline discussion" of the second file - Then I should not see a comment like "Line is wrong" in the second file + Then I should not see a comment like "Line is wrong here" in the second file @javascript Scenario: I show comments on a merge request diff with comments in a single file @@ -113,8 +113,6 @@ Feature: Project Merge Requests And I visit merge request page "Bug NS-05" And I switch to the diff tab And I leave a comment like "Line is wrong" on line 39 of the second file - And I click link "Hide inline discussion" of the second file - And I click link "Show inline discussion" of the second file Then I should see a comment like "Line is wrong" in the second file @javascript @@ -125,7 +123,7 @@ Feature: Project Merge Requests And I leave a comment like "Line is correct" on line 12 of the first file And I leave a comment like "Line is wrong" on line 39 of the second file And I click link "Hide inline discussion" of the second file - Then I should not see a comment like "Line is wrong" in the second file + Then I should not see a comment like "Line is wrong here" in the second file And I should still see a comment like "Line is correct" in the first file @javascript diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index c101c696253..fba03c2fc64 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -211,6 +211,18 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps 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" + 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-text' do + page.should have_visible_content "Line is wrong here" + end + end + step 'I leave a comment like "Line is correct" on line 12 of the first file' do init_diff_note_first_file @@ -228,13 +240,9 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps init_diff_note_second_file within(".js-discussion-note-form") do - fill_in "note_note", with: "Line is wrong" + fill_in "note_note", with: "Line is wrong on here" click_button "Add Comment" end - - within ".files [id^=diff]:nth-child(2) .note-text" do - page.should have_content "Line is wrong" - end end step 'I should still see a comment like "Line is correct" in the first file' do -- cgit v1.2.1 From eceef546d19c16d16772868a05e6769907442f83 Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Mon, 6 Oct 2014 16:50:24 +0200 Subject: Add slack service migration. --- .../20141006143943_move_slack_service_to_webhook.rb | 17 +++++++++++++++++ db/schema.rb | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20141006143943_move_slack_service_to_webhook.rb diff --git a/db/migrate/20141006143943_move_slack_service_to_webhook.rb b/db/migrate/20141006143943_move_slack_service_to_webhook.rb new file mode 100644 index 00000000000..4b62b223cbf --- /dev/null +++ b/db/migrate/20141006143943_move_slack_service_to_webhook.rb @@ -0,0 +1,17 @@ +class MoveSlackServiceToWebhook < ActiveRecord::Migration + def change + SlackService.all.each do |slack_service| + if ["token", "subdomain"].all? { |property| slack_service.properties.key? property } + token = slack_service.properties['token'] + subdomain = slack_service.properties['subdomain'] + webhook = "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}" + slack_service.properties['webhook'] = webhook + slack_service.properties.delete('token') + slack_service.properties.delete('subdomain') + # Room is configured on the Slack side + slack_service.properties.delete('room') + slack_service.save! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4e249caa022..84fd1256677 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140914173417) do +ActiveRecord::Schema.define(version: 20141006143943) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" -- cgit v1.2.1 From 897d69d6d5b88c964a94742d291d2d3a6e5b56c3 Mon Sep 17 00:00:00 2001 From: Ben Bodenmiller Date: Mon, 6 Oct 2014 09:26:40 -0700 Subject: number formatting fix --- doc/install/requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 49edf36f574..e2175399ec8 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -85,7 +85,7 @@ Redis stores all user sessions and the background task queue. The storage requirements for Redis are minimal, about 25kB per user. Sidekiq processes the background jobs with a multithreaded process. This process starts with the entire Rails stack (200MB+) but it can grow over time due to memory leaks. -On a very active server (10.000 active users) the Sidekiq process can use 1GB+ of memory. +On a very active server (10,000 active users) the Sidekiq process can use 1GB+ of memory. ## Supported webbrowsers -- cgit v1.2.1 From 014eeb2e0bf6ec8c969e1b188b9085b5e4166b5f Mon Sep 17 00:00:00 2001 From: Ben Bodenmiller Date: Mon, 6 Oct 2014 09:27:38 -0700 Subject: webbrowsers -> web browsers --- doc/install/requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 49edf36f574..fdd4e29e353 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -87,7 +87,7 @@ Sidekiq processes the background jobs with a multithreaded process. This process starts with the entire Rails stack (200MB+) but it can grow over time due to memory leaks. On a very active server (10.000 active users) the Sidekiq process can use 1GB+ of memory. -## Supported webbrowsers +## Supported web browsers - Chrome (Latest stable version) - Firefox (Latest released version) -- cgit v1.2.1 From fd8d1d9b62066766c96610b7d42b20fa0e84b0ac Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 7 Oct 2014 11:54:00 +0300 Subject: Snippets: rename public to internal --- app/controllers/snippets_controller.rb | 8 ++++---- app/models/snippet.rb | 2 +- app/views/shared/snippets/_form.html.haml | 2 +- app/views/snippets/current_user_index.html.haml | 8 ++++---- features/snippets/user.feature | 2 +- features/steps/snippets/snippets.rb | 2 +- features/steps/snippets/user.rb | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 3927584235e..5904dbbceda 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -14,7 +14,7 @@ class SnippetsController < ApplicationController layout 'navless' def index - @snippets = Snippet.are_public.fresh.non_expired.page(params[:page]).per(20) + @snippets = Snippet.are_internal.fresh.non_expired.page(params[:page]).per(20) end def user_index @@ -26,15 +26,15 @@ class SnippetsController < ApplicationController if @user == current_user @snippets = case params[:scope] - when 'are_public' then - @snippets.are_public + when 'are_internal' then + @snippets.are_internal when 'are_private' then @snippets.are_private else @snippets end else - @snippets = @snippets.are_public + @snippets = @snippets.are_internal end @snippets = @snippets.page(params[:page]).per(20) diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 80c1af8f337..addde2d106a 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -32,7 +32,7 @@ class Snippet < ActiveRecord::Base validates :content, presence: true # Scopes - scope :are_public, -> { where(private: false) } + scope :are_internal, -> { where(private: false) } scope :are_private, -> { where(private: true) } scope :fresh, -> { order("created_at DESC") } scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml index 49ea8460e7d..f4d74045f77 100644 --- a/app/views/shared/snippets/_form.html.haml +++ b/app/views/shared/snippets/_form.html.haml @@ -23,7 +23,7 @@ = f.label :private_false, class: 'radio-label' do = f.radio_button :private, false %span - %strong Public + %strong Internal (GitLab users can see this snippet) .form-group diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml index e3edd856983..14b5b072ec2 100644 --- a/app/views/snippets/current_user_index.html.haml +++ b/app/views/snippets/current_user_index.html.haml @@ -23,11 +23,11 @@ Private %span.pull-right = @user.snippets.are_private.count - = nav_tab :scope, 'are_public' do - = link_to user_snippets_path(@user, scope: 'are_public') do - Public + = nav_tab :scope, 'are_internal' do + = link_to user_snippets_path(@user, scope: 'are_internal') do + Internal %span.pull-right - = @user.snippets.are_public.count + = @user.snippets.are_internal.count .col-md-9.my-snippets = render 'snippets' diff --git a/features/snippets/user.feature b/features/snippets/user.feature index 424794f73fd..ae34e8e7ffa 100644 --- a/features/snippets/user.feature +++ b/features/snippets/user.feature @@ -18,6 +18,6 @@ Feature: Snippets User Scenario: I can see only my public snippets Given I visit my snippets page - And I click "Public" filter + And I click "Internal" filter Then I should see "Personal snippet one" in snippets And I should not see "Personal snippet private" in snippets diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb index dedbdd2c4f0..de936db85ee 100644 --- a/features/steps/snippets/snippets.rb +++ b/features/steps/snippets/snippets.rb @@ -46,7 +46,7 @@ class Spinach::Features::Snippets < Spinach::FeatureSteps end step 'I uncheck "Private" checkbox' do - choose "Public" + choose "Internal" click_button "Save" end diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index ca9aa64bee6..c41bc436142 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -23,9 +23,9 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps page.should_not have_content "Personal snippet private" end - step 'I click "Public" filter' do + step 'I click "Internal" filter' do within('.nav-stacked') do - click_link "Public" + click_link "Internal" end end -- cgit v1.2.1 From bbc52b000008c9020d2a38dafc09ff3341a69cae Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Tue, 7 Oct 2014 11:48:25 +0200 Subject: Use double quotes because we are inserting password now. --- db/fixtures/production/001_admin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb index f84d0903910..e0b13db020d 100644 --- a/db/fixtures/production/001_admin.rb +++ b/db/fixtures/production/001_admin.rb @@ -21,7 +21,7 @@ admin.save! admin.confirm! if admin.valid? -puts %q[ +puts %Q[ Administrator account created: login.........root -- cgit v1.2.1 From 7dcbf350197de169f3ca85b730c852e14c8feaa2 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 7 Oct 2014 13:16:19 +0200 Subject: Replace www.gitlab.com with about.gitlab.com --- CONTRIBUTING.md | 4 ++-- PROCESS.md | 6 +++--- app/helpers/application_helper.rb | 8 ++++++++ app/views/help/index.html.haml | 4 ++-- app/views/shared/_promo.html.haml | 4 ++-- doc/development/architecture.md | 2 +- doc/install/installation.md | 4 ++-- doc/release/security.md | 4 ++-- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d1e8270f46..ed49080d57a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ By submitting code as an individual you agree to the [individual contributor lic ## Security vulnerability disclosure -Please report suspected security vulnerabilities in private to support@gitlab.com, also see the [disclosure section on the GitLab.com website](http://www.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. +Please report suspected security vulnerabilities in private to support@gitlab.com, also see the [disclosure section on the GitLab.com website](http://about.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. ## Closing policy for issues and merge requests @@ -22,7 +22,7 @@ Issues and merge requests should be in English and contain appropriate language ## Issue tracker -To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/). +To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://about.gitlab.com/subscription/) and [consulting services](http://about.gitlab.com/consultancy/) are available from [GitLab.com](http://about.gitlab.com/). The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md). If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. diff --git a/PROCESS.md b/PROCESS.md index c3a787662f7..1dd28d6b670 100644 --- a/PROCESS.md +++ b/PROCESS.md @@ -18,7 +18,7 @@ Below we describe the contributing process to GitLab for two reasons. So that co - Responds to merge requests the issue team mentions them in and monitors for new merge requests - Provides feedback to the merge request submitter to improve the merge request (style, tests, etc.) - Mark merge requests 'ready-for-merge' when they meet the contribution guidelines -- Mention developer(s) based on the [list of members and their specialities](https://www.gitlab.com/core-team/) +- Mention developer(s) based on the [list of members and their specialities](https://about.gitlab.com/core-team/) - Closes merge requests with no feedback from the reporter for two weeks ## Priorities of the issue team @@ -30,7 +30,7 @@ Below we describe the contributing process to GitLab for two reasons. So that co ## Mentioning people -The most important thing is making sure valid issues receive feedback from the development team. Therefore the priority is mentioning developers that can help on those issue. Please select someone with relevant experience from [GitLab core team](https://www.gitlab.com/core-team/). If there is nobody mentioned with that expertise look in the commit history for the affected files to find someone. Avoid mentioning the lead developer, this is the person that is least likely to give a timely response. If the involvement of the lead developer is needed the other core team members will mention this person. +The most important thing is making sure valid issues receive feedback from the development team. Therefore the priority is mentioning developers that can help on those issue. Please select someone with relevant experience from [GitLab core team](https://about.gitlab.com/core-team/). If there is nobody mentioned with that expertise look in the commit history for the affected files to find someone. Avoid mentioning the lead developer, this is the person that is least likely to give a timely response. If the involvement of the lead developer is needed the other core team members will mention this person. ## Workflow labels @@ -79,7 +79,7 @@ Thanks for the issue report but we only support issues for the latest stable ver ### Support requests and configuration questions -Thanks for your interest in GitLab. We don't use the issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the #gitlab IRC channel on Freenode or the http://www.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. +Thanks for your interest in GitLab. We don't use the issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the #gitlab IRC channel on Freenode or the http://about.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. ### Code format diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e8a9c2efadf..021bd0a494c 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -263,4 +263,12 @@ module ApplicationHelper def escaped_autolink(text) auto_link ERB::Util.html_escape(text), link: :urls end + + def promo_host + 'about.gitlab.com' + end + + def promo_url + 'https://' + promo_host + end end diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml index 903e093e5fc..7b8193abfdf 100644 --- a/app/views/help/index.html.haml +++ b/app/views/help/index.html.haml @@ -14,7 +14,7 @@ %br Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises. %br - Read more about GitLab at #{link_to "www.gitlab.com", "https://www.gitlab.com/", target: "_blank"}. + Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank'}. %hr @@ -34,7 +34,7 @@ %ul.well-list %li See our website for - = link_to "getting help", "https://www.gitlab.com/getting-help/" + = link_to 'getting help', promo_url + '/getting-help/' %li Use the = link_to 'search bar', '#', onclick: 'Shortcuts.focusSearch(event)' diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml index 5675e43b05f..3400c345c4c 100644 --- a/app/views/shared/_promo.html.haml +++ b/app/views/shared/_promo.html.haml @@ -1,5 +1,5 @@ .gitlab-promo - = link_to "Homepage", "https://www.gitlab.com/" - = link_to "Blog", "https://www.gitlab.com/blog/" + = link_to 'Homepage', promo_url + = link_to "Blog", promo_url + '/blog/' = link_to "@gitlabhq", "https://twitter.com/gitlabhq" = link_to "Requests", "http://feedback.gitlab.com/" diff --git a/doc/development/architecture.md b/doc/development/architecture.md index 4624d9f60b6..c4813d22eaa 100644 --- a/doc/development/architecture.md +++ b/doc/development/architecture.md @@ -2,7 +2,7 @@ ## Software delivery -There are two editions of GitLab: [Enterprise Edition](https://www.gitlab.com/gitlab-ee/) (EE) and [Community Edition](https://www.gitlab.com/gitlab-ce/) (CE). GitLab CE is delivered via git from the [gitlabhq repository](https://gitlab.com/gitlab-org/gitlab-ce/tree/master). New versions of GitLab are released in stable branches and the master branch is for bleeding edge development. +There are two editions of GitLab: [Enterprise Edition](https://about.gitlab.com/gitlab-ee/) (EE) and [Community Edition](https://about.gitlab.com/gitlab-ce/) (CE). GitLab CE is delivered via git from the [gitlabhq repository](https://gitlab.com/gitlab-org/gitlab-ce/tree/master). New versions of GitLab are released in stable branches and the master branch is for bleeding edge development. EE releases are available not long after CE releases. To obtain the GitLab EE there is a [repository at gitlab.com](https://gitlab.com/subscribers/gitlab-ee). For more information about the release process see the section 'New versions and upgrading' in the readme. diff --git a/doc/install/installation.md b/doc/install/installation.md index af6e182cfa0..0d1a8da4d1b 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -6,13 +6,13 @@ Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitla ![Select latest branch](https://i.imgur.com/Lrdxk1k.png) -If the highest number stable branch is unclear please check the [GitLab Blog](https://www.gitlab.com/blog/) for installation guide links by version. +If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version. ## Important Notes This guide is long because it covers many cases and includes all commands you need, this is [one of the few installation scripts that actually works out of the box](https://twitter.com/robinvdvleuten/status/424163226532986880). -This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements. If you want to install on RHEL/CentOS we recommend using the [Omnibus packages](https://www.gitlab.com/downloads/). +This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements. If you want to install on RHEL/CentOS we recommend using the [Omnibus packages](https://about.gitlab.com/downloads/). This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please see [the installation section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#installation). diff --git a/doc/release/security.md b/doc/release/security.md index da442de6ee1..79d23c02ea4 100644 --- a/doc/release/security.md +++ b/doc/release/security.md @@ -8,7 +8,7 @@ Do a security release when there is a critical issue that needs to be addresses ## Security vulnerability disclosure -Please report suspected security vulnerabilities in private to , also see the [disclosure section on the GitLab.com website](http://www.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. +Please report suspected security vulnerabilities in private to , also see the [disclosure section on the GitLab.com website](http://about.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. ## Release Procedure @@ -21,7 +21,7 @@ Please report suspected security vulnerabilities in private to Date: Tue, 7 Oct 2014 15:11:18 +0300 Subject: Style merge request CI widget to match MR/Issue box Signed-off-by: Dmitriy Zaporozhets --- app/assets/javascripts/merge_request.js.coffee | 8 ---- .../stylesheets/sections/merge_requests.scss | 44 +++++++++++++++++++++- .../projects/merge_requests/show/_mr_ci.html.haml | 5 +-- .../merge_requests/show/_state_widget.html.haml | 10 ++--- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee index 203c721c30c..c0460a7ec4e 100644 --- a/app/assets/javascripts/merge_request.js.coffee +++ b/app/assets/javascripts/merge_request.js.coffee @@ -119,14 +119,6 @@ class MergeRequest else $('.ci_widget.ci-error').show() - switch state - when "success" - $('.mr-state-widget').addClass("panel-success") - when "failed" - $('.mr-state-widget').addClass("panel-danger") - when "running", "pending" - $('.mr-state-widget').addClass("panel-warning") - showCiCoverage: (coverage) -> cov_html = $('') cov_html.addClass('ci-coverage') diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index acaad519778..46e3884b302 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -104,7 +104,44 @@ } .mr-state-widget { - .panel-body { + background: #f9f9f9; + margin-bottom: 20px; + @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09)); + + .ci_widget { + padding: 10px 15px; + font-size: 15px; + border-bottom: 1px dashed #AAA; + + &.ci-success { + color: $bg_success; + border-color: $border_success; + } + + &.ci-pending { + color: #548; + border-color: #548; + } + + &.ci-running { + color: $bg_warning; + border-color: $border_warning; + } + + &.ci-failed { + color: $bg_danger; + border-color: $border_danger; + } + + &.ci-error { + color: $bg_danger; + border-color: $border_danger; + } + } + + .mr-widget-body { + padding: 10px 15px; + h4 { margin-top: 0px; } @@ -114,6 +151,11 @@ } } + .mr-widget-footer { + padding: 10px 15px; + border-top: 1px solid #EEE; + } + .ci-coverage { float: right; } diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml index dc64c096edc..941b15d3b32 100644 --- a/app/views/projects/merge_requests/show/_mr_ci.html.haml +++ b/app/views/projects/merge_requests/show/_mr_ci.html.haml @@ -20,9 +20,8 @@ = link_to "Build page", ci_build_details_path(@merge_request) .ci_widget - %strong - %i.fa.fa-spinner - Checking for CI status for #{@merge_request.last_commit_short_sha} + %i.fa.fa-spinner + Checking for CI status for #{@merge_request.last_commit_short_sha} .ci_widget.ci-error{style: "display:none"} %i.fa.fa-times diff --git a/app/views/projects/merge_requests/show/_state_widget.html.haml b/app/views/projects/merge_requests/show/_state_widget.html.haml index 5db77ab2754..2b58c865b2e 100644 --- a/app/views/projects/merge_requests/show/_state_widget.html.haml +++ b/app/views/projects/merge_requests/show/_state_widget.html.haml @@ -1,8 +1,8 @@ -.panel.mr-state-widget.panel-default +.mr-state-widget - if @merge_request.source_project.ci_service && @commits.any? - .panel-heading + .mr-widget-heading = render "projects/merge_requests/show/mr_ci" - .panel-body + .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" @@ -31,8 +31,8 @@ %br Try to use different branches or push new code. - - if !@closes_issues.empty? && @merge_request.open? - .panel-footer + - 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'} -- cgit v1.2.1 From 8fad7e63a3eac7e88026d82cf7fa3696a3cb379b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 7 Oct 2014 15:22:33 +0300 Subject: Add a bit of space between star icon and text Signed-off-by: Dmitriy Zaporozhets --- app/helpers/projects_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 6df7dae7314..2188b30a9af 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -128,9 +128,9 @@ module ProjectsHelper toggle_html = content_tag('span', class: 'toggle') do toggle_text = if starred - 'Unstar' + ' Unstar' else - 'Star' + ' Star' end content_tag('i', ' ', class: 'fa fa-star') + toggle_text -- cgit v1.2.1 From 0bf99f65577d1e0edda8f4e060159d927b308974 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 7 Oct 2014 16:05:24 +0300 Subject: Developers can push to wiki repo. Protected branches does not affect wiki repo any more Signed-off-by: Dmitriy Zaporozhets --- lib/api/internal.rb | 13 +++++++--- lib/gitlab/git_access.rb | 43 ++++++++++++++++++--------------- lib/gitlab/git_access_wiki.rb | 7 ++++++ spec/lib/gitlab/git_access_wiki_spec.rb | 22 +++++++++++++++++ 4 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 lib/gitlab/git_access_wiki.rb create mode 100644 spec/lib/gitlab/git_access_wiki_spec.rb diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 5f484f63418..94aa2f78c2e 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -14,13 +14,20 @@ module API # post "/allowed" do status 200 + project_path = params[:project] # Check for *.wiki repositories. # Strip out the .wiki from the pathname before finding the # project. This applies the correct project permissions to # the wiki repository as well. - project_path = params[:project] - project_path.gsub!(/\.wiki/,'') if project_path =~ /\.wiki/ + access = + if project_path =~ /\.wiki\Z/ + project_path = project_path[0..-6] + Gitlab::GitAccessWiki.new + else + Gitlab::GitAccess.new + end + project = Project.find_with_namespace(project_path) return false unless project @@ -32,7 +39,7 @@ module API return false unless actor - Gitlab::GitAccess.new.allowed?( + access.allowed?( actor, params[:action], project, diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 6247dd59867..b768a99a0e8 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -49,25 +49,7 @@ module Gitlab # Iterate over all changes to find if user allowed all of them to be applied changes.each do |change| - oldrev, newrev, ref = change.split(' ') - - action = if project.protected_branch?(branch_name(ref)) - # we dont allow force push to protected branch - if forced_push?(project, oldrev, newrev) - :force_push_code_to_protected_branches - # and we dont allow remove of protected branch - elsif newrev =~ /0000000/ - :remove_protected_branches - else - :push_code_to_protected_branches - end - elsif project.repository && project.repository.tag_names.include?(tag_name(ref)) - # Prevent any changes to existing git tag unless user has permissions - :admin_project - else - :push_code - end - unless user.can?(action, project) + unless change_allowed?(user, project, change) # If user does not have access to make at least one change - cancel all push return false end @@ -77,6 +59,29 @@ module Gitlab true end + def change_allowed?(user, project, change) + oldrev, newrev, ref = change.split(' ') + + action = if project.protected_branch?(branch_name(ref)) + # we dont allow force push to protected branch + if forced_push?(project, oldrev, newrev) + :force_push_code_to_protected_branches + # and we dont allow remove of protected branch + elsif newrev =~ /0000000/ + :remove_protected_branches + else + :push_code_to_protected_branches + end + elsif project.repository && project.repository.tag_names.include?(tag_name(ref)) + # Prevent any changes to existing git tag unless user has permissions + :admin_project + else + :push_code + end + + user.can?(action, project) + end + def forced_push?(project, oldrev, newrev) return false if project.empty_repo? diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb new file mode 100644 index 00000000000..9f0eb3be20f --- /dev/null +++ b/lib/gitlab/git_access_wiki.rb @@ -0,0 +1,7 @@ +module Gitlab + class GitAccessWiki < GitAccess + def change_allowed?(user, project, change) + user.can?(:write_wiki, project) + end + end +end diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb new file mode 100644 index 00000000000..ed5785b31e6 --- /dev/null +++ b/spec/lib/gitlab/git_access_wiki_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe Gitlab::GitAccessWiki do + let(:access) { Gitlab::GitAccessWiki.new } + let(:project) { create(:project) } + let(:user) { create(:user) } + + describe 'push_allowed?' do + before do + create(:protected_branch, name: 'master', project: project) + project.team << [user, :developer] + end + + subject { access.push_allowed?(user, project, changes) } + + it { should be_true } + end + + def changes + ['6f6d7e7ed 570e7b2ab refs/heads/master'] + end +end -- cgit v1.2.1 From 3386a82d5eb105f764e62e818bcec19b1c92be8e Mon Sep 17 00:00:00 2001 From: Job van der Voort Date: Tue, 7 Oct 2014 15:50:23 +0200 Subject: add references to gitlab flow article --- doc/workflow/gitlab_flow.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md index 947646c756a..70edea9c8d7 100644 --- a/doc/workflow/gitlab_flow.md +++ b/doc/workflow/gitlab_flow.md @@ -309,3 +309,8 @@ If you need to merge in another branch after starting explain the reason in the If you have not pushed your commits to a shared location yet you can also rebase on master or another feature branch. Do not merge in upstream if your code will work and merge cleanly without doing so, Linus even says that [you should never merge in upstream at random points, only at major releases](http://lwn.net/Articles/328438/). Merging only when needed prevents creating merge commits in your feature branch that later end up littering the master history. + +### References + +- [Sketch file](https://www.dropbox.com/s/58dvsj5votbwrzv/git_flows.sketch?dl=0) with vectors of images in this article +- [Git Flow by Vincent Driessen](http://nvie.com/posts/a-successful-git-branching-model/) -- cgit v1.2.1 From 06c91aa20e6a8aed383d0a623a558983705edcb9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 7 Oct 2014 17:28:55 +0300 Subject: Improve wiki path parsing in internal api Signed-off-by: Dmitriy Zaporozhets --- lib/api/internal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/internal.rb b/lib/api/internal.rb index 94aa2f78c2e..9ac659f50fd 100644 --- a/lib/api/internal.rb +++ b/lib/api/internal.rb @@ -22,7 +22,7 @@ module API # the wiki repository as well. access = if project_path =~ /\.wiki\Z/ - project_path = project_path[0..-6] + project_path.sub!(/\.wiki\Z/, '') Gitlab::GitAccessWiki.new else Gitlab::GitAccess.new -- cgit v1.2.1 From ceaebe233c00bbf0df2d2bd6e3c852752546ba42 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 7 Oct 2014 18:52:16 +0200 Subject: Remove outdated comment from commits_controller --- app/controllers/projects/commits_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb index 038645aa497..b7f09eb271d 100644 --- a/app/controllers/projects/commits_controller.rb +++ b/app/controllers/projects/commits_controller.rb @@ -17,7 +17,7 @@ class Projects::CommitsController < Projects::ApplicationController group(:commit_id).count respond_to do |format| - format.html # index.html.erb + format.html format.json { pager_json("projects/commits/_commits", @commits.size) } format.atom { render layout: false } end -- cgit v1.2.1 From 7984065776d0a32d245a3caa57342be83e45af2d Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 7 Oct 2014 22:39:45 +0200 Subject: Improve formatting of app/finders/README.md --- app/finders/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/finders/README.md b/app/finders/README.md index 47823c51efb..1f46518d230 100644 --- a/app/finders/README.md +++ b/app/finders/README.md @@ -1,7 +1,7 @@ # Finders -This type of classes responsible for collectiong items based on different conditions. -To prevent lookup methods in models like this: +This type of classes responsible for collection items based on different conditions. +To prevent lookup methods in models like this: ```ruby class Project @@ -13,10 +13,10 @@ end issues = project.issues_for_user_filtered_by(user, params) ``` -Better use this: +Better use this: ```ruby issues = IssuesFinder.new.execute(project, user, filter) ``` -It will help keep models thiner +It will help keep models thiner. -- cgit v1.2.1 From 901d099ceab49a32e83e14313c630e262a35a427 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 7 Oct 2014 23:28:38 +0200 Subject: Upcase missing feature names --- features/admin/active_tab.feature | 2 +- features/project/source/browse_files.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/admin/active_tab.feature b/features/admin/active_tab.feature index b28e16f0d6a..5de07e90e28 100644 --- a/features/admin/active_tab.feature +++ b/features/admin/active_tab.feature @@ -1,5 +1,5 @@ @admin -Feature: Admin active tab +Feature: Admin Active Tab Background: Given I sign in as an admin diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index 20ef7ac5702..83f23f66e34 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -1,4 +1,4 @@ -Feature: Project Source Browse files +Feature: Project Source Browse Files Background: Given I sign in as a user And I own project "Shop" -- cgit v1.2.1