Commit cfd9fd30d60c5a880785acda27e9f3d55b17e4ef

Authored by Dmitriy Zaporozhets
1 parent 3b0510a7

Move code for issue creation to service.

The goal of suych refactoring is to get rid of observers.
Its much easier to test and code when object creation and all other
related actions done in one class instead of splited across observers,
callbacks etc.

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
app/controllers/projects/issues_controller.rb
... ... @@ -59,9 +59,7 @@ class Projects::IssuesController &lt; Projects::ApplicationController
59 59 end
60 60  
61 61 def create
62   - @issue = @project.issues.new(params[:issue])
63   - @issue.author = current_user
64   - @issue.save
  62 + @issue = Issues::CreateService.new(project, current_user, params[:issue]).execute
65 63  
66 64 respond_to do |format|
67 65 format.html do
... ...
app/observers/issue_observer.rb
1 1 class IssueObserver < BaseObserver
2   - def after_create(issue)
3   - notification.new_issue(issue, current_user)
4   - event_service.open_issue(issue, current_user)
5   - issue.create_cross_references!(issue.project, current_user)
6   - execute_hooks(issue)
7   - end
8   -
9 2 def after_close(issue, transition)
10 3 notification.close_issue(issue, current_user)
11 4 event_service.close_issue(issue, current_user)
... ...
app/services/base_service.rb
... ... @@ -16,4 +16,16 @@ class BaseService
16 16 def can?(object, action, subject)
17 17 abilities.allowed?(object, action, subject)
18 18 end
  19 +
  20 + def notification_service
  21 + NotificationService.new
  22 + end
  23 +
  24 + def event_service
  25 + EventCreateService.new
  26 + end
  27 +
  28 + def log_info message
  29 + Gitlab::AppLogger.info message
  30 + end
19 31 end
... ...
app/services/issues/create_service.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +module Issues
  2 + class CreateService < BaseService
  3 + def execute
  4 + issue = project.issues.new(params)
  5 + issue.author = current_user
  6 +
  7 + if issue.save
  8 + notification_service.new_issue(issue, current_user)
  9 + event_service.open_issue(issue, current_user)
  10 + issue.create_cross_references!(issue.project, current_user)
  11 + execute_hooks(issue)
  12 + end
  13 +
  14 + issue
  15 + end
  16 +
  17 + private
  18 +
  19 + def execute_hooks(issue)
  20 + issue.project.execute_hooks(issue.to_hook_data, :issue_hooks)
  21 + end
  22 + end
  23 +end
... ...
lib/api/issues.rb
... ... @@ -48,17 +48,15 @@ module API
48 48 # Example Request:
49 49 # POST /projects/:id/issues
50 50 post ":id/issues" do
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
  51 + required_attributes! [:title]
  52 + attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id]
  53 + attrs[:label_list] = params[:labels] if params[:labels].present?
  54 + issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute
  55 +
  56 + if issue.valid?
  57 + present issue, with: Entities::Issue
  58 + else
  59 + not_found!
62 60 end
63 61 end
64 62  
... ...
spec/services/issues/create_service_spec.rb 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Issues::CreateService do
  4 + let(:project) { create(:empty_project) }
  5 + let(:user) { create(:user) }
  6 +
  7 + describe :execute do
  8 + context "valid params" do
  9 + before do
  10 + project.team << [user, :master]
  11 + opts = {
  12 + title: 'Awesome issue',
  13 + description: 'please fix'
  14 + }
  15 +
  16 + @issue = Issues::CreateService.new(project, user, opts).execute
  17 + end
  18 +
  19 + it { @issue.should be_valid }
  20 + end
  21 + end
  22 +end
... ...