@@ -0,0 +1,32 | |||||
|
1 | api.array :issues do | |||
|
2 | @issues.each do |issue| | |||
|
3 | api.issue do | |||
|
4 | api.id issue.id | |||
|
5 | api.project(:id => issue.project_id, :name => issue.project.name) unless issue.project.nil? | |||
|
6 | api.tracker(:id => issue.tracker_id, :name => issue.tracker.name) unless issue.tracker.nil? | |||
|
7 | api.status(:id => issue.status_id, :name => issue.status.name) unless issue.status.nil? | |||
|
8 | api.priority(:id => issue.priority_id, :name => issue.priority.name) unless issue.priority.nil? | |||
|
9 | api.author(:id => issue.author_id, :name => issue.author.name) unless issue.author.nil? | |||
|
10 | api.assigned_to(:id => issue.assigned_to_id, :name => issue.assigned_to.name) unless issue.assigned_to.nil? | |||
|
11 | api.category(:id => issue.category_id, :name => issue.category.name) unless issue.category.nil? | |||
|
12 | api.fixed_version(:id => issue.fixed_version_id, :name => issue.fixed_version.name) unless issue.fixed_version.nil? | |||
|
13 | api.parent(:id => issue.parent_id) unless issue.parent.nil? | |||
|
14 | ||||
|
15 | api.subject issue.subject | |||
|
16 | api.description issue.description | |||
|
17 | api.start_date issue.start_date | |||
|
18 | api.due_date issue.due_date | |||
|
19 | api.done_ratio issue.done_ratio | |||
|
20 | api.estimated_hours issue.estimated_hours | |||
|
21 | ||||
|
22 | api.array :custom_fields do | |||
|
23 | issue.custom_field_values.each do |custom_value| | |||
|
24 | api.custom_field custom_value.value, :id => custom_value.custom_field_id, :name => custom_value.custom_field.name | |||
|
25 | end | |||
|
26 | end | |||
|
27 | ||||
|
28 | api.created_on issue.created_on | |||
|
29 | api.updated_on issue.updated_on | |||
|
30 | end | |||
|
31 | end | |||
|
32 | end |
@@ -0,0 +1,61 | |||||
|
1 | api.issue do | |||
|
2 | api.id @issue.id | |||
|
3 | api.project(:id => @issue.project_id, :name => @issue.project.name) unless @issue.project.nil? | |||
|
4 | api.tracker(:id => @issue.tracker_id, :name => @issue.tracker.name) unless @issue.tracker.nil? | |||
|
5 | api.status(:id => @issue.status_id, :name => @issue.status.name) unless @issue.status.nil? | |||
|
6 | api.priority(:id => @issue.priority_id, :name => @issue.priority.name) unless @issue.priority.nil? | |||
|
7 | api.author(:id => @issue.author_id, :name => @issue.author.name) unless @issue.author.nil? | |||
|
8 | api.assigned_to(:id => @issue.assigned_to_id, :name => @issue.assigned_to.name) unless @issue.assigned_to.nil? | |||
|
9 | api.category(:id => @issue.category_id, :name => @issue.category.name) unless @issue.category.nil? | |||
|
10 | api.fixed_version(:id => @issue.fixed_version_id, :name => @issue.fixed_version.name) unless @issue.fixed_version.nil? | |||
|
11 | api.parent(:id => @issue.parent_id) unless @issue.parent.nil? | |||
|
12 | ||||
|
13 | api.subject @issue.subject | |||
|
14 | api.description @issue.description | |||
|
15 | api.start_date @issue.start_date | |||
|
16 | api.due_date @issue.due_date | |||
|
17 | api.done_ratio @issue.done_ratio | |||
|
18 | api.estimated_hours @issue.estimated_hours | |||
|
19 | if User.current.allowed_to?(:view_time_entries, @project) | |||
|
20 | api.spent_hours @issue.spent_hours | |||
|
21 | end | |||
|
22 | ||||
|
23 | api.array :custom_fields do | |||
|
24 | @issue.custom_field_values.each do |custom_value| | |||
|
25 | api.custom_field custom_value.value, :id => custom_value.custom_field_id, :name => custom_value.custom_field.name | |||
|
26 | end | |||
|
27 | end unless @issue.custom_field_values.empty? | |||
|
28 | ||||
|
29 | api.created_on @issue.created_on | |||
|
30 | api.updated_on @issue.updated_on | |||
|
31 | ||||
|
32 | api.array :relations do | |||
|
33 | @issue.relations.select {|r| r.other_issue(@issue).visible? }.each do |relation| | |||
|
34 | api.relation(:id => relation.id, :issue_id => relation.other_issue(@issue).id, :relation_type => relation.relation_type_for(@issue), :delay => relation.delay) | |||
|
35 | end | |||
|
36 | end | |||
|
37 | ||||
|
38 | api.array :changesets do | |||
|
39 | @issue.changesets.each do |changeset| | |||
|
40 | api.changeset :revision => changeset.revision do | |||
|
41 | api.user(:id => changeset.user_id, :name => changeset.user.name) unless changeset.user.nil? | |||
|
42 | api.comments changeset.comments | |||
|
43 | api.committed_on changeset.committed_on | |||
|
44 | end | |||
|
45 | end | |||
|
46 | end if User.current.allowed_to?(:view_changesets, @project) && @issue.changesets.any? | |||
|
47 | ||||
|
48 | api.array :journals do | |||
|
49 | @issue.journals.each do |journal| | |||
|
50 | api.journal :id => journal.id do | |||
|
51 | api.user(:id => journal.user_id, :name => journal.user.name) unless journal.user.nil? | |||
|
52 | api.notes journal.notes | |||
|
53 | api.array :details do | |||
|
54 | journal.details.each do |detail| | |||
|
55 | api.detail :property => detail.property, :name => detail.prop_key, :old => detail.old_value, :new => detail.value | |||
|
56 | end | |||
|
57 | end | |||
|
58 | end | |||
|
59 | end | |||
|
60 | end unless @issue.journals.empty? | |||
|
61 | end |
@@ -84,8 +84,7 class IssuesController < ApplicationController | |||||
84 |
|
84 | |||
85 | respond_to do |format| |
|
85 | respond_to do |format| | |
86 | format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? } |
|
86 | format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? } | |
87 |
format. |
|
87 | format.api { render :template => 'issues/index.apit' } | |
88 | format.json { render :text => @issues.to_json, :layout => false } |
|
|||
89 | format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } |
|
88 | format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") } | |
90 | format.csv { send_data(issues_to_csv(@issues, @project), :type => 'text/csv; header=present', :filename => 'export.csv') } |
|
89 | format.csv { send_data(issues_to_csv(@issues, @project), :type => 'text/csv; header=present', :filename => 'export.csv') } | |
91 | format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') } |
|
90 | format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'export.pdf') } | |
@@ -110,8 +109,7 class IssuesController < ApplicationController | |||||
110 | @time_entry = TimeEntry.new |
|
109 | @time_entry = TimeEntry.new | |
111 | respond_to do |format| |
|
110 | respond_to do |format| | |
112 | format.html { render :template => 'issues/show.rhtml' } |
|
111 | format.html { render :template => 'issues/show.rhtml' } | |
113 |
format. |
|
112 | format.api { render :template => 'issues/show.apit' } | |
114 | format.json { render :text => @issue.to_json, :layout => false } |
|
|||
115 | format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } |
|
113 | format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' } | |
116 | format.pdf { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") } |
|
114 | format.pdf { send_data(issue_to_pdf(@issue), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") } | |
117 | end |
|
115 | end | |
@@ -138,15 +136,13 class IssuesController < ApplicationController | |||||
138 | redirect_to(params[:continue] ? { :action => 'new', :project_id => @project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } : |
|
136 | redirect_to(params[:continue] ? { :action => 'new', :project_id => @project, :issue => {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?} } : | |
139 | { :action => 'show', :id => @issue }) |
|
137 | { :action => 'show', :id => @issue }) | |
140 | } |
|
138 | } | |
141 |
format. |
|
139 | format.api { render :template => 'issues/show.apit', :status => :created, :location => issue_url(@issue) } | |
142 | format.json { render :text => @issue.to_json, :status => :created, :location => url_for(:controller => 'issues', :action => 'show'), :layout => false } |
|
|||
143 | end |
|
140 | end | |
144 | return |
|
141 | return | |
145 | else |
|
142 | else | |
146 | respond_to do |format| |
|
143 | respond_to do |format| | |
147 | format.html { render :action => 'new' } |
|
144 | format.html { render :action => 'new' } | |
148 | format.xml { render(:xml => @issue.errors, :status => :unprocessable_entity); return } |
|
145 | format.api { render_validation_errors(@issue) } | |
149 | format.json { render :text => object_errors_to_json(@issue), :status => :unprocessable_entity, :layout => false } |
|
|||
150 | end |
|
146 | end | |
151 | end |
|
147 | end | |
152 | end |
|
148 | end | |
@@ -171,8 +167,7 class IssuesController < ApplicationController | |||||
171 |
|
167 | |||
172 | respond_to do |format| |
|
168 | respond_to do |format| | |
173 | format.html { redirect_back_or_default({:action => 'show', :id => @issue}) } |
|
169 | format.html { redirect_back_or_default({:action => 'show', :id => @issue}) } | |
174 |
format. |
|
170 | format.api { head :ok } | |
175 | format.json { head :ok } |
|
|||
176 | end |
|
171 | end | |
177 | else |
|
172 | else | |
178 | render_attachment_warning_if_needed(@issue) |
|
173 | render_attachment_warning_if_needed(@issue) | |
@@ -181,8 +176,7 class IssuesController < ApplicationController | |||||
181 |
|
176 | |||
182 | respond_to do |format| |
|
177 | respond_to do |format| | |
183 | format.html { render :action => 'edit' } |
|
178 | format.html { render :action => 'edit' } | |
184 | format.xml { render :xml => @issue.errors, :status => :unprocessable_entity } |
|
179 | format.api { render_validation_errors(@issue) } | |
185 | format.json { render :text => object_errors_to_json(@issue), :status => :unprocessable_entity, :layout => false } |
|
|||
186 | end |
|
180 | end | |
187 | end |
|
181 | end | |
188 | end |
|
182 | end | |
@@ -232,17 +226,14 class IssuesController < ApplicationController | |||||
232 | TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues]) |
|
226 | TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues]) | |
233 | end |
|
227 | end | |
234 | else |
|
228 | else | |
235 | unless params[:format] == 'xml' || params[:format] == 'json' |
|
229 | # display the destroy form if it's a user request | |
236 | # display the destroy form if it's a user request |
|
230 | return unless api_request? | |
237 | return |
|
|||
238 | end |
|
|||
239 | end |
|
231 | end | |
240 | end |
|
232 | end | |
241 | @issues.each(&:destroy) |
|
233 | @issues.each(&:destroy) | |
242 | respond_to do |format| |
|
234 | respond_to do |format| | |
243 | format.html { redirect_back_or_default(:action => 'index', :project_id => @project) } |
|
235 | format.html { redirect_back_or_default(:action => 'index', :project_id => @project) } | |
244 |
format. |
|
236 | format.api { head :ok } | |
245 | format.json { head :ok } |
|
|||
246 | end |
|
237 | end | |
247 | end |
|
238 | end | |
248 |
|
239 |
@@ -37,6 +37,8 module Redmine | |||||
37 | if args.first.is_a?(Hash) |
|
37 | if args.first.is_a?(Hash) | |
38 | if @struct.last.is_a?(Array) |
|
38 | if @struct.last.is_a?(Array) | |
39 | @struct.last << args.first |
|
39 | @struct.last << args.first | |
|
40 | else | |||
|
41 | @struct.last[sym] = args.first | |||
40 | end |
|
42 | end | |
41 | else |
|
43 | else | |
42 | if @struct.last.is_a?(Array) |
|
44 | if @struct.last.is_a?(Array) |
@@ -74,7 +74,7 class ApiTest::IssuesTest < ActionController::IntegrationTest | |||||
74 | get '/issues.json?status_id=5' |
|
74 | get '/issues.json?status_id=5' | |
75 |
|
75 | |||
76 | json = ActiveSupport::JSON.decode(response.body) |
|
76 | json = ActiveSupport::JSON.decode(response.body) | |
77 |
status_ids_used = json.collect {|j| j['status |
|
77 | status_ids_used = json['issues'].collect {|j| j['status']['id'] } | |
78 | assert_equal 3, status_ids_used.length |
|
78 | assert_equal 3, status_ids_used.length | |
79 | assert status_ids_used.all? {|id| id == 5 } |
|
79 | assert status_ids_used.all? {|id| id == 5 } | |
80 | end |
|
80 | end | |
@@ -160,7 +160,7 class ApiTest::IssuesTest < ActionController::IntegrationTest | |||||
160 | end |
|
160 | end | |
161 |
|
161 | |||
162 | json = ActiveSupport::JSON.decode(response.body) |
|
162 | json = ActiveSupport::JSON.decode(response.body) | |
163 | assert_equal "can't be blank", json.first['subject'] |
|
163 | assert json['errors'].include?(['subject', "can't be blank"]) | |
164 | end |
|
164 | end | |
165 | end |
|
165 | end | |
166 |
|
166 | |||
@@ -300,7 +300,7 class ApiTest::IssuesTest < ActionController::IntegrationTest | |||||
300 | put '/issues/6.json', @parameters, @headers |
|
300 | put '/issues/6.json', @parameters, @headers | |
301 |
|
301 | |||
302 | json = ActiveSupport::JSON.decode(response.body) |
|
302 | json = ActiveSupport::JSON.decode(response.body) | |
303 | assert_equal "can't be blank", json.first['subject'] |
|
303 | assert json['errors'].include?(['subject', "can't be blank"]) | |
304 | end |
|
304 | end | |
305 | end |
|
305 | end | |
306 |
|
306 |
@@ -28,6 +28,15 class Redmine::Views::Builders::JsonTest < HelperTestCase | |||||
28 | end |
|
28 | end | |
29 | end |
|
29 | end | |
30 |
|
30 | |||
|
31 | def test_hash_hash | |||
|
32 | assert_json_output({'person' => {'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b| | |||
|
33 | b.person do | |||
|
34 | b.name 'Ryan' | |||
|
35 | b.birth :city => 'London', :country => 'UK' | |||
|
36 | end | |||
|
37 | end | |||
|
38 | end | |||
|
39 | ||||
31 | def test_array |
|
40 | def test_array | |
32 | assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b| |
|
41 | assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b| | |
33 | b.array :books do |b| |
|
42 | b.array :books do |b| |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now