Commit a7ab029d22baec1aa6e5a095b5eac99a9ffebdaa

Authored by Dmitriy Zaporozhets
2 parents 96f91c0f 9b6224f9

Merge branch 'reduce-observers' into 'master'

Remove some observers
app/controllers/projects/merge_requests_controller.rb
... ... @@ -76,10 +76,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
76 76 end
77 77  
78 78 def create
79   - @merge_request = MergeRequest.new(params[:merge_request])
80   - @merge_request.author = current_user
81 79 @target_branches ||= []
82   - if @merge_request.save
  80 + @merge_request = MergeRequests::CreateService.new(project, current_user, params[:merge_request]).execute
  81 +
  82 + if @merge_request.valid?
83 83 redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully created.'
84 84 else
85 85 @source_project = @merge_request.source_project
... ... @@ -89,29 +89,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
89 89 end
90 90  
91 91 def update
92   - # If we close MergeRequest we want to ignore validation
93   - # so we can close broken one (Ex. fork project removed)
94   - if params[:merge_request] == {"state_event"=>"close"}
95   - @merge_request.allow_broken = true
96   -
97   - if @merge_request.close
98   - opts = { notice: 'Merge request was successfully closed.' }
99   - else
100   - opts = { alert: 'Failed to close merge request.' }
101   - end
102   -
103   - redirect_to [@merge_request.target_project, @merge_request], opts
104   - return
105   - end
106   -
107   - # We dont allow change of source/target projects
108   - # after merge request was created
109   - params[:merge_request].delete(:source_project_id)
110   - params[:merge_request].delete(:target_project_id)
111   -
112   - if @merge_request.update_attributes(params[:merge_request])
113   - @merge_request.reset_events_cache
  92 + @merge_request = MergeRequests::UpdateService.new(project, current_user, params[:merge_request]).execute(@merge_request)
114 93  
  94 + if @merge_request.valid?
115 95 respond_to do |format|
116 96 format.js
117 97 format.html do
... ...
app/models/email.rb
... ... @@ -13,14 +13,15 @@ class Email < ActiveRecord::Base
13 13 # Relations
14 14 #
15 15 belongs_to :user
16   -
  16 +
17 17 #
18 18 # Validations
19 19 #
20 20 validates :user_id, presence: true
21 21 validates :email, presence: true, email: { strict_mode: true }, uniqueness: true
22 22 validate :unique_email, if: ->(email) { email.email_changed? }
23   -
  23 +
  24 + after_create :notify
24 25 before_validation :cleanup_email
25 26  
26 27 def cleanup_email
... ... @@ -30,4 +31,8 @@ class Email < ActiveRecord::Base
30 31 def unique_email
31 32 self.errors.add(:email, 'has already been taken') if User.exists?(email: self.email)
32 33 end
33   -end
34 34 \ No newline at end of file
  35 +
  36 + def notify
  37 + NotificationService.new.new_email(self)
  38 + end
  39 +end
... ...
app/models/key.rb
... ... @@ -29,6 +29,10 @@ class Key < ActiveRecord::Base
29 29  
30 30 delegate :name, :email, to: :user, prefix: true
31 31  
  32 + after_create :add_to_shell
  33 + after_create :notify_user
  34 + after_destroy :remove_from_shell
  35 +
32 36 def strip_white_space
33 37 self.key = key.strip unless key.blank?
34 38 end
... ... @@ -42,6 +46,26 @@ class Key < ActiveRecord::Base
42 46 "key-#{id}"
43 47 end
44 48  
  49 + def add_to_shell
  50 + GitlabShellWorker.perform_async(
  51 + :add_key,
  52 + shell_id,
  53 + key
  54 + )
  55 + end
  56 +
  57 + def notify_user
  58 + NotificationService.new.new_key(self)
  59 + end
  60 +
  61 + def remove_from_shell
  62 + GitlabShellWorker.perform_async(
  63 + :remove_key,
  64 + shell_id,
  65 + key,
  66 + )
  67 + end
  68 +
