Commit 0b512af803d007852bcba40c75203e0e45dda177
1 parent
29f70acc
Exists in
master
and in
4 other branches
Milestone uses StateMachine now
Showing
7 changed files
with
39 additions
and
25 deletions
Show diff stats
app/controllers/milestones_controller.rb
@@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController | @@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController | ||
12 | 12 | ||
13 | def index | 13 | def index |
14 | @milestones = case params[:f] | 14 | @milestones = case params[:f] |
15 | - when 'all'; @project.milestones.order("closed, due_date DESC") | 15 | + when 'all'; @project.milestones.order("state, due_date DESC") |
16 | when 'closed'; @project.milestones.closed.order("due_date DESC") | 16 | when 'closed'; @project.milestones.closed.order("due_date DESC") |
17 | else @project.milestones.active.order("due_date ASC") | 17 | else @project.milestones.active.order("due_date ASC") |
18 | end | 18 | end |
app/models/milestone.rb
@@ -13,19 +13,32 @@ | @@ -13,19 +13,32 @@ | ||
13 | # | 13 | # |
14 | 14 | ||
15 | class Milestone < ActiveRecord::Base | 15 | class Milestone < ActiveRecord::Base |
16 | - attr_accessible :title, :description, :due_date, :closed, :author_id_of_changes | 16 | + attr_accessible :title, :description, :due_date, :state_event, :author_id_of_changes |
17 | attr_accessor :author_id_of_changes | 17 | attr_accessor :author_id_of_changes |
18 | 18 | ||
19 | belongs_to :project | 19 | belongs_to :project |
20 | has_many :issues | 20 | has_many :issues |
21 | has_many :merge_requests | 21 | has_many :merge_requests |
22 | 22 | ||
23 | - scope :active, -> { where(closed: false) } | ||
24 | - scope :closed, -> { where(closed: true) } | 23 | + scope :active, -> { with_state(:active) } |
24 | + scope :closed, -> { with_state(:closed) } | ||
25 | 25 | ||
26 | validates :title, presence: true | 26 | validates :title, presence: true |
27 | validates :project, presence: true | 27 | validates :project, presence: true |
28 | - validates :closed, inclusion: { in: [true, false] } | 28 | + |
29 | + state_machine :state, :initial => :active do | ||
30 | + event :close do | ||
31 | + transition :active => :closed | ||
32 | + end | ||
33 | + | ||
34 | + event :activate do | ||
35 | + transition :closed => :active | ||
36 | + end | ||
37 | + | ||
38 | + state :closed | ||
39 | + | ||
40 | + state :active | ||
41 | + end | ||
29 | 42 | ||
30 | def expired? | 43 | def expired? |
31 | if due_date | 44 | if due_date |
@@ -68,17 +81,13 @@ class Milestone < ActiveRecord::Base | @@ -68,17 +81,13 @@ class Milestone < ActiveRecord::Base | ||
68 | end | 81 | end |
69 | 82 | ||
70 | def can_be_closed? | 83 | def can_be_closed? |
71 | - open? && issues.opened.count.zero? | 84 | + active? && issues.opened.count.zero? |
72 | end | 85 | end |
73 | 86 | ||
74 | def is_empty? | 87 | def is_empty? |
75 | total_items_count.zero? | 88 | total_items_count.zero? |
76 | end | 89 | end |
77 | 90 | ||
78 | - def open? | ||
79 | - !closed | ||
80 | - end | ||
81 | - | ||
82 | def author_id | 91 | def author_id |
83 | author_id_of_changes | 92 | author_id_of_changes |
84 | end | 93 | end |
app/views/milestones/_milestone.html.haml
1 | -%li{class: "milestone milestone-#{milestone.closed ? 'closed' : 'open'}", id: dom_id(milestone) } | 1 | +%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } |
2 | .pull-right | 2 | .pull-right |
3 | - - if can?(current_user, :admin_milestone, milestone.project) and milestone.open? | 3 | + - if can?(current_user, :admin_milestone, milestone.project) and milestone.opened? |
4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do | 4 | = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do |
5 | %i.icon-edit | 5 | %i.icon-edit |
6 | Edit | 6 | Edit |
app/views/milestones/show.html.haml
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | ← To milestones list | 9 | ← To milestones list |
10 | .span6 | 10 | .span6 |
11 | .pull-right | 11 | .pull-right |
12 | - - unless @milestone.closed | 12 | + - unless @milestone.closed? |
13 | = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do | 13 | = link_to new_project_issue_path(@project, issue: { milestone_id: @milestone.id }), class: "btn btn-small grouped", title: "New Issue" do |
14 | %i.icon-plus | 14 | %i.icon-plus |
15 | New Issue | 15 | New Issue |
@@ -25,12 +25,12 @@ | @@ -25,12 +25,12 @@ | ||
25 | %hr | 25 | %hr |
26 | %p | 26 | %p |
27 | %span All issues for this milestone are closed. You may close milestone now. | 27 | %span All issues for this milestone are closed. You may close milestone now. |
28 | - = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {closed: true }), method: :put, class: "btn btn-small btn-remove" | 28 | + = link_to 'Close Milestone', project_milestone_path(@project, @milestone, milestone: {state: :closed }), method: :put, class: "btn btn-small btn-remove" |
29 | 29 | ||
30 | .ui-box.ui-box-show | 30 | .ui-box.ui-box-show |
31 | .ui-box-head | 31 | .ui-box-head |
32 | %h4.box-title | 32 | %h4.box-title |
33 | - - if @milestone.closed | 33 | + - if @milestone.closed? |
34 | .error.status_info Closed | 34 | .error.status_info Closed |
35 | - elsif @milestone.expired? | 35 | - elsif @milestone.expired? |
36 | .error.status_info Expired | 36 | .error.status_info Expired |
@@ -63,7 +63,7 @@ | @@ -63,7 +63,7 @@ | ||
63 | %li=link_to('All Issues', '#') | 63 | %li=link_to('All Issues', '#') |
64 | %ul.well-list | 64 | %ul.well-list |
65 | - @issues.each do |issue| | 65 | - @issues.each do |issue| |
66 | - %li{data: {closed: issue.closed}} | 66 | + %li{data: {closed: issue.closed?}} |
67 | = link_to [@project, issue] do | 67 | = link_to [@project, issue] do |
68 | %span.badge.badge-info ##{issue.id} | 68 | %span.badge.badge-info ##{issue.id} |
69 | – | 69 | – |
lib/api/milestones.rb
@@ -59,14 +59,14 @@ module Gitlab | @@ -59,14 +59,14 @@ module Gitlab | ||
59 | # title (optional) - The title of a milestone | 59 | # title (optional) - The title of a milestone |
60 | # description (optional) - The description of a milestone | 60 | # description (optional) - The description of a milestone |
61 | # due_date (optional) - The due date of a milestone | 61 | # due_date (optional) - The due date of a milestone |
62 | - # closed (optional) - The status of the milestone | 62 | + # state (optional) - The status of the milestone (close|activate) |
63 | # Example Request: | 63 | # Example Request: |
64 | # PUT /projects/:id/milestones/:milestone_id | 64 | # PUT /projects/:id/milestones/:milestone_id |
65 | put ":id/milestones/:milestone_id" do | 65 | put ":id/milestones/:milestone_id" do |
66 | authorize! :admin_milestone, user_project | 66 | authorize! :admin_milestone, user_project |
67 | 67 | ||
68 | @milestone = user_project.milestones.find(params[:milestone_id]) | 68 | @milestone = user_project.milestones.find(params[:milestone_id]) |
69 | - attrs = attributes_for_keys [:title, :description, :due_date, :closed] | 69 | + attrs = attributes_for_keys [:title, :description, :due_date, :state_event] |
70 | if @milestone.update_attributes attrs | 70 | if @milestone.update_attributes attrs |
71 | present @milestone, with: Entities::Milestone | 71 | present @milestone, with: Entities::Milestone |
72 | else | 72 | else |
spec/models/milestone_spec.rb
@@ -27,7 +27,6 @@ describe Milestone do | @@ -27,7 +27,6 @@ describe Milestone do | ||
27 | describe "Validation" do | 27 | describe "Validation" do |
28 | it { should validate_presence_of(:title) } | 28 | it { should validate_presence_of(:title) } |
29 | it { should validate_presence_of(:project) } | 29 | it { should validate_presence_of(:project) } |
30 | - it { should ensure_inclusion_of(:closed).in_array([true, false]) } | ||
31 | end | 30 | end |
32 | 31 | ||
33 | let(:milestone) { create(:milestone) } | 32 | let(:milestone) { create(:milestone) } |
@@ -41,7 +40,7 @@ describe Milestone do | @@ -41,7 +40,7 @@ describe Milestone do | ||
41 | 40 | ||
42 | it "should count closed issues" do | 41 | it "should count closed issues" do |
43 | IssueObserver.current_user = issue.author | 42 | IssueObserver.current_user = issue.author |
44 | - issue.update_attributes(closed: true) | 43 | + issue.close |
45 | milestone.issues << issue | 44 | milestone.issues << issue |
46 | milestone.percent_complete.should == 100 | 45 | milestone.percent_complete.should == 100 |
47 | end | 46 | end |
@@ -96,7 +95,7 @@ describe Milestone do | @@ -96,7 +95,7 @@ describe Milestone do | ||
96 | describe :items_count do | 95 | describe :items_count do |
97 | before do | 96 | before do |
98 | milestone.issues << create(:issue) | 97 | milestone.issues << create(:issue) |
99 | - milestone.issues << create(:issue, closed: true) | 98 | + milestone.issues << create(:closed_issue) |
100 | milestone.merge_requests << create(:merge_request) | 99 | milestone.merge_requests << create(:merge_request) |
101 | end | 100 | end |
102 | 101 | ||
@@ -109,8 +108,4 @@ describe Milestone do | @@ -109,8 +108,4 @@ describe Milestone do | ||
109 | describe :can_be_closed? do | 108 | describe :can_be_closed? do |
110 | it { milestone.can_be_closed?.should be_true } | 109 | it { milestone.can_be_closed?.should be_true } |
111 | end | 110 | end |
112 | - | ||
113 | - describe :open? do | ||
114 | - it { milestone.open?.should be_true } | ||
115 | - end | ||
116 | end | 111 | end |
spec/requests/api/milestones_spec.rb
@@ -44,4 +44,14 @@ describe Gitlab::API do | @@ -44,4 +44,14 @@ describe Gitlab::API do | ||
44 | json_response['title'].should == 'updated title' | 44 | json_response['title'].should == 'updated title' |
45 | end | 45 | end |
46 | end | 46 | end |
47 | + | ||
48 | + describe "PUT /projects/:id/milestones/:milestone_id to close milestone" do | ||
49 | + it "should update a project milestone" do | ||
50 | + put api("/projects/#{project.id}/milestones/#{milestone.id}", user), | ||
51 | + state_event: 'close' | ||
52 | + response.status.should == 200 | ||
53 | + | ||
54 | + json_response['state'].should == 'closed' | ||
55 | + end | ||
56 | + end | ||
47 | end | 57 | end |