##// END OF EJS Templates
Makes issue categories available in project REST API (#9553)....
Jean-Philippe Lang -
r7760:30556f8cbfac
parent child
Show More
@@ -1,19 +1,25
1 api.project do
1 api.project do
2 api.id @project.id
2 api.id @project.id
3 api.name @project.name
3 api.name @project.name
4 api.identifier @project.identifier
4 api.identifier @project.identifier
5 api.description @project.description
5 api.description @project.description
6 api.homepage @project.homepage
6 api.homepage @project.homepage
7 api.parent(:id => @project.parent.id, :name => @project.parent.name) if @project.parent && @project.parent.visible?
7 api.parent(:id => @project.parent.id, :name => @project.parent.name) if @project.parent && @project.parent.visible?
8
8
9 render_api_custom_values @project.visible_custom_field_values, api
9 render_api_custom_values @project.visible_custom_field_values, api
10
10
11 api.created_on @project.created_on
11 api.created_on @project.created_on
12 api.updated_on @project.updated_on
12 api.updated_on @project.updated_on
13
13
14 api.array :trackers do
14 api.array :trackers do
15 @project.trackers.each do |tracker|
15 @project.trackers.each do |tracker|
16 api.tracker(:id => tracker.id, :name => tracker.name)
16 api.tracker(:id => tracker.id, :name => tracker.name)
17 end
17 end
18 end if include_in_api_response?('trackers')
18 end if include_in_api_response?('trackers')
19
20 api.array :issue_categories do
21 @project.issue_categories.each do |category|
22 api.issue_category(:id => category.id, :name => category.name)
23 end
24 end if include_in_api_response?('issue_categories')
19 end
25 end
@@ -1,262 +1,297
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class ApiTest::ProjectsTest < ActionController::IntegrationTest
20 class ApiTest::ProjectsTest < ActionController::IntegrationTest
21 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
21 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
23 :attachments, :custom_fields, :custom_values, :time_entries
23 :attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
24
24
25 def setup
25 def setup
26 Setting.rest_api_enabled = '1'
26 Setting.rest_api_enabled = '1'
27 set_tmp_attachments_directory
27 set_tmp_attachments_directory
28 end
28 end
29
29
30 context "GET /projects" do
30 context "GET /projects" do
31 context ".xml" do
31 context ".xml" do
32 should "return projects" do
32 should "return projects" do
33 get '/projects.xml'
33 get '/projects.xml'
34 assert_response :success
34 assert_response :success
35 assert_equal 'application/xml', @response.content_type
35 assert_equal 'application/xml', @response.content_type
36
36
37 assert_tag :tag => 'projects',
37 assert_tag :tag => 'projects',
38 :child => {:tag => 'project', :child => {:tag => 'id', :content => '1'}}
38 :child => {:tag => 'project', :child => {:tag => 'id', :content => '1'}}
39 end
39 end
40 end
40 end
41
41
42 context ".json" do
42 context ".json" do
43 should "return projects" do
43 should "return projects" do
44 get '/projects.json'
44 get '/projects.json'
45 assert_response :success
45 assert_response :success
46 assert_equal 'application/json', @response.content_type
46 assert_equal 'application/json', @response.content_type
47
47
48 json = ActiveSupport::JSON.decode(response.body)
48 json = ActiveSupport::JSON.decode(response.body)
49 assert_kind_of Hash, json
49 assert_kind_of Hash, json
50 assert_kind_of Array, json['projects']
50 assert_kind_of Array, json['projects']
51 assert_kind_of Hash, json['projects'].first
51 assert_kind_of Hash, json['projects'].first
52 assert json['projects'].first.has_key?('id')
52 assert json['projects'].first.has_key?('id')
53 end
53 end
54 end
54 end
55 end
55 end
56
56
57 context "GET /projects/:id" do
57 context "GET /projects/:id" do
58 context ".xml" do
58 context ".xml" do
59 # TODO: A private project is needed because should_allow_api_authentication
59 # TODO: A private project is needed because should_allow_api_authentication
60 # actually tests that authentication is *required*, not just allowed
60 # actually tests that authentication is *required*, not just allowed
61 should_allow_api_authentication(:get, "/projects/2.xml")
61 should_allow_api_authentication(:get, "/projects/2.xml")
62
62
63 should "return requested project" do
63 should "return requested project" do
64 get '/projects/1.xml'
64 get '/projects/1.xml'
65 assert_response :success
65 assert_response :success
66 assert_equal 'application/xml', @response.content_type
66 assert_equal 'application/xml', @response.content_type
67
67
68 assert_tag :tag => 'project',
68 assert_tag :tag => 'project',
69 :child => {:tag => 'id', :content => '1'}
69 :child => {:tag => 'id', :content => '1'}
70 assert_tag :tag => 'custom_field',
70 assert_tag :tag => 'custom_field',
71 :attributes => {:name => 'Development status'}, :content => 'Stable'
71 :attributes => {:name => 'Development status'}, :content => 'Stable'
72
73 assert_no_tag 'trackers'
74 assert_no_tag 'issue_categories'
72 end
75 end
73
76
74 context "with hidden custom fields" do
77 context "with hidden custom fields" do
75 setup do
78 setup do
76 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
79 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
77 end
80 end
78
81
79 should "not display hidden custom fields" do
82 should "not display hidden custom fields" do
80 get '/projects/1.xml'
83 get '/projects/1.xml'
81 assert_response :success
84 assert_response :success
82 assert_equal 'application/xml', @response.content_type
85 assert_equal 'application/xml', @response.content_type
83
86
84 assert_no_tag 'custom_field',
87 assert_no_tag 'custom_field',
85 :attributes => {:name => 'Development status'}
88 :attributes => {:name => 'Development status'}
86 end
89 end
87 end
90 end
91
92 should "return categories with include=issue_categories" do
93 get '/projects/1.xml?include=issue_categories'
94 assert_response :success
95 assert_equal 'application/xml', @response.content_type
96
97 assert_tag 'issue_categories',
98 :attributes => {:type => 'array'},
99 :child => {
100 :tag => 'issue_category',
101 :attributes => {
102 :id => '2',
103 :name => 'Recipes'
104 }
105 }
106 end
107
108 should "return trackers with include=trackers" do
109 get '/projects/1.xml?include=trackers'
110 assert_response :success
111 assert_equal 'application/xml', @response.content_type
112
113 assert_tag 'trackers',
114 :attributes => {:type => 'array'},
115 :child => {
116 :tag => 'tracker',
117 :attributes => {
118 :id => '2',
119 :name => 'Feature request'
120 }
121 }
122 end
88 end
123 end
89
124
90 context ".json" do
125 context ".json" do
91 should_allow_api_authentication(:get, "/projects/2.json")
126 should_allow_api_authentication(:get, "/projects/2.json")
92
127
93 should "return requested project" do
128 should "return requested project" do
94 get '/projects/1.json'
129 get '/projects/1.json'
95
130
96 json = ActiveSupport::JSON.decode(response.body)
131 json = ActiveSupport::JSON.decode(response.body)
97 assert_kind_of Hash, json
132 assert_kind_of Hash, json
98 assert_kind_of Hash, json['project']
133 assert_kind_of Hash, json['project']
99 assert_equal 1, json['project']['id']
134 assert_equal 1, json['project']['id']
100 end
135 end
101 end
136 end
102 end
137 end
103
138
104 context "POST /projects" do
139 context "POST /projects" do
105 context "with valid parameters" do
140 context "with valid parameters" do
106 setup do
141 setup do
107 Setting.default_projects_modules = ['issue_tracking', 'repository']
142 Setting.default_projects_modules = ['issue_tracking', 'repository']
108 @parameters = {:project => {:name => 'API test', :identifier => 'api-test'}}
143 @parameters = {:project => {:name => 'API test', :identifier => 'api-test'}}
109 end
144 end
110
145
111 context ".xml" do
146 context ".xml" do
112 should_allow_api_authentication(:post,
147 should_allow_api_authentication(:post,
113 '/projects.xml',
148 '/projects.xml',
114 {:project => {:name => 'API test', :identifier => 'api-test'}},
149 {:project => {:name => 'API test', :identifier => 'api-test'}},
115 {:success_code => :created})
150 {:success_code => :created})
116
151
117
152
118 should "create a project with the attributes" do
153 should "create a project with the attributes" do
119 assert_difference('Project.count') do
154 assert_difference('Project.count') do
120 post '/projects.xml', @parameters, :authorization => credentials('admin')
155 post '/projects.xml', @parameters, :authorization => credentials('admin')
121 end
156 end
122
157
123 project = Project.first(:order => 'id DESC')
158 project = Project.first(:order => 'id DESC')
124 assert_equal 'API test', project.name
159 assert_equal 'API test', project.name
125 assert_equal 'api-test', project.identifier
160 assert_equal 'api-test', project.identifier
126 assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
161 assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
127 assert_equal Tracker.all.size, project.trackers.size
162 assert_equal Tracker.all.size, project.trackers.size
128
163
129 assert_response :created
164 assert_response :created
130 assert_equal 'application/xml', @response.content_type
165 assert_equal 'application/xml', @response.content_type
131 assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
166 assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
132 end
167 end
133
168
134 should "accept enabled_module_names attribute" do
169 should "accept enabled_module_names attribute" do
135 @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
170 @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
136
171
137 assert_difference('Project.count') do
172 assert_difference('Project.count') do
138 post '/projects.xml', @parameters, :authorization => credentials('admin')
173 post '/projects.xml', @parameters, :authorization => credentials('admin')
139 end
174 end
140
175
141 project = Project.first(:order => 'id DESC')
176 project = Project.first(:order => 'id DESC')
142 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
177 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
143 end
178 end
144
179
145 should "accept tracker_ids attribute" do
180 should "accept tracker_ids attribute" do
146 @parameters[:project].merge!({:tracker_ids => [1, 3]})
181 @parameters[:project].merge!({:tracker_ids => [1, 3]})
147
182
148 assert_difference('Project.count') do
183 assert_difference('Project.count') do
149 post '/projects.xml', @parameters, :authorization => credentials('admin')
184 post '/projects.xml', @parameters, :authorization => credentials('admin')
150 end
185 end
151
186
152 project = Project.first(:order => 'id DESC')
187 project = Project.first(:order => 'id DESC')
153 assert_equal [1, 3], project.trackers.map(&:id).sort
188 assert_equal [1, 3], project.trackers.map(&:id).sort
154 end
189 end
155 end
190 end
156 end
191 end
157
192
158 context "with invalid parameters" do
193 context "with invalid parameters" do
159 setup do
194 setup do
160 @parameters = {:project => {:name => 'API test'}}
195 @parameters = {:project => {:name => 'API test'}}
161 end
196 end
162
197
163 context ".xml" do
198 context ".xml" do
164 should "return errors" do
199 should "return errors" do
165 assert_no_difference('Project.count') do
200 assert_no_difference('Project.count') do
166 post '/projects.xml', @parameters, :authorization => credentials('admin')
201 post '/projects.xml', @parameters, :authorization => credentials('admin')
167 end
202 end
168
203
169 assert_response :unprocessable_entity
204 assert_response :unprocessable_entity
170 assert_equal 'application/xml', @response.content_type
205 assert_equal 'application/xml', @response.content_type
171 assert_tag 'errors', :child => {:tag => 'error', :content => "Identifier can't be blank"}
206 assert_tag 'errors', :child => {:tag => 'error', :content => "Identifier can't be blank"}
172 end
207 end
173 end
208 end
174 end
209 end
175 end
210 end
176
211
177 context "PUT /projects/:id" do
212 context "PUT /projects/:id" do
178 context "with valid parameters" do
213 context "with valid parameters" do
179 setup do
214 setup do
180 @parameters = {:project => {:name => 'API update'}}
215 @parameters = {:project => {:name => 'API update'}}
181 end
216 end
182
217
183 context ".xml" do
218 context ".xml" do
184 should_allow_api_authentication(:put,
219 should_allow_api_authentication(:put,
185 '/projects/2.xml',
220 '/projects/2.xml',
186 {:project => {:name => 'API update'}},
221 {:project => {:name => 'API update'}},
187 {:success_code => :ok})
222 {:success_code => :ok})
188
223
189 should "update the project" do
224 should "update the project" do
190 assert_no_difference 'Project.count' do
225 assert_no_difference 'Project.count' do
191 put '/projects/2.xml', @parameters, :authorization => credentials('jsmith')
226 put '/projects/2.xml', @parameters, :authorization => credentials('jsmith')
192 end
227 end
193 assert_response :ok
228 assert_response :ok
194 assert_equal 'application/xml', @response.content_type
229 assert_equal 'application/xml', @response.content_type
195 project = Project.find(2)
230 project = Project.find(2)
196 assert_equal 'API update', project.name
231 assert_equal 'API update', project.name
197 end
232 end
198
233
199 should "accept enabled_module_names attribute" do
234 should "accept enabled_module_names attribute" do
200 @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
235 @parameters[:project].merge!({:enabled_module_names => ['issue_tracking', 'news', 'time_tracking']})
201
236
202 assert_no_difference 'Project.count' do
237 assert_no_difference 'Project.count' do
203 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
238 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
204 end
239 end
205 assert_response :ok
240 assert_response :ok
206 project = Project.find(2)
241 project = Project.find(2)
207 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
242 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
208 end
243 end
209
244
210 should "accept tracker_ids attribute" do
245 should "accept tracker_ids attribute" do
211 @parameters[:project].merge!({:tracker_ids => [1, 3]})
246 @parameters[:project].merge!({:tracker_ids => [1, 3]})
212
247
213 assert_no_difference 'Project.count' do
248 assert_no_difference 'Project.count' do
214 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
249 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
215 end
250 end
216 assert_response :ok
251 assert_response :ok
217 project = Project.find(2)
252 project = Project.find(2)
218 assert_equal [1, 3], project.trackers.map(&:id).sort
253 assert_equal [1, 3], project.trackers.map(&:id).sort
219 end
254 end
220 end
255 end
221 end
256 end
222
257
223 context "with invalid parameters" do
258 context "with invalid parameters" do
224 setup do
259 setup do
225 @parameters = {:project => {:name => ''}}
260 @parameters = {:project => {:name => ''}}
226 end
261 end
227
262
228 context ".xml" do
263 context ".xml" do
229 should "return errors" do
264 should "return errors" do
230 assert_no_difference('Project.count') do
265 assert_no_difference('Project.count') do
231 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
266 put '/projects/2.xml', @parameters, :authorization => credentials('admin')
232 end
267 end
233
268
234 assert_response :unprocessable_entity
269 assert_response :unprocessable_entity
235 assert_equal 'application/xml', @response.content_type
270 assert_equal 'application/xml', @response.content_type
236 assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
271 assert_tag 'errors', :child => {:tag => 'error', :content => "Name can't be blank"}
237 end
272 end
238 end
273 end
239 end
274 end
240 end
275 end
241
276
242 context "DELETE /projects/:id" do
277 context "DELETE /projects/:id" do
243 context ".xml" do
278 context ".xml" do
244 should_allow_api_authentication(:delete,
279 should_allow_api_authentication(:delete,
245 '/projects/2.xml',
280 '/projects/2.xml',
246 {},
281 {},
247 {:success_code => :ok})
282 {:success_code => :ok})
248
283
249 should "delete the project" do
284 should "delete the project" do
250 assert_difference('Project.count',-1) do
285 assert_difference('Project.count',-1) do
251 delete '/projects/2.xml', {}, :authorization => credentials('admin')
286 delete '/projects/2.xml', {}, :authorization => credentials('admin')
252 end
287 end
253 assert_response :ok
288 assert_response :ok
254 assert_nil Project.find_by_id(2)
289 assert_nil Project.find_by_id(2)
255 end
290 end
256 end
291 end
257 end
292 end
258
293
259 def credentials(user, password=nil)
294 def credentials(user, password=nil)
260 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
295 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
261 end
296 end
262 end
297 end
General Comments 0
You need to be logged in to leave comments. Login now