45 69 private
46 70  
47 71 def generate_fingerpint
... ...
app/models/merge_request.rb
... ... @@ -97,6 +97,7 @@ class MergeRequest < ActiveRecord::Base
97 97 validates :target_project, presence: true
98 98 validates :target_branch, presence: true
99 99 validate :validate_branches
  100 + validate :validate_fork
100 101  
101 102 scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) }
102 103 scope :of_user_team, ->(team) { where("(source_project_id in (:team_project_ids) OR target_project_id in (:team_project_ids) AND assignee_id in (:team_member_ids))", team_project_ids: team.project_ids, team_member_ids: team.member_ids) }
... ... @@ -125,6 +126,22 @@ class MergeRequest < ActiveRecord::Base
125 126 end
126 127 end
127 128  
  129 + def validate_fork
  130 + return true unless target_project && source_project
  131 +
  132 + if target_project == source_project
  133 + true
  134 + else
  135 + # If source and target projects are different
  136 + # we should check if source project is actually a fork of target project
  137 + if source_project.forked_from?(target_project)
  138 + true
  139 + else
  140 + errors.add :base, "Source project is not a fork of target project"
  141 + end
  142 + end
  143 + end
  144 +
128 145 def update_merge_request_diff
129 146 if source_branch_changed? || target_branch_changed?
130 147 reload_code
... ...
app/models/project.rb
... ... @@ -552,4 +552,8 @@ class Project < ActiveRecord::Base
552 552 gitlab_shell.update_repository_head(self.path_with_namespace, branch)
553 553 reload_default_branch
554 554 end
  555 +
  556 + def forked_from?(project)
  557 + forked? && project == forked_from_project
  558 + end
555 559 end
... ...
app/observers/email_observer.rb
... ... @@ -1,5 +0,0 @@
1   -class EmailObserver < BaseObserver
2   - def after_create(email)
3   - notification.new_email(email)
4   - end
5   -end
app/observers/key_observer.rb
... ... @@ -1,19 +0,0 @@
1   -class KeyObserver < BaseObserver
2   - def after_create(key)
3   - GitlabShellWorker.perform_async(
4   - :add_key,
5   - key.shell_id,
6   - key.key
7   - )
8   -
9   - notification.new_key(key)
10   - end
11   -
12   - def after_destroy(key)
13   - GitlabShellWorker.perform_async(
14   - :remove_key,
15   - key.shell_id,
16   - key.key,
17   - )
18   - end
19   -end
app/observers/merge_request_observer.rb
... ... @@ -1,43 +0,0 @@
1   -class MergeRequestObserver < BaseObserver
2   - def after_create(merge_request)
3   - event_service.open_mr(merge_request, current_user)
4   - notification.new_merge_request(merge_request, current_user)
5   - merge_request.create_cross_references!(merge_request.project, current_user)
6   - execute_hooks(merge_request)
7   - end
8   -
9   - def after_close(merge_request, transition)
10   - event_service.close_mr(merge_request, current_user)
11   - notification.close_mr(merge_request, current_user)
12   - create_note(merge_request)
13   - execute_hooks(merge_request)
14   - end
15   -
16   - def after_reopen(merge_request, transition)
17   - event_service.reopen_mr(merge_request, current_user)
18   - create_note(merge_request)
19   - execute_hooks(merge_request)
20   - merge_request.reload_code
21   - merge_request.mark_as_unchecked
22   - end
23   -
24   - def after_update(merge_request)
25   - notification.reassigned_merge_request(merge_request, current_user) if merge_request.is_being_reassigned?
26   -
27   - merge_request.notice_added_references(merge_request.project, current_user)
28   - execute_hooks(merge_request)
29   - end
30   -
31   - private
32   -
33   - # Create merge request note with service comment like 'Status changed to closed'
34   - def create_note(merge_request)
35   - Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
36   - end
37   -
38   - def execute_hooks(merge_request)
39   - if merge_request.project
40   - merge_request.project.execute_hooks(merge_request.to_hook_data, :merge_request_hooks)
41   - end
42   - end
43   -end
app/services/merge_requests/base_service.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +module MergeRequests
  2 + class BaseService < ::BaseService
  3 +
  4 + private
  5 +
  6 + def create_note(merge_request)
  7 + Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
  8 + end
  9 +
  10 + def execute_hooks(merge_request)
  11 + if merge_request.project
  12 + merge_request.project.execute_hooks(merge_request.to_hook_data, :merge_request_hooks)
  13 + end
  14 + end
  15 + end
  16 +end
