Commit 1644117a1ac45bd7d250e7bced929a00a3befe5e
1 parent
0b512af8
Exists in
master
and in
4 other branches
Issue uses StateMachine now
Showing
13 changed files
with
134 additions
and
135 deletions
Show diff stats
app/helpers/issues_helper.rb
app/models/issue.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # project_id :integer |
10 | 10 | # created_at :datetime not null |
11 | 11 | # updated_at :datetime not null |
12 | -# closed :boolean default(FALSE), not null | |
12 | +# state :string default(FALSE), not null | |
13 | 13 | # position :integer default(0) |
14 | 14 | # branch_name :string(255) |
15 | 15 | # description :text |
... | ... | @@ -19,11 +19,29 @@ |
19 | 19 | class Issue < ActiveRecord::Base |
20 | 20 | include Issuable |
21 | 21 | |
22 | - attr_accessible :title, :assignee_id, :closed, :position, :description, | |
23 | - :milestone_id, :label_list, :author_id_of_changes | |
22 | + attr_accessible :title, :assignee_id, :position, :description, | |
23 | + :milestone_id, :label_list, :author_id_of_changes, | |
24 | + :state_event | |
24 | 25 | |
25 | 26 | acts_as_taggable_on :labels |
26 | 27 | |
28 | + state_machine :state, :initial => :opened do | |
29 | + event :close do | |
30 | + transition [:reopened, :opened] => :closed | |
31 | + end | |
32 | + | |
33 | + event :reopen do | |
34 | + transition :closed => :reopened | |
35 | + end | |
36 | + | |
37 | + state :opened | |
38 | + | |
39 | + state :reopened | |
40 | + | |
41 | + state :closed | |
42 | + end | |
43 | + | |
44 | + | |
27 | 45 | def self.open_for(user) |
28 | 46 | opened.assigned(user) |
29 | 47 | end | ... | ... |
app/models/project.rb
... | ... | @@ -43,7 +43,7 @@ class Project < ActiveRecord::Base |
43 | 43 | |
44 | 44 | has_many :events, dependent: :destroy |
45 | 45 | has_many :merge_requests, dependent: :destroy |
46 | - has_many :issues, dependent: :destroy, order: "closed, created_at DESC" | |
46 | + has_many :issues, dependent: :destroy, order: "state, created_at DESC" | |
47 | 47 | has_many :milestones, dependent: :destroy |
48 | 48 | has_many :users_projects, dependent: :destroy |
49 | 49 | has_many :notes, dependent: :destroy | ... | ... |
app/observers/issue_observer.rb
... | ... | @@ -7,22 +7,31 @@ class IssueObserver < ActiveRecord::Observer |
7 | 7 | end |
8 | 8 | end |
9 | 9 | |
10 | - def after_update(issue) | |
10 | + def after_close(issue, transition) | |
11 | 11 | send_reassigned_email(issue) if issue.is_being_reassigned? |
12 | 12 | |
13 | - status = nil | |
14 | - status = 'closed' if issue.is_being_closed? | |
15 | - status = 'reopened' if issue.is_being_reopened? | |
16 | - if status | |
17 | - Note.create_status_change_note(issue, current_user, status) | |
18 | - [issue.author, issue.assignee].compact.each do |recipient| | |
19 | - Notify.delay.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) | |
20 | - end | |
21 | - end | |
13 | + create_note(issue) | |
14 | + end | |
15 | + | |
16 | + def after_reopen(issue, transition) | |
17 | + send_reassigned_email(issue) if issue.is_being_reassigned? | |
18 | + | |
19 | + create_note(issue) | |
20 | + end | |
21 | + | |
22 | + def after_update(issue) | |
23 | + send_reassigned_email(issue) if issue.is_being_reassigned? | |
22 | 24 | end |
23 | 25 | |
24 | 26 | protected |
25 | 27 | |
28 | + def create_note(issue) | |
29 | + Note.create_status_change_note(issue, current_user, issue.state) | |
30 | + [issue.author, issue.assignee].compact.each do |recipient| | |
31 | + Notify.delay.issue_status_changed_email(recipient.id, issue.id, issue.state, current_user.id) | |
32 | + end | |
33 | + end | |
34 | + | |
26 | 35 | def send_reassigned_email(issue) |
27 | 36 | recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id } |
28 | 37 | ... | ... |
app/views/issues/_show.html.haml
... | ... | @@ -8,10 +8,10 @@ |
8 | 8 | %i.icon-comment |
9 | 9 | = issue.notes.count |
10 | 10 | - if can? current_user, :modify_issue, issue |
11 | - - if issue.closed | |
12 | - = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {closed: false }, status_only: true), method: :put, class: "btn btn-small grouped reopen_issue", remote: true | |
11 | + - if issue.closed? | |
12 | + = link_to 'Reopen', project_issue_path(issue.project, issue, issue: {state: :reopened }, status_only: true), method: :put, class: "btn btn-small grouped reopen_issue", remote: true | |
13 | 13 | - else |
14 | - = link_to 'Close', project_issue_path(issue.project, issue, issue: {closed: true }, status_only: true), method: :put, class: "btn btn-small grouped close_issue", remote: true | |
14 | + = link_to 'Close', project_issue_path(issue.project, issue, issue: {state: :closed }, status_only: true), method: :put, class: "btn btn-small grouped close_issue", remote: true | |
15 | 15 | = link_to edit_project_issue_path(issue.project, issue), class: "btn btn-small edit-issue-link grouped" do |
16 | 16 | %i.icon-edit |
17 | 17 | Edit | ... | ... |
app/views/issues/show.html.haml
... | ... | @@ -7,10 +7,10 @@ |
7 | 7 | |
8 | 8 | %span.pull-right |
9 | 9 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
10 | - - if @issue.closed | |
11 | - = link_to 'Reopen', project_issue_path(@project, @issue, issue: {closed: false }, status_only: true), method: :put, class: "btn grouped reopen_issue" | |
10 | + - if @issue.closed? | |
11 | + = link_to 'Reopen', project_issue_path(@project, @issue, issue: {state: :reopened }, status_only: true), method: :put, class: "btn grouped reopen_issue" | |
12 | 12 | - else |
13 | - = link_to 'Close', project_issue_path(@project, @issue, issue: {closed: true }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" | |
13 | + = link_to 'Close', project_issue_path(@project, @issue, issue: {state: :closed }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" | |
14 | 14 | - if can?(current_user, :admin_project, @project) || @issue.author == current_user |
15 | 15 | = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do |
16 | 16 | %i.icon-edit |
... | ... | @@ -27,7 +27,7 @@ |
27 | 27 | .ui-box.ui-box-show |
28 | 28 | .ui-box-head |
29 | 29 | %h4.box-title |
30 | - - if @issue.closed | |
30 | + - if @issue.closed? | |
31 | 31 | .error.status_info Closed |
32 | 32 | = gfm escape_once(@issue.title) |
33 | 33 | ... | ... |
lib/api/entities.rb
... | ... | @@ -35,12 +35,11 @@ module Gitlab |
35 | 35 | class Group < Grape::Entity |
36 | 36 | expose :id, :name, :path, :owner_id |
37 | 37 | end |
38 | - | |
38 | + | |
39 | 39 | class GroupDetail < Group |
40 | 40 | expose :projects, using: Entities::Project |
41 | 41 | end |
42 | 42 | |
43 | - | |
44 | 43 | class RepoObject < Grape::Entity |
45 | 44 | expose :name, :commit |
46 | 45 | expose :protected do |repo, options| |
... | ... | @@ -63,7 +62,7 @@ module Gitlab |
63 | 62 | class Milestone < Grape::Entity |
64 | 63 | expose :id |
65 | 64 | expose (:project_id) {|milestone| milestone.project.id} |
66 | - expose :title, :description, :due_date, :closed, :updated_at, :created_at | |
65 | + expose :title, :description, :due_date, :state, :updated_at, :created_at | |
67 | 66 | end |
68 | 67 | |
69 | 68 | class Issue < Grape::Entity |
... | ... | @@ -73,7 +72,7 @@ module Gitlab |
73 | 72 | expose :label_list, as: :labels |
74 | 73 | expose :milestone, using: Entities::Milestone |
75 | 74 | expose :assignee, :author, using: Entities::UserBasic |
76 | - expose :closed, :updated_at, :created_at | |
75 | + expose :state, :updated_at, :created_at | |
77 | 76 | end |
78 | 77 | |
79 | 78 | class SSHKey < Grape::Entity | ... | ... |
lib/api/issues.rb
... | ... | @@ -69,14 +69,14 @@ module Gitlab |
69 | 69 | # assignee_id (optional) - The ID of a user to assign issue |
70 | 70 | # milestone_id (optional) - The ID of a milestone to assign issue |
71 | 71 | # labels (optional) - The labels of an issue |
72 | - # closed (optional) - The state of an issue (0 = false, 1 = true) | |
72 | + # state (optional) - The state of an issue (close|reopen) | |
73 | 73 | # Example Request: |
74 | 74 | # PUT /projects/:id/issues/:issue_id |
75 | 75 | put ":id/issues/:issue_id" do |
76 | 76 | @issue = user_project.issues.find(params[:issue_id]) |
77 | 77 | authorize! :modify_issue, @issue |
78 | 78 | |
79 | - attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :closed] | |
79 | + attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event] | |
80 | 80 | attrs[:label_list] = params[:labels] if params[:labels].present? |
81 | 81 | IssueObserver.current_user = current_user |
82 | 82 | if @issue.update_attributes attrs | ... | ... |
spec/factories.rb
... | ... | @@ -54,10 +54,15 @@ FactoryGirl.define do |
54 | 54 | project |
55 | 55 | |
56 | 56 | trait :closed do |
57 | - closed true | |
57 | + state :closed | |
58 | + end | |
59 | + | |
60 | + trait :reopened do | |
61 | + state :reopened | |
58 | 62 | end |
59 | 63 | |
60 | 64 | factory :closed_issue, traits: [:closed] |
65 | + factory :reopened_issue, traits: [:reopened] | |
61 | 66 | end |
62 | 67 | |
63 | 68 | factory :merge_request do | ... | ... |
spec/models/issue_spec.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # project_id :integer |
10 | 10 | # created_at :datetime not null |
11 | 11 | # updated_at :datetime not null |
12 | -# closed :boolean default(FALSE), not null | |
12 | +# state :string default(FALSE), not null | |
13 | 13 | # position :integer default(0) |
14 | 14 | # branch_name :string(255) |
15 | 15 | # description :text | ... | ... |
spec/observers/issue_observer_spec.rb
1 | 1 | require 'spec_helper' |
2 | 2 | |
3 | 3 | describe IssueObserver do |
4 | - let(:some_user) { double(:user, id: 1) } | |
5 | - let(:assignee) { double(:user, id: 2) } | |
6 | - let(:author) { double(:user, id: 3) } | |
7 | - let(:issue) { double(:issue, id: 42, assignee: assignee, author: author) } | |
4 | + let(:some_user) { create :user } | |
5 | + let(:assignee) { create :user } | |
6 | + let(:author) { create :user } | |
7 | + let(:mock_issue) { double(:issue, id: 42, assignee: assignee, author: author) } | |
8 | + let(:assigned_issue) { create(:issue, assignee: assignee, author: author) } | |
9 | + let(:unassigned_issue) { create(:issue, author: author) } | |
10 | + let(:closed_assigned_issue) { create(:closed_issue, assignee: assignee, author: author) } | |
11 | + let(:closed_unassigned_issue) { create(:closed_issue, author: author) } | |
12 | + | |
8 | 13 | |
9 | 14 | before(:each) { subject.stub(:current_user).and_return(some_user) } |
10 | 15 | |
... | ... | @@ -21,137 +26,91 @@ describe IssueObserver do |
21 | 26 | end |
22 | 27 | |
23 | 28 | it 'sends an email to the assignee' do |
24 | - Notify.should_receive(:new_issue_email).with(issue.id) | |
29 | + Notify.should_receive(:new_issue_email).with(mock_issue.id) | |
25 | 30 | |
26 | - subject.after_create(issue) | |
31 | + subject.after_create(mock_issue) | |
27 | 32 | end |
28 | 33 | |
29 | 34 | it 'does not send an email to the assignee if assignee created the issue' do |
30 | 35 | subject.stub(:current_user).and_return(assignee) |
31 | 36 | Notify.should_not_receive(:new_issue_email) |
32 | 37 | |
33 | - subject.after_create(issue) | |
38 | + subject.after_create(mock_issue) | |
34 | 39 | end |
35 | 40 | end |
36 | 41 | |
37 | - context '#after_update' do | |
38 | - before(:each) do | |
39 | - issue.stub(:is_being_reassigned?).and_return(false) | |
40 | - issue.stub(:is_being_closed?).and_return(false) | |
41 | - issue.stub(:is_being_reopened?).and_return(false) | |
42 | - end | |
43 | - | |
44 | - it 'is called when an issue is changed' do | |
45 | - changed = create(:issue, project: create(:project)) | |
46 | - subject.should_receive(:after_update) | |
47 | - | |
48 | - Issue.observers.enable :issue_observer do | |
49 | - changed.description = 'I changed' | |
50 | - changed.save | |
51 | - end | |
52 | - end | |
53 | - | |
54 | - context 'a reassigned email' do | |
55 | - it 'is sent if the issue is being reassigned' do | |
56 | - issue.should_receive(:is_being_reassigned?).and_return(true) | |
57 | - subject.should_receive(:send_reassigned_email).with(issue) | |
58 | - | |
59 | - subject.after_update(issue) | |
60 | - end | |
61 | - | |
62 | - it 'is not sent if the issue is not being reassigned' do | |
63 | - issue.should_receive(:is_being_reassigned?).and_return(false) | |
64 | - subject.should_not_receive(:send_reassigned_email) | |
65 | - | |
66 | - subject.after_update(issue) | |
67 | - end | |
68 | - end | |
69 | - | |
42 | + context '#after_close' do | |
70 | 43 | context 'a status "closed"' do |
71 | 44 | it 'note is created if the issue is being closed' do |
72 | - issue.should_receive(:is_being_closed?).and_return(true) | |
73 | - Notify.should_receive(:issue_status_changed_email).twice | |
74 | - Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed') | |
75 | - | |
76 | - subject.after_update(issue) | |
77 | - end | |
78 | - | |
79 | - it 'note is not created if the issue is not being closed' do | |
80 | - issue.should_receive(:is_being_closed?).and_return(false) | |
81 | - Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed') | |
45 | + Note.should_receive(:create_status_change_note).with(assigned_issue, some_user, 'closed') | |
82 | 46 | |
83 | - subject.after_update(issue) | |
47 | + assigned_issue.close | |
84 | 48 | end |
85 | 49 | |
86 | 50 | it 'notification is delivered if the issue being closed' do |
87 | - issue.stub(:is_being_closed?).and_return(true) | |
88 | 51 | Notify.should_receive(:issue_status_changed_email).twice |
89 | - Note.should_receive(:create_status_change_note).with(issue, some_user, 'closed') | |
90 | 52 | |
91 | - subject.after_update(issue) | |
92 | - end | |
93 | - | |
94 | - it 'notification is not delivered if the issue not being closed' do | |
95 | - issue.stub(:is_being_closed?).and_return(false) | |
96 | - Notify.should_not_receive(:issue_status_changed_email) | |
97 | - Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'closed') | |
98 | - | |
99 | - subject.after_update(issue) | |
53 | + assigned_issue.close | |
100 | 54 | end |
101 | 55 | |
102 | 56 | it 'notification is delivered only to author if the issue being closed' do |
103 | - issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil) | |
104 | - issue_without_assignee.stub(:is_being_reassigned?).and_return(false) | |
105 | - issue_without_assignee.stub(:is_being_closed?).and_return(true) | |
106 | - issue_without_assignee.stub(:is_being_reopened?).and_return(false) | |
107 | 57 | Notify.should_receive(:issue_status_changed_email).once |
108 | - Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'closed') | |
58 | + Note.should_receive(:create_status_change_note).with(unassigned_issue, some_user, 'closed') | |
109 | 59 | |
110 | - subject.after_update(issue_without_assignee) | |
60 | + unassigned_issue.close | |
111 | 61 | end |
112 | 62 | end |
113 | 63 | |
114 | 64 | context 'a status "reopened"' do |
115 | 65 | it 'note is created if the issue is being reopened' do |
66 | + Note.should_receive(:create_status_change_note).with(closed_assigned_issue, some_user, 'reopened') | |
67 | + | |
68 | + closed_assigned_issue.reopen | |
69 | + end | |
70 | + | |
71 | + it 'notification is delivered if the issue being reopened' do | |
116 | 72 | Notify.should_receive(:issue_status_changed_email).twice |
117 | - issue.should_receive(:is_being_reopened?).and_return(true) | |
118 | - Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened') | |
119 | 73 | |
120 | - subject.after_update(issue) | |
74 | + closed_assigned_issue.reopen | |
121 | 75 | end |
122 | 76 | |
123 | - it 'note is not created if the issue is not being reopened' do | |
124 | - issue.should_receive(:is_being_reopened?).and_return(false) | |
125 | - Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened') | |
77 | + it 'notification is delivered only to author if the issue being reopened' do | |
78 | + Notify.should_receive(:issue_status_changed_email).once | |
79 | + Note.should_receive(:create_status_change_note).with(closed_unassigned_issue, some_user, 'reopened') | |
126 | 80 | |
127 | - subject.after_update(issue) | |
81 | + closed_unassigned_issue.reopen | |
128 | 82 | end |
83 | + end | |
84 | + end | |
129 | 85 | |
130 | - it 'notification is delivered if the issue being reopened' do | |
131 | - issue.stub(:is_being_reopened?).and_return(true) | |
132 | - Notify.should_receive(:issue_status_changed_email).twice | |
133 | - Note.should_receive(:create_status_change_note).with(issue, some_user, 'reopened') | |
86 | + context '#after_update' do | |
87 | + before(:each) do | |
88 | + mock_issue.stub(:is_being_reassigned?).and_return(false) | |
89 | + end | |
90 | + | |
91 | + it 'is called when an issue is changed' do | |
92 | + changed = create(:issue, project: create(:project)) | |
93 | + subject.should_receive(:after_update) | |
134 | 94 | |
135 | - subject.after_update(issue) | |
95 | + Issue.observers.enable :issue_observer do | |
96 | + changed.description = 'I changed' | |
97 | + changed.save | |
136 | 98 | end |
99 | + end | |
137 | 100 | |
138 | - it 'notification is not delivered if the issue not being reopened' do | |
139 | - issue.stub(:is_being_reopened?).and_return(false) | |
140 | - Notify.should_not_receive(:issue_status_changed_email) | |
141 | - Note.should_not_receive(:create_status_change_note).with(issue, some_user, 'reopened') | |
101 | + context 'a reassigned email' do | |
102 | + it 'is sent if the issue is being reassigned' do | |
103 | + mock_issue.should_receive(:is_being_reassigned?).and_return(true) | |
104 | + subject.should_receive(:send_reassigned_email).with(mock_issue) | |
142 | 105 | |
143 | - subject.after_update(issue) | |
106 | + subject.after_update(mock_issue) | |
144 | 107 | end |
145 | 108 | |
146 | - it 'notification is delivered only to author if the issue being reopened' do | |
147 | - issue_without_assignee = double(:issue, id: 42, author: author, assignee: nil) | |
148 | - issue_without_assignee.stub(:is_being_reassigned?).and_return(false) | |
149 | - issue_without_assignee.stub(:is_being_closed?).and_return(false) | |
150 | - issue_without_assignee.stub(:is_being_reopened?).and_return(true) | |
151 | - Notify.should_receive(:issue_status_changed_email).once | |
152 | - Note.should_receive(:create_status_change_note).with(issue_without_assignee, some_user, 'reopened') | |
109 | + it 'is not sent if the issue is not being reassigned' do | |
110 | + mock_issue.should_receive(:is_being_reassigned?).and_return(false) | |
111 | + subject.should_not_receive(:send_reassigned_email) | |
153 | 112 | |
154 | - subject.after_update(issue_without_assignee) | |
113 | + subject.after_update(mock_issue) | |
155 | 114 | end |
156 | 115 | end |
157 | 116 | end |
... | ... | @@ -160,23 +119,23 @@ describe IssueObserver do |
160 | 119 | let(:previous_assignee) { double(:user, id: 3) } |
161 | 120 | |
162 | 121 | before(:each) do |
163 | - issue.stub(:assignee_id).and_return(assignee.id) | |
164 | - issue.stub(:assignee_id_was).and_return(previous_assignee.id) | |
122 | + mock_issue.stub(:assignee_id).and_return(assignee.id) | |
123 | + mock_issue.stub(:assignee_id_was).and_return(previous_assignee.id) | |
165 | 124 | end |
166 | 125 | |
167 | 126 | def it_sends_a_reassigned_email_to(recipient) |
168 | - Notify.should_receive(:reassigned_issue_email).with(recipient, issue.id, previous_assignee.id) | |
127 | + Notify.should_receive(:reassigned_issue_email).with(recipient, mock_issue.id, previous_assignee.id) | |
169 | 128 | end |
170 | 129 | |
171 | 130 | def it_does_not_send_a_reassigned_email_to(recipient) |
172 | - Notify.should_not_receive(:reassigned_issue_email).with(recipient, issue.id, previous_assignee.id) | |
131 | + Notify.should_not_receive(:reassigned_issue_email).with(recipient, mock_issue.id, previous_assignee.id) | |
173 | 132 | end |
174 | 133 | |
175 | 134 | it 'sends a reassigned email to the previous and current assignees' do |
176 | 135 | it_sends_a_reassigned_email_to assignee.id |
177 | 136 | it_sends_a_reassigned_email_to previous_assignee.id |
178 | 137 | |
179 | - subject.send(:send_reassigned_email, issue) | |
138 | + subject.send(:send_reassigned_email, mock_issue) | |
180 | 139 | end |
181 | 140 | |
182 | 141 | context 'does not send an email to the user who made the reassignment' do |
... | ... | @@ -185,14 +144,14 @@ describe IssueObserver do |
185 | 144 | it_sends_a_reassigned_email_to previous_assignee.id |
186 | 145 | it_does_not_send_a_reassigned_email_to assignee.id |
187 | 146 | |
188 | - subject.send(:send_reassigned_email, issue) | |
147 | + subject.send(:send_reassigned_email, mock_issue) | |
189 | 148 | end |
190 | 149 | it 'if the user is the previous assignee' do |
191 | 150 | subject.stub(:current_user).and_return(previous_assignee) |
192 | 151 | it_sends_a_reassigned_email_to assignee.id |
193 | 152 | it_does_not_send_a_reassigned_email_to previous_assignee.id |
194 | 153 | |
195 | - subject.send(:send_reassigned_email, issue) | |
154 | + subject.send(:send_reassigned_email, mock_issue) | |
196 | 155 | end |
197 | 156 | end |
198 | 157 | end | ... | ... |
spec/requests/api/issues_spec.rb
... | ... | @@ -54,14 +54,24 @@ describe Gitlab::API do |
54 | 54 | end |
55 | 55 | end |
56 | 56 | |
57 | - describe "PUT /projects/:id/issues/:issue_id" do | |
57 | + describe "PUT /projects/:id/issues/:issue_id to update only title" do | |
58 | 58 | it "should update a project issue" do |
59 | 59 | put api("/projects/#{project.id}/issues/#{issue.id}", user), |
60 | - title: 'updated title', labels: 'label2', closed: 1 | |
60 | + title: 'updated title' | |
61 | 61 | response.status.should == 200 |
62 | + | |
62 | 63 | json_response['title'].should == 'updated title' |
64 | + end | |
65 | + end | |
66 | + | |
67 | + describe "PUT /projects/:id/issues/:issue_id to update state and label" do | |
68 | + it "should update a project issue" do | |
69 | + put api("/projects/#{project.id}/issues/#{issue.id}", user), | |
70 | + labels: 'label2', state_event: "close" | |
71 | + response.status.should == 200 | |
72 | + | |
63 | 73 | json_response['labels'].should == ['label2'] |
64 | - json_response['closed'].should be_true | |
74 | + json_response['state'].should eq "closed" | |
65 | 75 | end |
66 | 76 | end |
67 | 77 | ... | ... |
spec/requests/issues_spec.rb
... | ... | @@ -58,8 +58,7 @@ describe "Issues" do |
58 | 58 | |
59 | 59 | it "should be able to search on different statuses" do |
60 | 60 | issue = Issue.first # with title 'foobar' |
61 | - issue.closed = true | |
62 | - issue.save | |
61 | + issue.close | |
63 | 62 | |
64 | 63 | visit project_issues_path(project) |
65 | 64 | click_link 'Closed' | ... | ... |