Commit aefe2e952f33267ce38fb9270400f4f6f194d37b
1 parent
a8eb525e
Exists in
master
and in
4 other branches
Fixing unsafe use of Thread.current variable :current_user
Showing
14 changed files
with
196 additions
and
120 deletions
Show diff stats
app/controllers/application_controller.rb
| @@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base | @@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base | ||
| 2 | before_filter :authenticate_user! | 2 | before_filter :authenticate_user! |
| 3 | before_filter :reject_blocked! | 3 | before_filter :reject_blocked! |
| 4 | before_filter :check_password_expiration | 4 | before_filter :check_password_expiration |
| 5 | - before_filter :set_current_user_for_thread | 5 | + around_filter :set_current_user_for_thread |
| 6 | before_filter :add_abilities | 6 | before_filter :add_abilities |
| 7 | before_filter :dev_tools if Rails.env == 'development' | 7 | before_filter :dev_tools if Rails.env == 'development' |
| 8 | before_filter :default_headers | 8 | before_filter :default_headers |
| @@ -50,6 +50,11 @@ class ApplicationController < ActionController::Base | @@ -50,6 +50,11 @@ class ApplicationController < ActionController::Base | ||
| 50 | 50 | ||
| 51 | def set_current_user_for_thread | 51 | def set_current_user_for_thread |
| 52 | Thread.current[:current_user] = current_user | 52 | Thread.current[:current_user] = current_user |
| 53 | + begin | ||
| 54 | + yield | ||
| 55 | + ensure | ||
| 56 | + Thread.current[:current_user] = nil | ||
| 57 | + end | ||
| 53 | end | 58 | end |
| 54 | 59 | ||
| 55 | def abilities | 60 | def abilities |
db/fixtures/development/09_issues.rb
| @@ -11,17 +11,22 @@ Gitlab::Seeder.quiet do | @@ -11,17 +11,22 @@ Gitlab::Seeder.quiet do | ||
| 11 | next unless user | 11 | next unless user |
| 12 | 12 | ||
| 13 | user_id = user.id | 13 | user_id = user.id |
| 14 | - Thread.current[:current_user] = user | ||
| 15 | 14 | ||
| 16 | - Issue.seed(:id, [{ | ||
| 17 | - id: i, | ||
| 18 | - project_id: project.id, | ||
| 19 | - author_id: user_id, | ||
| 20 | - assignee_id: user_id, | ||
| 21 | - state: ['opened', 'closed'].sample, | ||
| 22 | - milestone: project.milestones.sample, | ||
| 23 | - title: Faker::Lorem.sentence(6) | ||
| 24 | - }]) | 15 | + begin |
| 16 | + Thread.current[:current_user] = user | ||
| 17 | + | ||
| 18 | + Issue.seed(:id, [{ | ||
| 19 | + id: i, | ||
| 20 | + project_id: project.id, | ||
| 21 | + author_id: user_id, | ||
| 22 | + assignee_id: user_id, | ||
| 23 | + state: ['opened', 'closed'].sample, | ||
| 24 | + milestone: project.milestones.sample, | ||
| 25 | + title: Faker::Lorem.sentence(6) | ||
| 26 | + }]) | ||
| 27 | + ensure | ||
| 28 | + Thread.current[:current_user] = nil | ||
| 29 | + end | ||
| 25 | print('.') | 30 | print('.') |
| 26 | end | 31 | end |
| 27 | 32 |
db/fixtures/development/10_merge_requests.rb
| @@ -17,19 +17,23 @@ Gitlab::Seeder.quiet do | @@ -17,19 +17,23 @@ Gitlab::Seeder.quiet do | ||
| 17 | next if branches.uniq.size < 2 | 17 | next if branches.uniq.size < 2 |
| 18 | 18 | ||
| 19 | user_id = user.id | 19 | user_id = user.id |
| 20 | - Thread.current[:current_user] = user | ||
| 21 | - | ||
| 22 | - MergeRequest.seed(:id, [{ | ||
| 23 | - id: i, | ||
| 24 | - source_branch: branches.first, | ||
| 25 | - target_branch: branches.last, | ||
| 26 | - source_project_id: project.id, | ||
| 27 | - target_project_id: project.id, | ||
| 28 | - author_id: user_id, | ||
| 29 | - assignee_id: user_id, | ||
| 30 | - milestone: project.milestones.sample, | ||
| 31 | - title: Faker::Lorem.sentence(6) | ||
| 32 | - }]) | 20 | + begin |
| 21 | + Thread.current[:current_user] = user | ||
| 22 | + | ||
| 23 | + MergeRequest.seed(:id, [{ | ||
| 24 | + id: i, | ||
| 25 | + source_branch: branches.first, | ||
| 26 | + target_branch: branches.last, | ||
| 27 | + source_project_id: project.id, | ||
| 28 | + target_project_id: project.id, | ||
| 29 | + author_id: user_id, | ||
| 30 | + assignee_id: user_id, | ||
| 31 | + milestone: project.milestones.sample, | ||
| 32 | + title: Faker::Lorem.sentence(6) | ||
| 33 | + }]) | ||
| 34 | + ensure | ||
| 35 | + Thread.current[:current_user] = nil | ||
| 36 | + end | ||
| 33 | print('.') | 37 | print('.') |
| 34 | end | 38 | end |
| 35 | end | 39 | end |
features/support/env.rb
| @@ -51,4 +51,6 @@ Spinach.hooks.before_run do | @@ -51,4 +51,6 @@ Spinach.hooks.before_run do | ||
| 51 | RSpec::Mocks::setup self | 51 | RSpec::Mocks::setup self |
| 52 | 52 | ||
| 53 | include FactoryGirl::Syntax::Methods | 53 | include FactoryGirl::Syntax::Methods |
| 54 | + MergeRequestObserver.any_instance.stub(current_user: create(:user)) | ||
| 54 | end | 55 | end |
| 56 | + |
lib/api/helpers.rb
| @@ -31,6 +31,15 @@ module API | @@ -31,6 +31,15 @@ module API | ||
| 31 | end | 31 | end |
| 32 | end | 32 | end |
| 33 | 33 | ||
| 34 | + def set_current_user_for_thread | ||
| 35 | + Thread.current[:current_user] = current_user | ||
| 36 | + begin | ||
| 37 | + yield | ||
| 38 | + ensure | ||
| 39 | + Thread.current[:current_user] = nil | ||
| 40 | + end | ||
| 41 | + end | ||
| 42 | + | ||
| 34 | def user_project | 43 | def user_project |
| 35 | @project ||= find_project(params[:id]) | 44 | @project ||= find_project(params[:id]) |
| 36 | @project || not_found! | 45 | @project || not_found! |
lib/api/issues.rb
| @@ -2,7 +2,6 @@ module API | @@ -2,7 +2,6 @@ module API | ||
| 2 | # Issues API | 2 | # Issues API |
| 3 | class Issues < Grape::API | 3 | class Issues < Grape::API |
| 4 | before { authenticate! } | 4 | before { authenticate! } |
| 5 | - before { Thread.current[:current_user] = current_user } | ||
| 6 | 5 | ||
| 7 | resource :issues do | 6 | resource :issues do |
| 8 | # Get currently authenticated user's issues | 7 | # Get currently authenticated user's issues |
| @@ -49,15 +48,17 @@ module API | @@ -49,15 +48,17 @@ module API | ||
| 49 | # Example Request: | 48 | # Example Request: |
| 50 | # POST /projects/:id/issues | 49 | # POST /projects/:id/issues |
| 51 | post ":id/issues" do | 50 | post ":id/issues" do |
| 52 | - required_attributes! [:title] | ||
| 53 | - attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id] | ||
| 54 | - attrs[:label_list] = params[:labels] if params[:labels].present? | ||
| 55 | - @issue = user_project.issues.new attrs | ||
| 56 | - @issue.author = current_user | ||
| 57 | - if @issue.save | ||
| 58 | - present @issue, with: Entities::Issue | ||
| 59 | - else | ||
| 60 | - not_found! | 51 | + set_current_user_for_thread do |
| 52 | + required_attributes! [:title] | ||
| 53 | + attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id] | ||
| 54 | + attrs[:label_list] = params[:labels] if params[:labels].present? | ||
| 55 | + @issue = user_project.issues.new attrs | ||
| 56 | + @issue.author = current_user | ||
| 57 | + if @issue.save | ||
| 58 | + present @issue, with: Entities::Issue | ||
| 59 | + else | ||
| 60 | + not_found! | ||
| 61 | + end | ||
| 61 | end | 62 | end |
| 62 | end | 63 | end |
| 63 | 64 | ||
| @@ -75,16 +76,18 @@ module API | @@ -75,16 +76,18 @@ module API | ||
| 75 | # Example Request: | 76 | # Example Request: |
| 76 | # PUT /projects/:id/issues/:issue_id | 77 | # PUT /projects/:id/issues/:issue_id |
| 77 | put ":id/issues/:issue_id" do | 78 | put ":id/issues/:issue_id" do |
| 78 | - @issue = user_project.issues.find(params[:issue_id]) | ||
| 79 | - authorize! :modify_issue, @issue | 79 | + set_current_user_for_thread do |
| 80 | + @issue = user_project.issues.find(params[:issue_id]) | ||
| 81 | + authorize! :modify_issue, @issue | ||
| 80 | 82 | ||
| 81 | - attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event] | ||
| 82 | - attrs[:label_list] = params[:labels] if params[:labels].present? | 83 | + attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event] |
| 84 | + attrs[:label_list] = params[:labels] if params[:labels].present? | ||
| 83 | 85 | ||
| 84 | - if @issue.update_attributes attrs | ||
| 85 | - present @issue, with: Entities::Issue | ||
| 86 | - else | ||
| 87 | - not_found! | 86 | + if @issue.update_attributes attrs |
| 87 | + present @issue, with: Entities::Issue | ||
| 88 | + else | ||
| 89 | + not_found! | ||
| 90 | + end | ||
| 88 | end | 91 | end |
| 89 | end | 92 | end |
| 90 | 93 |
lib/api/merge_requests.rb
| @@ -2,7 +2,6 @@ module API | @@ -2,7 +2,6 @@ module API | ||
| 2 | # MergeRequest API | 2 | # MergeRequest API |
| 3 | class MergeRequests < Grape::API | 3 | class MergeRequests < Grape::API |
| 4 | before { authenticate! } | 4 | before { authenticate! } |
| 5 | - before { Thread.current[:current_user] = current_user } | ||
| 6 | 5 | ||
| 7 | resource :projects do | 6 | resource :projects do |
| 8 | helpers do | 7 | helpers do |
| @@ -70,28 +69,30 @@ module API | @@ -70,28 +69,30 @@ module API | ||
| 70 | # POST /projects/:id/merge_requests | 69 | # POST /projects/:id/merge_requests |
| 71 | # | 70 | # |
| 72 | post ":id/merge_requests" do | 71 | post ":id/merge_requests" do |
| 73 | - authorize! :write_merge_request, user_project | ||
| 74 | - required_attributes! [:source_branch, :target_branch, :title] | ||
| 75 | - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id] | ||
| 76 | - merge_request = user_project.merge_requests.new(attrs) | ||
| 77 | - merge_request.author = current_user | ||
| 78 | - merge_request.source_project = user_project | ||
| 79 | - target_project_id = attrs[:target_project_id] | ||
| 80 | - if not_fork?(target_project_id, user_project) | ||
| 81 | - merge_request.target_project = user_project | ||
| 82 | - else | ||
| 83 | - if target_matches_fork(target_project_id,user_project) | ||
| 84 | - merge_request.target_project = Project.find_by_id(attrs[:target_project_id]) | 72 | + set_current_user_for_thread do |
| 73 | + authorize! :write_merge_request, user_project | ||
| 74 | + required_attributes! [:source_branch, :target_branch, :title] | ||
| 75 | + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id] | ||
| 76 | + merge_request = user_project.merge_requests.new(attrs) | ||
| 77 | + merge_request.author = current_user | ||
| 78 | + merge_request.source_project = user_project | ||
| 79 | + target_project_id = attrs[:target_project_id] | ||
| 80 | + if not_fork?(target_project_id, user_project) | ||
| 81 | + merge_request.target_project = user_project | ||
| 85 | else | 82 | else |
| 86 | - render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400) | 83 | + if target_matches_fork(target_project_id,user_project) |
| 84 | + merge_request.target_project = Project.find_by_id(attrs[:target_project_id]) | ||
| 85 | + else | ||
| 86 | + render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400) | ||
| 87 | + end | ||
| 87 | end | 88 | end |
| 88 | - end | ||
| 89 | 89 | ||
| 90 | - if merge_request.save | ||
| 91 | - merge_request.reload_code | ||
| 92 | - present merge_request, with: Entities::MergeRequest | ||
| 93 | - else | ||
| 94 | - handle_merge_request_errors! merge_request.errors | 90 | + if merge_request.save |
| 91 | + merge_request.reload_code | ||
| 92 | + present merge_request, with: Entities::MergeRequest | ||
| 93 | + else | ||
| 94 | + handle_merge_request_errors! merge_request.errors | ||
| 95 | + end | ||
| 95 | end | 96 | end |
| 96 | end | 97 | end |
| 97 | 98 | ||
| @@ -109,17 +110,19 @@ module API | @@ -109,17 +110,19 @@ module API | ||
| 109 | # PUT /projects/:id/merge_request/:merge_request_id | 110 | # PUT /projects/:id/merge_request/:merge_request_id |
| 110 | # | 111 | # |
| 111 | put ":id/merge_request/:merge_request_id" do | 112 | put ":id/merge_request/:merge_request_id" do |
| 112 | - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event] | ||
| 113 | - merge_request = user_project.merge_requests.find(params[:merge_request_id]) | 113 | + set_current_user_for_thread do |
| 114 | + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event] | ||
| 115 | + merge_request = user_project.merge_requests.find(params[:merge_request_id]) | ||
| 114 | 116 | ||
| 115 | - authorize! :modify_merge_request, merge_request | 117 | + authorize! :modify_merge_request, merge_request |
| 116 | 118 | ||
| 117 | - if merge_request.update_attributes attrs | ||
| 118 | - merge_request.reload_code | ||
| 119 | - merge_request.mark_as_unchecked | ||
| 120 | - present merge_request, with: Entities::MergeRequest | ||
| 121 | - else | ||
| 122 | - handle_merge_request_errors! merge_request.errors | 119 | + if merge_request.update_attributes attrs |
| 120 | + merge_request.reload_code | ||
| 121 | + merge_request.mark_as_unchecked | ||
| 122 | + present merge_request, with: Entities::MergeRequest | ||
| 123 | + else | ||
| 124 | + handle_merge_request_errors! merge_request.errors | ||
| 125 | + end | ||
| 123 | end | 126 | end |
| 124 | end | 127 | end |
| 125 | 128 | ||
| @@ -133,16 +136,18 @@ module API | @@ -133,16 +136,18 @@ module API | ||
| 133 | # POST /projects/:id/merge_request/:merge_request_id/comments | 136 | # POST /projects/:id/merge_request/:merge_request_id/comments |
| 134 | # | 137 | # |
| 135 | post ":id/merge_request/:merge_request_id/comments" do | 138 | post ":id/merge_request/:merge_request_id/comments" do |
| 136 | - required_attributes! [:note] | 139 | + set_current_user_for_thread do |
| 140 | + required_attributes! [:note] | ||
| 137 | 141 | ||
| 138 | - merge_request = user_project.merge_requests.find(params[:merge_request_id]) | ||
| 139 | - note = merge_request.notes.new(note: params[:note], project_id: user_project.id) | ||
| 140 | - note.author = current_user | 142 | + merge_request = user_project.merge_requests.find(params[:merge_request_id]) |
| 143 | + note = merge_request.notes.new(note: params[:note], project_id: user_project.id) | ||
| 144 | + note.author = current_user | ||
| 141 | 145 | ||
| 142 | - if note.save | ||
| 143 | - present note, with: Entities::MRNote | ||
| 144 | - else | ||
| 145 | - not_found! | 146 | + if note.save |
| 147 | + present note, with: Entities::MRNote | ||
| 148 | + else | ||
| 149 | + not_found! | ||
| 150 | + end | ||
| 146 | end | 151 | end |
| 147 | end | 152 | end |
| 148 | 153 |
lib/api/milestones.rb
| @@ -40,15 +40,17 @@ module API | @@ -40,15 +40,17 @@ module API | ||
| 40 | # Example Request: | 40 | # Example Request: |
| 41 | # POST /projects/:id/milestones | 41 | # POST /projects/:id/milestones |
| 42 | post ":id/milestones" do | 42 | post ":id/milestones" do |
| 43 | - authorize! :admin_milestone, user_project | ||
| 44 | - required_attributes! [:title] | 43 | + set_current_user_for_thread do |
| 44 | + authorize! :admin_milestone, user_project | ||
| 45 | + required_attributes! [:title] | ||
| 45 | 46 | ||
| 46 | - attrs = attributes_for_keys [:title, :description, :due_date] | ||
| 47 | - @milestone = user_project.milestones.new attrs | ||
| 48 | - if @milestone.save | ||
| 49 | - present @milestone, with: Entities::Milestone | ||
| 50 | - else | ||
| 51 | - not_found! | 47 | + attrs = attributes_for_keys [:title, :description, :due_date] |
| 48 | + @milestone = user_project.milestones.new attrs | ||
| 49 | + if @milestone.save | ||
| 50 | + present @milestone, with: Entities::Milestone | ||
| 51 | + else | ||
| 52 | + not_found! | ||
| 53 | + end | ||
| 52 | end | 54 | end |
| 53 | end | 55 | end |
| 54 | 56 | ||
| @@ -64,14 +66,16 @@ module API | @@ -64,14 +66,16 @@ module API | ||
| 64 | # Example Request: | 66 | # Example Request: |
| 65 | # PUT /projects/:id/milestones/:milestone_id | 67 | # PUT /projects/:id/milestones/:milestone_id |
| 66 | put ":id/milestones/:milestone_id" do | 68 | put ":id/milestones/:milestone_id" do |
| 67 | - authorize! :admin_milestone, user_project | 69 | + set_current_user_for_thread do |
| 70 | + authorize! :admin_milestone, user_project | ||
| 68 | 71 | ||
| 69 | - @milestone = user_project.milestones.find(params[:milestone_id]) | ||
| 70 | - attrs = attributes_for_keys [:title, :description, :due_date, :state_event] | ||
| 71 | - if @milestone.update_attributes attrs | ||
| 72 | - present @milestone, with: Entities::Milestone | ||
| 73 | - else | ||
| 74 | - not_found! | 72 | + @milestone = user_project.milestones.find(params[:milestone_id]) |
| 73 | + attrs = attributes_for_keys [:title, :description, :due_date, :state_event] | ||
| 74 | + if @milestone.update_attributes attrs | ||
| 75 | + present @milestone, with: Entities::Milestone | ||
| 76 | + else | ||
| 77 | + not_found! | ||
| 78 | + end | ||
| 75 | end | 79 | end |
| 76 | end | 80 | end |
| 77 | end | 81 | end |
lib/api/notes.rb
| @@ -41,17 +41,19 @@ module API | @@ -41,17 +41,19 @@ module API | ||
| 41 | # Example Request: | 41 | # Example Request: |
| 42 | # POST /projects/:id/notes | 42 | # POST /projects/:id/notes |
| 43 | post ":id/notes" do | 43 | post ":id/notes" do |
| 44 | - required_attributes! [:body] | 44 | + set_current_user_for_thread do |
| 45 | + required_attributes! [:body] | ||
| 45 | 46 | ||
| 46 | - @note = user_project.notes.new(note: params[:body]) | ||
| 47 | - @note.author = current_user | 47 | + @note = user_project.notes.new(note: params[:body]) |
| 48 | + @note.author = current_user | ||
| 48 | 49 | ||
| 49 | - if @note.save | ||
| 50 | - present @note, with: Entities::Note | ||
| 51 | - else | ||
| 52 | - # :note is exposed as :body, but :note is set on error | ||
| 53 | - bad_request!(:note) if @note.errors[:note].any? | ||
| 54 | - not_found! | 50 | + if @note.save |
| 51 | + present @note, with: Entities::Note | ||
| 52 | + else | ||
| 53 | + # :note is exposed as :body, but :note is set on error | ||
| 54 | + bad_request!(:note) if @note.errors[:note].any? | ||
| 55 | + not_found! | ||
| 56 | + end | ||
| 55 | end | 57 | end |
| 56 | end | 58 | end |
| 57 | 59 | ||
| @@ -97,17 +99,19 @@ module API | @@ -97,17 +99,19 @@ module API | ||
| 97 | # POST /projects/:id/issues/:noteable_id/notes | 99 | # POST /projects/:id/issues/:noteable_id/notes |
| 98 | # POST /projects/:id/snippets/:noteable_id/notes | 100 | # POST /projects/:id/snippets/:noteable_id/notes |
| 99 | post ":id/#{noteables_str}/:#{noteable_id_str}/notes" do | 101 | post ":id/#{noteables_str}/:#{noteable_id_str}/notes" do |
| 100 | - required_attributes! [:body] | 102 | + set_current_user_for_thread do |
| 103 | + required_attributes! [:body] | ||
| 101 | 104 | ||
| 102 | - @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) | ||
| 103 | - @note = @noteable.notes.new(note: params[:body]) | ||
| 104 | - @note.author = current_user | ||
| 105 | - @note.project = user_project | 105 | + @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) |
| 106 | + @note = @noteable.notes.new(note: params[:body]) | ||
| 107 | + @note.author = current_user | ||
| 108 | + @note.project = user_project | ||
| 106 | 109 | ||
| 107 | - if @note.save | ||
| 108 | - present @note, with: Entities::Note | ||
| 109 | - else | ||
| 110 | - not_found! | 110 | + if @note.save |
| 111 | + present @note, with: Entities::Note | ||
| 112 | + else | ||
| 113 | + not_found! | ||
| 114 | + end | ||
| 111 | end | 115 | end |
| 112 | end | 116 | end |
| 113 | end | 117 | end |
spec/models/project_spec.rb
| @@ -27,14 +27,8 @@ | @@ -27,14 +27,8 @@ | ||
| 27 | require 'spec_helper' | 27 | require 'spec_helper' |
| 28 | 28 | ||
| 29 | describe Project do | 29 | describe Project do |
| 30 | - let(:user) { create(:user) } | ||
| 31 | - | ||
| 32 | - before do | ||
| 33 | - enable_observers | ||
| 34 | - Thread.current[:current_user] = user | ||
| 35 | - end | ||
| 36 | - | ||
| 37 | - after { disable_observers } | 30 | + before { enable_observers } |
| 31 | + after { disable_observers } | ||
| 38 | 32 | ||
| 39 | describe "Associations" do | 33 | describe "Associations" do |
| 40 | it { should belong_to(:group) } | 34 | it { should belong_to(:group) } |
spec/requests/api/issues_spec.rb
| @@ -100,4 +100,16 @@ describe API::API do | @@ -100,4 +100,16 @@ describe API::API do | ||
| 100 | response.status.should == 405 | 100 | response.status.should == 405 |
| 101 | end | 101 | end |
| 102 | end | 102 | end |
| 103 | + | ||
| 104 | + describe "PUT /projects/:id/issues/:issue_id to test observer on close" do | ||
| 105 | + before { enable_observers } | ||
| 106 | + after { disable_observers } | ||
| 107 | + | ||
| 108 | + it "should create an activity event when an issue is closed" do | ||
| 109 | + Event.should_receive(:create) | ||
| 110 | + | ||
| 111 | + put api("/projects/#{project.id}/issues/#{issue.id}", user), | ||
| 112 | + state_event: "close" | ||
| 113 | + end | ||
| 114 | + end | ||
| 103 | end | 115 | end |
spec/requests/api/milestones_spec.rb
| @@ -90,4 +90,16 @@ describe API::API do | @@ -90,4 +90,16 @@ describe API::API do | ||
| 90 | json_response['state'].should == 'closed' | 90 | json_response['state'].should == 'closed' |
| 91 | end | 91 | end |
| 92 | end | 92 | end |
| 93 | + | ||
| 94 | + describe "PUT /projects/:id/milestones/:milestone_id to test observer on close" do | ||
| 95 | + before { enable_observers } | ||
| 96 | + after { disable_observers } | ||
| 97 | + | ||
| 98 | + it "should create an activity event when an milestone is closed" do | ||
| 99 | + Event.should_receive(:create) | ||
| 100 | + | ||
| 101 | + put api("/projects/#{project.id}/milestones/#{milestone.id}", user), | ||
| 102 | + state_event: 'close' | ||
| 103 | + end | ||
| 104 | + end | ||
| 93 | end | 105 | end |
spec/requests/api/notes_spec.rb
| @@ -176,4 +176,16 @@ describe API::API do | @@ -176,4 +176,16 @@ describe API::API do | ||
| 176 | end | 176 | end |
| 177 | end | 177 | end |
| 178 | end | 178 | end |
| 179 | + | ||
| 180 | + describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do | ||
| 181 | + before { enable_observers } | ||
| 182 | + after { disable_observers } | ||
| 183 | + | ||
| 184 | + it "should create an activity event when an issue note is created" do | ||
| 185 | + Event.should_receive(:create) | ||
| 186 | + | ||
| 187 | + post api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' | ||
| 188 | + end | ||
| 189 | + end | ||
| 190 | + | ||
| 179 | end | 191 | end |
spec/support/test_env.rb
| @@ -84,6 +84,11 @@ module TestEnv | @@ -84,6 +84,11 @@ module TestEnv | ||
| 84 | Repository.any_instance.stub( | 84 | Repository.any_instance.stub( |
| 85 | size: 12.45 | 85 | size: 12.45 |
| 86 | ) | 86 | ) |
| 87 | + | ||
| 88 | + ActivityObserver.any_instance.stub( | ||
| 89 | + current_user: double("current_user", id: 1) | ||
| 90 | + ) | ||
| 91 | + | ||
| 87 | end | 92 | end |
| 88 | 93 | ||
| 89 | def clear_repo_dir(namespace, name) | 94 | def clear_repo_dir(namespace, name) |