... ...
app/services/merge_requests/close_service.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +module MergeRequests
  2 + class CloseService < MergeRequests::BaseService
  3 + def execute(merge_request, commit = nil)
  4 + # If we close MergeRequest we want to ignore validation
  5 + # so we can close broken one (Ex. fork project removed)
  6 + merge_request.allow_broken = true
  7 +
  8 + if merge_request.close
  9 + event_service.close_mr(merge_request, current_user)
  10 + notification_service.close_mr(merge_request, current_user)
  11 + create_note(merge_request)
  12 + execute_hooks(merge_request)
  13 + end
  14 +
  15 + merge_request
  16 + end
  17 + end
  18 +end
... ...
app/services/merge_requests/create_service.rb 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +module MergeRequests
  2 + class CreateService < MergeRequests::BaseService
  3 + def execute
  4 + merge_request = MergeRequest.new(params)
  5 + merge_request.source_project = project
  6 + merge_request.target_project ||= project
  7 + merge_request.author = current_user
  8 +
  9 + if merge_request.save
  10 + event_service.open_mr(merge_request, current_user)
  11 + notification_service.new_merge_request(merge_request, current_user)
  12 + merge_request.create_cross_references!(merge_request.project, current_user)
  13 + execute_hooks(merge_request)
  14 + end
  15 +
  16 + merge_request
  17 + end
  18 + end
  19 +end
... ...
app/services/merge_requests/reopen_service.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +module MergeRequests
  2 + class ReopenService < MergeRequests::BaseService
  3 + def execute(merge_request)
  4 + if merge_request.reopen
  5 + event_service.reopen_mr(merge_request, current_user)
  6 + create_note(merge_request)
  7 + execute_hooks(merge_request)
  8 + merge_request.reload_code
  9 + merge_request.mark_as_unchecked
  10 + end
  11 +
  12 + merge_request
  13 + end
  14 + end
  15 +end
... ...
app/services/merge_requests/update_service.rb 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +require_relative 'base_service'
  2 +require_relative 'reopen_service'
  3 +require_relative 'close_service'
  4 +
  5 +module MergeRequests
  6 + class UpdateService < MergeRequests::BaseService
  7 + def execute(merge_request)
  8 + # We dont allow change of source/target projects
  9 + # after merge request was created
  10 + params.delete(:source_project_id)
  11 + params.delete(:target_project_id)
  12 +
  13 + state = params.delete('state_event')
  14 +
  15 + case state
  16 + when 'reopen'
  17 + MergeRequests::ReopenService.new(project, current_user, {}).execute(merge_request)
  18 + when 'close'
  19 + MergeRequests::CloseService.new(project, current_user, {}).execute(merge_request)
  20 + end
  21 +
  22 + if params.present? && merge_request.update_attributes(params)
  23 + merge_request.reset_events_cache
  24 +
  25 + if merge_request.previous_changes.include?('assignee_id')
  26 + notification_service.reassigned_merge_request(merge_request, current_user)
  27 + create_assignee_note(merge_request)
  28 + end
  29 +
  30 + merge_request.notice_added_references(merge_request.project, current_user)
  31 + execute_hooks(merge_request)
  32 + end
  33 +
  34 + merge_request
  35 + end
  36 + end
  37 +end
... ...
app/views/projects/merge_requests/_form.html.haml
... ... @@ -33,7 +33,7 @@
33 33 .col-sm-10
34 34 .clearfix
35 35 .pull-left
36   - - projects = @project.forked_from_project.nil? ? [@project] : [ @project,@project.forked_from_project]
  36 + - projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
37 37 = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? })
38 38 .pull-left
39 39 &nbsp;
... ...
config/application.rb
... ... @@ -21,8 +21,6 @@ module Gitlab
21 21 # Activate observers that should always be running.
22 22 config.active_record.observers = :milestone_observer,
23 23 :project_activity_cache_observer,
24   - :key_observer,
25   - :merge_request_observer,
26 24 :note_observer,
27 25 :project_observer,
28 26 :system_hook_observer,
... ...
features/steps/dashboard/merge_requests.rb
... ... @@ -53,15 +53,15 @@ class DashboardMergeRequests &lt; Spinach::FeatureSteps
53 53 end
54 54  
55 55 def assigned_merge_request
56   - @assigned_merge_request ||= create :merge_request, assignee: current_user, target_project: project
  56 + @assigned_merge_request ||= create :merge_request, assignee: current_user, target_project: project, source_project: project
57 57 end
58 58  
59 59 def authored_merge_request
60   - @authored_merge_request ||= create :merge_request, author: current_user, target_project: project
  60 + @authored_merge_request ||= create :merge_request, source_branch: 'simple_merge_request', author: current_user, target_project: project, source_project: project
61 61 end
62 62  
63 63 def other_merge_request
64   - @other_merge_request ||= create :merge_request, target_project: project
  64 + @other_merge_request ||= create :merge_request, source_branch: '2_3_notes_fix', target_project: project, source_project: project
65 65 end
66 66  
67 67 def project
... ...
features/support/env.rb
... ... @@ -52,6 +52,4 @@ Spinach.hooks.before_run do
52 52 RSpec::Mocks::setup self
53 53  
54 54 include FactoryGirl::Syntax::Methods
55   - MergeRequestObserver.any_instance.stub(current_user: create(:user))
56 55 end
57   -
... ...
lib/api/merge_requests.rb
... ... @@ -13,14 +13,6 @@ module API
13 13 end
14 14 not_found!
15 15 end
16   -
17   - def not_fork?(target_project_id, user_project)
18   - target_project_id.nil? || target_project_id == user_project.id.to_s
19   - end
20   -
21   - def target_matches_fork(target_project_id,user_project)
22   - user_project.forked? && user_project.forked_from_project.id.to_s == target_project_id
23   - end
24 16 end
25 17  
26 18 # List merge requests
... ... @@ -70,29 +62,15 @@ module API
70 62 # POST /projects/:id/merge_requests
71 63 #
72 64 post ":id/merge_requests" do
73   - set_current_user_for_thread do
74   - authorize! :write_merge_request, user_project
75   - required_attributes! [:source_branch, :target_branch, :title]
76   - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
77   - merge_request = user_project.merge_requests.new(attrs)
78   - merge_request.author = current_user
79   - merge_request.source_project = user_project
80   - target_project_id = attrs[:target_project_id]
81   - if not_fork?(target_project_id, user_project)
82   - merge_request.target_project = user_project
83   - else
84   - if target_matches_fork(target_project_id,user_project)
85   - merge_request.target_project = Project.find_by(id: attrs[:target_project_id])
86   - else
87   - render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
88   - end
89   - end
90   -
91   - if merge_request.save
92   - present merge_request, with: Entities::MergeRequest
93   - else
94   - handle_merge_request_errors! merge_request.errors
95   - end
  65 + authorize! :write_merge_request, user_project
  66 + required_attributes! [:source_branch, :target_branch, :title]
  67 + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description]
  68 + merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute
  69 +
  70 + if merge_request.valid?
  71 + present merge_request, with: Entities::MergeRequest
  72 + else
  73 + handle_merge_request_errors! merge_request.errors
96 74 end
97 75 end
98 76  
... ... @@ -111,17 +89,15 @@ module API
111 89 # PUT /projects/:id/merge_request/:merge_request_id
112 90 #
113 91 put ":id/merge_request/:merge_request_id" do
114   - set_current_user_for_thread do
115   - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description]
116   - merge_request = user_project.merge_requests.find(params[:merge_request_id])
117   -
118   - authorize! :modify_merge_request, merge_request
  92 + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description]
  93 + merge_request = user_project.merge_requests.find(params[:merge_request_id])
  94 + authorize! :modify_merge_request, merge_request
  95 + merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, attrs).execute(merge_request)
119 96  
120   - if merge_request.update_attributes attrs
121   - present merge_request, with: Entities::MergeRequest
122   - else
123   - handle_merge_request_errors! merge_request.errors
124   - end
  97 + if merge_request.valid?
  98 + present merge_request, with: Entities::MergeRequest
  99 + else
  100 + handle_merge_request_errors! merge_request.errors
125 101 end
126 102 end
127 103  
... ...
spec/finders/merge_requests_finder_spec.rb
... ... @@ -5,10 +5,10 @@ describe MergeRequestsFinder do
5 5 let(:user2) { create :user }
6 6  
7 7 let(:project1) { create(:project) }
8   - let(:project2) { create(:project) }
  8 + let(:project2) { create(:project, forked_from_project: project1) }
9 9  
10   - let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2) }
11   - let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
  10 + let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
  11 + let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1, state: 'closed') }
12 12 let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2) }
13 13  
14 14 before do
... ... @@ -21,7 +21,7 @@ describe MergeRequestsFinder do
21 21 it 'should filter by scope' do
22 22 params = { scope: 'authored', state: 'opened' }
23 23 merge_requests = MergeRequestsFinder.new.execute(user, params)
24   - merge_requests.size.should == 3
  24 + merge_requests.size.should == 2
25 25 end
26 26  
27 27 it 'should filter by project' do
... ...
spec/lib/gitlab/satellite/merge_action_spec.rb
... ... @@ -13,7 +13,7 @@ describe &#39;Gitlab::Satellite::MergeAction&#39; do
13 13 end
14 14  
15 15 let(:project) { create(:project, namespace: create(:group)) }
16   - let(:fork_project) { create(:project, namespace: create(:group)) }
  16 + let(:fork_project) { create(:project, namespace: create(:group), forked_from_project: project) }
17 17 let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
18 18 let(:merge_request_fork) { create(:merge_request, source_project: fork_project, target_project: project) }
19 19  
... ...
spec/models/key_spec.rb
... ... @@ -68,4 +68,18 @@ describe Key do
68 68 build(:invalid_key).should_not be_valid
69 69 end
70 70 end
  71 +
  72 + context 'callbacks' do
  73 + it 'should add new key to authorized_file' do
  74 + @key = build(:personal_key, id: 7)
  75 + GitlabShellWorker.should_receive(:perform_async).with(:add_key, @key.shell_id, @key.key)
  76 + @key.save
  77 + end
  78 +
  79 + it 'should remove key from authorized_file' do
  80 + @key = create(:personal_key)
  81 + GitlabShellWorker.should_receive(:perform_async).with(:remove_key, @key.shell_id, @key.key)
  82 + @key.destroy
  83 + end
  84 + end
71 85 end
... ...
spec/models/note_spec.rb
... ... @@ -209,7 +209,7 @@ describe Note do
209 209 let(:project) { create(:project) }
210 210 let(:author) { create(:user) }
211 211 let(:issue) { create(:issue, project: project) }
212   - let(:mergereq) { create(:merge_request, target_project: project) }
  212 + let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) }
213 213 let(:commit) { project.repository.commit }
214 214  
215 215 # Test all of {issue, merge request, commit} in both the referenced and referencing
... ...
spec/observers/email_observer_spec.rb
... ... @@ -1,17 +0,0 @@
1   -require 'spec_helper'
2   -
3   -describe EmailObserver do
4   - let(:email) { create(:email) }
5   -
6   - before { subject.stub(notification: double('NotificationService').as_null_object) }
7   -
8   - subject { EmailObserver.instance }
9   -
10   - describe '#after_create' do
11   - it 'trigger notification to send emails' do
12   - subject.should_receive(:notification)
13   -
14   - subject.after_create(email)
15   - end
16   - end
17   -end
spec/observers/key_observer_spec.rb
... ... @@ -1,23 +0,0 @@
1   -require 'spec_helper'
2   -
3   -describe KeyObserver do
4   - before do
5   - @key = create(:personal_key)
6   -
7   - @observer = KeyObserver.instance
8   - end
9   -
10   - context :after_create do
11   - it do
12   - GitlabShellWorker.should_receive(:perform_async).with(:add_key, @key.shell_id, @key.key)
13   - @observer.after_create(@key)
14   - end
15   - end
16   -
17   - context :after_destroy do
18   - it do
19   - GitlabShellWorker.should_receive(:perform_async).with(:remove_key, @key.shell_id, @key.key)
20   - @observer.after_destroy(@key)
21   - end
22   - end
23   -end
spec/observers/merge_request_observer_spec.rb
... ... @@ -1,131 +0,0 @@
1   -require 'spec_helper'
2   -
3   -describe MergeRequestObserver do
4   - let(:some_user) { create :user }
5   - let(:assignee) { create :user }
6   - let(:author) { create :user }
7   - let(:project) { create :project }
8   - let(:mr_mock) { double(:merge_request, id: 42, assignee: assignee, author: author).as_null_object }
9   - let(:assigned_mr) { create(:merge_request, assignee: assignee, author: author, source_project: project) }
10   - let(:unassigned_mr) { create(:merge_request, author: author, source_project: project) }
11   - let(:closed_assigned_mr) { create(:closed_merge_request, assignee: assignee, author: author, source_project: project) }
12   - let(:closed_unassigned_mr) { create(:closed_merge_request, author: author, source_project: project) }
13   -
14   - before { subject.stub(:current_user).and_return(some_user) }
15   - before { subject.stub(notification: double('NotificationService').as_null_object) }
16   - before { mr_mock.stub(:author_id) }
17   - before { mr_mock.stub(:source_project) }
18   - before { mr_mock.stub(:source_project) }
19   - before { mr_mock.stub(:project) }
20   - before { mr_mock.stub(:create_cross_references!).and_return(true) }
21   - before { Repository.any_instance.stub(commit: nil) }
22   -
23   - before(:each) { enable_observers }
24   - after(:each) { disable_observers }
25   -
26   - subject { MergeRequestObserver.instance }
27   -
28   - describe '#after_create' do
29   - it 'trigger notification service' do
30   - subject.should_receive(:notification)
31   - subject.after_create(mr_mock)
32   - end
33   -
34   - it 'creates cross-reference notes' do
35   - project = create :project
36   - mr_mock.stub(title: "this mr references !#{assigned_mr.id}", project: project)
37   - mr_mock.should_receive(:create_cross_references!).with(project, some_user)
38   -
39   - subject.after_create(mr_mock)
40   - end
41   - end
42   -
43   - context '#after_update' do
44   - before(:each) do
45   - mr_mock.stub(:is_being_reassigned?).and_return(false)
46   - mr_mock.stub(:notice_added_references)
47   - end
48   -
49   - it 'is called when a merge request is changed' do
50   - changed = create(:merge_request, source_project: project)
51   - subject.should_receive(:after_update)
52   -
53   - MergeRequest.observers.enable :merge_request_observer do
54   - changed.title = 'I changed'
55   - changed.save
56   - end
57   - end
58   -
59   - it 'checks for new references' do
60   - mr_mock.should_receive(:notice_added_references)
61   -
62   - subject.after_update(mr_mock)
63   - end
64   -
65   - context 'a notification' do
66   - it 'is sent if the merge request is being reassigned' do
67   - mr_mock.should_receive(:is_being_reassigned?).and_return(true)
68   - subject.should_receive(:notification)
69   -
70   - subject.after_update(mr_mock)
71   - end
72   -
73   - it 'is not sent if the merge request is not being reassigned' do
74   - mr_mock.should_receive(:is_being_reassigned?).and_return(false)
75   - subject.should_not_receive(:notification)
76   -
77   - subject.after_update(mr_mock)
78   - end
79   - end
80   - end
81   -
82   - context '#after_close' do
83   - context 'a status "closed"' do
84   - it 'note is created if the merge request is being closed' do
85   - Note.should_receive(:create_status_change_note).with(assigned_mr, assigned_mr.source_project, some_user, 'closed', nil)
86   -
87   - assigned_mr.close
88   - end
89   -
90   - it 'notification is delivered only to author if the merge request is being closed' do
91   - Note.should_receive(:create_status_change_note).with(unassigned_mr, unassigned_mr.source_project, some_user, 'closed', nil)
92   -
93   - unassigned_mr.close
94   - end
95   - end
96   - end
97   -
98   - context '#after_reopen' do
99   - context 'a status "reopened"' do
100   - it 'note is created if the merge request is being reopened' do
101   - Note.should_receive(:create_status_change_note).with(closed_assigned_mr, closed_assigned_mr.source_project, some_user, 'reopened', nil)
102   -
103   - closed_assigned_mr.reopen
104   - end
105   -
106   - it 'notification is delivered only to author if the merge request is being reopened' do
107   - Note.should_receive(:create_status_change_note).with(closed_unassigned_mr, closed_unassigned_mr.source_project, some_user, 'reopened', nil)
108   -
109   - closed_unassigned_mr.reopen
110   - end
111   - end
112   - end
113   -
114   - describe "Merge Request created" do
115   - def self.it_should_be_valid_event
116   - it { @event.should_not be_nil }
117   - it { @event.should_not be_nil }
118   - it { @event.project.should == project }
119   - it { @event.project.should == project }
120   - end
121   -
122   - before do
123   - @merge_request = create(:merge_request, source_project: project, target_project: project)
124   - @event = Event.last
125   - end
126   -
127   - it_should_be_valid_event
128   - it { @event.action.should == Event::CREATED }
129   - it { @event.target.should == @merge_request }
130   - end
131   -end
spec/requests/api/merge_requests_spec.rb
... ... @@ -6,7 +6,7 @@ describe API::API do
6 6 after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
7 7 let(:user) { create(:user) }
8 8 let!(:project) {create(:project, creator_id: user.id, namespace: user.namespace) }
9   - let!(:merge_request) { create(:merge_request, author: user, assignee: user, source_project: project, target_project: project, title: "Test") }
  9 + let!(:merge_request) { create(:merge_request, :simple, author: user, assignee: user, source_project: project, target_project: project, title: "Test") }
10 10 let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
11 11 before {
12 12 project.team << [user, :reporters]
... ... @@ -79,16 +79,12 @@ describe API::API do
79 79 end
80 80  
81 81 context 'forked projects' do
82   - let!(:user2) {create(:user)}
83   - let!(:forked_project_link) { build(:forked_project_link) }
84   - let!(:fork_project) { create(:project, forked_project_link: forked_project_link, namespace: user2.namespace, creator_id: user2.id) }
85   - let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) }
  82 + let!(:user2) { create(:user) }
  83 + let!(:fork_project) { create(:project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) }
  84 + let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) }
86 85  
87 86 before :each do |each|
88 87 fork_project.team << [user2, :reporters]
89   - forked_project_link.forked_from_project = project
90   - forked_project_link.forked_to_project = fork_project
91   - forked_project_link.save!
92 88 end
93 89  
94 90 it "should return merge_request" do
... ... @@ -127,16 +123,16 @@ describe API::API do
127 123 response.status.should == 400
128 124 end
129 125  
130   - it "should return 400 when target_branch is specified and not a forked project" do
  126 + it "should return 404 when target_branch is specified and not a forked project" do
131 127 post api("/projects/#{project.id}/merge_requests", user),
132 128 title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user, target_project_id: fork_project.id
133   - response.status.should == 400
  129 + response.status.should == 404
134 130 end
135 131  
136   - it "should return 400 when target_branch is specified and for a different fork" do
  132 + it "should return 404 when target_branch is specified and for a different fork" do
137 133 post api("/projects/#{fork_project.id}/merge_requests", user2),
138 134 title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: unrelated_project.id
139   - response.status.should == 400
  135 + response.status.should == 404
140 136 end
141 137  
142 138 it "should return 201 when target_branch is specified and for the same project" do
... ...
spec/services/notification_service_spec.rb
... ... @@ -5,7 +5,7 @@ describe NotificationService do
5 5  
6 6 describe 'Keys' do
7 7 describe :new_key do
8   - let(:key) { create(:personal_key) }
  8 + let!(:key) { create(:personal_key) }
9 9  
10 10 it { notification.new_key(key).should be_true }
11 11  
... ... @@ -18,7 +18,7 @@ describe NotificationService do
18 18  
19 19 describe 'Email' do
20 20 describe :new_email do
21   - let(:email) { create(:email) }
  21 + let!(:email) { create(:email) }
22 22  
23 23 it { notification.new_email(email).should be_true }
24 24  
... ...