##// END OF EJS Templates
Move all API tests into the ApiTest module to make management easier...
Eric Davis -
r4243:d5fde17bf5d0
parent child
Show More
@@ -1,110 +1,110
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2
2
3 class DisabledRestApi < ActionController::IntegrationTest
3 class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
4 fixtures :all
4 fixtures :all
5
5
6 def setup
6 def setup
7 Setting.rest_api_enabled = '0'
7 Setting.rest_api_enabled = '0'
8 Setting.login_required = '1'
8 Setting.login_required = '1'
9 end
9 end
10
10
11 def teardown
11 def teardown
12 Setting.rest_api_enabled = '1'
12 Setting.rest_api_enabled = '1'
13 Setting.login_required = '0'
13 Setting.login_required = '0'
14 end
14 end
15
15
16 # Using the NewsController because it's a simple API.
16 # Using the NewsController because it's a simple API.
17 context "get /news with the API disabled" do
17 context "get /news with the API disabled" do
18
18
19 context "in :xml format" do
19 context "in :xml format" do
20 context "with a valid api token" do
20 context "with a valid api token" do
21 setup do
21 setup do
22 @user = User.generate_with_protected!
22 @user = User.generate_with_protected!
23 @token = Token.generate!(:user => @user, :action => 'api')
23 @token = Token.generate!(:user => @user, :action => 'api')
24 get "/news.xml?key=#{@token.value}"
24 get "/news.xml?key=#{@token.value}"
25 end
25 end
26
26
27 should_respond_with :unauthorized
27 should_respond_with :unauthorized
28 should_respond_with_content_type :xml
28 should_respond_with_content_type :xml
29 should "not login as the user" do
29 should "not login as the user" do
30 assert_equal User.anonymous, User.current
30 assert_equal User.anonymous, User.current
31 end
31 end
32 end
32 end
33
33
34 context "with a valid HTTP authentication" do
34 context "with a valid HTTP authentication" do
35 setup do
35 setup do
36 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
36 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
38 get "/news.xml", nil, :authorization => @authorization
38 get "/news.xml", nil, :authorization => @authorization
39 end
39 end
40
40
41 should_respond_with :unauthorized
41 should_respond_with :unauthorized
42 should_respond_with_content_type :xml
42 should_respond_with_content_type :xml
43 should "not login as the user" do
43 should "not login as the user" do
44 assert_equal User.anonymous, User.current
44 assert_equal User.anonymous, User.current
45 end
45 end
46 end
46 end
47
47
48 context "with a valid HTTP authentication using the API token" do
48 context "with a valid HTTP authentication using the API token" do
49 setup do
49 setup do
50 @user = User.generate_with_protected!
50 @user = User.generate_with_protected!
51 @token = Token.generate!(:user => @user, :action => 'api')
51 @token = Token.generate!(:user => @user, :action => 'api')
52 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
52 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
53 get "/news.xml", nil, :authorization => @authorization
53 get "/news.xml", nil, :authorization => @authorization
54 end
54 end
55
55
56 should_respond_with :unauthorized
56 should_respond_with :unauthorized
57 should_respond_with_content_type :xml
57 should_respond_with_content_type :xml
58 should "not login as the user" do
58 should "not login as the user" do
59 assert_equal User.anonymous, User.current
59 assert_equal User.anonymous, User.current
60 end
60 end
61 end
61 end
62 end
62 end
63
63
64 context "in :json format" do
64 context "in :json format" do
65 context "with a valid api token" do
65 context "with a valid api token" do
66 setup do
66 setup do
67 @user = User.generate_with_protected!
67 @user = User.generate_with_protected!
68 @token = Token.generate!(:user => @user, :action => 'api')
68 @token = Token.generate!(:user => @user, :action => 'api')
69 get "/news.json?key=#{@token.value}"
69 get "/news.json?key=#{@token.value}"
70 end
70 end
71
71
72 should_respond_with :unauthorized
72 should_respond_with :unauthorized
73 should_respond_with_content_type :json
73 should_respond_with_content_type :json
74 should "not login as the user" do
74 should "not login as the user" do
75 assert_equal User.anonymous, User.current
75 assert_equal User.anonymous, User.current
76 end
76 end
77 end
77 end
78
78
79 context "with a valid HTTP authentication" do
79 context "with a valid HTTP authentication" do
80 setup do
80 setup do
81 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
81 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
82 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
82 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
83 get "/news.json", nil, :authorization => @authorization
83 get "/news.json", nil, :authorization => @authorization
84 end
84 end
85
85
86 should_respond_with :unauthorized
86 should_respond_with :unauthorized
87 should_respond_with_content_type :json
87 should_respond_with_content_type :json
88 should "not login as the user" do
88 should "not login as the user" do
89 assert_equal User.anonymous, User.current
89 assert_equal User.anonymous, User.current
90 end
90 end
91 end
91 end
92
92
93 context "with a valid HTTP authentication using the API token" do
93 context "with a valid HTTP authentication using the API token" do
94 setup do
94 setup do
95 @user = User.generate_with_protected!
95 @user = User.generate_with_protected!
96 @token = Token.generate!(:user => @user, :action => 'api')
96 @token = Token.generate!(:user => @user, :action => 'api')
97 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
97 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
98 get "/news.json", nil, :authorization => @authorization
98 get "/news.json", nil, :authorization => @authorization
99 end
99 end
100
100
101 should_respond_with :unauthorized
101 should_respond_with :unauthorized
102 should_respond_with_content_type :json
102 should_respond_with_content_type :json
103 should "not login as the user" do
103 should "not login as the user" do
104 assert_equal User.anonymous, User.current
104 assert_equal User.anonymous, User.current
105 end
105 end
106 end
106 end
107
107
108 end
108 end
109 end
109 end
110 end
110 end
@@ -1,103 +1,103
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2
2
3 class HttpBasicLoginTest < ActionController::IntegrationTest
3 class ApiTest::HttpBasicLoginTest < ActionController::IntegrationTest
4 fixtures :all
4 fixtures :all
5
5
6 def setup
6 def setup
7 Setting.rest_api_enabled = '1'
7 Setting.rest_api_enabled = '1'
8 Setting.login_required = '1'
8 Setting.login_required = '1'
9 end
9 end
10
10
11 def teardown
11 def teardown
12 Setting.rest_api_enabled = '0'
12 Setting.rest_api_enabled = '0'
13 Setting.login_required = '0'
13 Setting.login_required = '0'
14 end
14 end
15
15
16 # Using the NewsController because it's a simple API.
16 # Using the NewsController because it's a simple API.
17 context "get /news" do
17 context "get /news" do
18
18
19 context "in :xml format" do
19 context "in :xml format" do
20 context "with a valid HTTP authentication" do
20 context "with a valid HTTP authentication" do
21 setup do
21 setup do
22 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
22 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
23 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
23 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
24 get "/news.xml", nil, :authorization => @authorization
24 get "/news.xml", nil, :authorization => @authorization
25 end
25 end
26
26
27 should_respond_with :success
27 should_respond_with :success
28 should_respond_with_content_type :xml
28 should_respond_with_content_type :xml
29 should "login as the user" do
29 should "login as the user" do
30 assert_equal @user, User.current
30 assert_equal @user, User.current
31 end
31 end
32 end
32 end
33
33
34 context "with an invalid HTTP authentication" do
34 context "with an invalid HTTP authentication" do
35 setup do
35 setup do
36 @user = User.generate_with_protected!
36 @user = User.generate_with_protected!
37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
38 get "/news.xml", nil, :authorization => @authorization
38 get "/news.xml", nil, :authorization => @authorization
39 end
39 end
40
40
41 should_respond_with :unauthorized
41 should_respond_with :unauthorized
42 should_respond_with_content_type :xml
42 should_respond_with_content_type :xml
43 should "not login as the user" do
43 should "not login as the user" do
44 assert_equal User.anonymous, User.current
44 assert_equal User.anonymous, User.current
45 end
45 end
46 end
46 end
47
47
48 context "without credentials" do
48 context "without credentials" do
49 setup do
49 setup do
50 get "/projects/onlinestore/news.xml"
50 get "/projects/onlinestore/news.xml"
51 end
51 end
52
52
53 should_respond_with :unauthorized
53 should_respond_with :unauthorized
54 should_respond_with_content_type :xml
54 should_respond_with_content_type :xml
55 should "include_www_authenticate_header" do
55 should "include_www_authenticate_header" do
56 assert @controller.response.headers.has_key?('WWW-Authenticate')
56 assert @controller.response.headers.has_key?('WWW-Authenticate')
57 end
57 end
58 end
58 end
59 end
59 end
60
60
61 context "in :json format" do
61 context "in :json format" do
62 context "with a valid HTTP authentication" do
62 context "with a valid HTTP authentication" do
63 setup do
63 setup do
64 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
64 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
65 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
65 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
66 get "/news.json", nil, :authorization => @authorization
66 get "/news.json", nil, :authorization => @authorization
67 end
67 end
68
68
69 should_respond_with :success
69 should_respond_with :success
70 should_respond_with_content_type :json
70 should_respond_with_content_type :json
71 should "login as the user" do
71 should "login as the user" do
72 assert_equal @user, User.current
72 assert_equal @user, User.current
73 end
73 end
74 end
74 end
75
75
76 context "with an invalid HTTP authentication" do
76 context "with an invalid HTTP authentication" do
77 setup do
77 setup do
78 @user = User.generate_with_protected!
78 @user = User.generate_with_protected!
79 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
79 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
80 get "/news.json", nil, :authorization => @authorization
80 get "/news.json", nil, :authorization => @authorization
81 end
81 end
82
82
83 should_respond_with :unauthorized
83 should_respond_with :unauthorized
84 should_respond_with_content_type :json
84 should_respond_with_content_type :json
85 should "not login as the user" do
85 should "not login as the user" do
86 assert_equal User.anonymous, User.current
86 assert_equal User.anonymous, User.current
87 end
87 end
88 end
88 end
89 end
89 end
90
90
91 context "without credentials" do
91 context "without credentials" do
92 setup do
92 setup do
93 get "/projects/onlinestore/news.json"
93 get "/projects/onlinestore/news.json"
94 end
94 end
95
95
96 should_respond_with :unauthorized
96 should_respond_with :unauthorized
97 should_respond_with_content_type :json
97 should_respond_with_content_type :json
98 should "include_www_authenticate_header" do
98 should "include_www_authenticate_header" do
99 assert @controller.response.headers.has_key?('WWW-Authenticate')
99 assert @controller.response.headers.has_key?('WWW-Authenticate')
100 end
100 end
101 end
101 end
102 end
102 end
103 end
103 end
@@ -1,84 +1,84
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2
2
3 class HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
3 class ApiTest::HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
4 fixtures :all
4 fixtures :all
5
5
6 def setup
6 def setup
7 Setting.rest_api_enabled = '1'
7 Setting.rest_api_enabled = '1'
8 Setting.login_required = '1'
8 Setting.login_required = '1'
9 end
9 end
10
10
11 def teardown
11 def teardown
12 Setting.rest_api_enabled = '0'
12 Setting.rest_api_enabled = '0'
13 Setting.login_required = '0'
13 Setting.login_required = '0'
14 end
14 end
15
15
16 # Using the NewsController because it's a simple API.
16 # Using the NewsController because it's a simple API.
17 context "get /news" do
17 context "get /news" do
18
18
19 context "in :xml format" do
19 context "in :xml format" do
20 context "with a valid HTTP authentication using the API token" do
20 context "with a valid HTTP authentication using the API token" do
21 setup do
21 setup do
22 @user = User.generate_with_protected!
22 @user = User.generate_with_protected!
23 @token = Token.generate!(:user => @user, :action => 'api')
23 @token = Token.generate!(:user => @user, :action => 'api')
24 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
24 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
25 get "/news.xml", nil, :authorization => @authorization
25 get "/news.xml", nil, :authorization => @authorization
26 end
26 end
27
27
28 should_respond_with :success
28 should_respond_with :success
29 should_respond_with_content_type :xml
29 should_respond_with_content_type :xml
30 should "login as the user" do
30 should "login as the user" do
31 assert_equal @user, User.current
31 assert_equal @user, User.current
32 end
32 end
33 end
33 end
34
34
35 context "with an invalid HTTP authentication" do
35 context "with an invalid HTTP authentication" do
36 setup do
36 setup do
37 @user = User.generate_with_protected!
37 @user = User.generate_with_protected!
38 @token = Token.generate!(:user => @user, :action => 'feeds')
38 @token = Token.generate!(:user => @user, :action => 'feeds')
39 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
39 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
40 get "/news.xml", nil, :authorization => @authorization
40 get "/news.xml", nil, :authorization => @authorization
41 end
41 end
42
42
43 should_respond_with :unauthorized
43 should_respond_with :unauthorized
44 should_respond_with_content_type :xml
44 should_respond_with_content_type :xml
45 should "not login as the user" do
45 should "not login as the user" do
46 assert_equal User.anonymous, User.current
46 assert_equal User.anonymous, User.current
47 end
47 end
48 end
48 end
49 end
49 end
50
50
51 context "in :json format" do
51 context "in :json format" do
52 context "with a valid HTTP authentication" do
52 context "with a valid HTTP authentication" do
53 setup do
53 setup do
54 @user = User.generate_with_protected!
54 @user = User.generate_with_protected!
55 @token = Token.generate!(:user => @user, :action => 'api')
55 @token = Token.generate!(:user => @user, :action => 'api')
56 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
56 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
57 get "/news.json", nil, :authorization => @authorization
57 get "/news.json", nil, :authorization => @authorization
58 end
58 end
59
59
60 should_respond_with :success
60 should_respond_with :success
61 should_respond_with_content_type :json
61 should_respond_with_content_type :json
62 should "login as the user" do
62 should "login as the user" do
63 assert_equal @user, User.current
63 assert_equal @user, User.current
64 end
64 end
65 end
65 end
66
66
67 context "with an invalid HTTP authentication" do
67 context "with an invalid HTTP authentication" do
68 setup do
68 setup do
69 @user = User.generate_with_protected!
69 @user = User.generate_with_protected!
70 @token = Token.generate!(:user => @user, :action => 'feeds')
70 @token = Token.generate!(:user => @user, :action => 'feeds')
71 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
71 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
72 get "/news.json", nil, :authorization => @authorization
72 get "/news.json", nil, :authorization => @authorization
73 end
73 end
74
74
75 should_respond_with :unauthorized
75 should_respond_with :unauthorized
76 should_respond_with_content_type :json
76 should_respond_with_content_type :json
77 should "not login as the user" do
77 should "not login as the user" do
78 assert_equal User.anonymous, User.current
78 assert_equal User.anonymous, User.current
79 end
79 end
80 end
80 end
81 end
81 end
82
82
83 end
83 end
84 end
84 end
@@ -1,349 +1,349
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 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.dirname(__FILE__)}/../test_helper"
18 require "#{File.dirname(__FILE__)}/../../test_helper"
19
19
20 class IssuesApiTest < ActionController::IntegrationTest
20 class ApiTest::IssuesTest < ActionController::IntegrationTest
21 fixtures :projects,
21 fixtures :projects,
22 :users,
22 :users,
23 :roles,
23 :roles,
24 :members,
24 :members,
25 :member_roles,
25 :member_roles,
26 :issues,
26 :issues,
27 :issue_statuses,
27 :issue_statuses,
28 :versions,
28 :versions,
29 :trackers,
29 :trackers,
30 :projects_trackers,
30 :projects_trackers,
31 :issue_categories,
31 :issue_categories,
32 :enabled_modules,
32 :enabled_modules,
33 :enumerations,
33 :enumerations,
34 :attachments,
34 :attachments,
35 :workflows,
35 :workflows,
36 :custom_fields,
36 :custom_fields,
37 :custom_values,
37 :custom_values,
38 :custom_fields_projects,
38 :custom_fields_projects,
39 :custom_fields_trackers,
39 :custom_fields_trackers,
40 :time_entries,
40 :time_entries,
41 :journals,
41 :journals,
42 :journal_details,
42 :journal_details,
43 :queries
43 :queries
44
44
45 def setup
45 def setup
46 Setting.rest_api_enabled = '1'
46 Setting.rest_api_enabled = '1'
47 end
47 end
48
48
49 context "/index.xml" do
49 context "/index.xml" do
50 setup do
50 setup do
51 get '/issues.xml'
51 get '/issues.xml'
52 end
52 end
53
53
54 should_respond_with :success
54 should_respond_with :success
55 should_respond_with_content_type 'application/xml'
55 should_respond_with_content_type 'application/xml'
56 end
56 end
57
57
58 context "/index.json" do
58 context "/index.json" do
59 setup do
59 setup do
60 get '/issues.json'
60 get '/issues.json'
61 end
61 end
62
62
63 should_respond_with :success
63 should_respond_with :success
64 should_respond_with_content_type 'application/json'
64 should_respond_with_content_type 'application/json'
65
65
66 should 'return a valid JSON string' do
66 should 'return a valid JSON string' do
67 assert ActiveSupport::JSON.decode(response.body)
67 assert ActiveSupport::JSON.decode(response.body)
68 end
68 end
69 end
69 end
70
70
71 context "/index.xml with filter" do
71 context "/index.xml with filter" do
72 setup do
72 setup do
73 get '/issues.xml?status_id=5'
73 get '/issues.xml?status_id=5'
74 end
74 end
75
75
76 should_respond_with :success
76 should_respond_with :success
77 should_respond_with_content_type 'application/xml'
77 should_respond_with_content_type 'application/xml'
78 should "show only issues with the status_id" do
78 should "show only issues with the status_id" do
79 assert_tag :tag => 'issues',
79 assert_tag :tag => 'issues',
80 :children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
80 :children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
81 :only => { :tag => 'issue' } }
81 :only => { :tag => 'issue' } }
82 end
82 end
83 end
83 end
84
84
85 context "/index.json with filter" do
85 context "/index.json with filter" do
86 setup do
86 setup do
87 get '/issues.json?status_id=5'
87 get '/issues.json?status_id=5'
88 end
88 end
89
89
90 should_respond_with :success
90 should_respond_with :success
91 should_respond_with_content_type 'application/json'
91 should_respond_with_content_type 'application/json'
92
92
93 should 'return a valid JSON string' do
93 should 'return a valid JSON string' do
94 assert ActiveSupport::JSON.decode(response.body)
94 assert ActiveSupport::JSON.decode(response.body)
95 end
95 end
96
96
97 should "show only issues with the status_id" do
97 should "show only issues with the status_id" do
98 json = ActiveSupport::JSON.decode(response.body)
98 json = ActiveSupport::JSON.decode(response.body)
99 status_ids_used = json.collect {|j| j['status_id'] }
99 status_ids_used = json.collect {|j| j['status_id'] }
100 assert_equal 3, status_ids_used.length
100 assert_equal 3, status_ids_used.length
101 assert status_ids_used.all? {|id| id == 5 }
101 assert status_ids_used.all? {|id| id == 5 }
102 end
102 end
103
103
104 end
104 end
105
105
106 context "/issues/1.xml" do
106 context "/issues/1.xml" do
107 setup do
107 setup do
108 get '/issues/1.xml'
108 get '/issues/1.xml'
109 end
109 end
110
110
111 should_respond_with :success
111 should_respond_with :success
112 should_respond_with_content_type 'application/xml'
112 should_respond_with_content_type 'application/xml'
113 end
113 end
114
114
115 context "/issues/1.json" do
115 context "/issues/1.json" do
116 setup do
116 setup do
117 get '/issues/1.json'
117 get '/issues/1.json'
118 end
118 end
119
119
120 should_respond_with :success
120 should_respond_with :success
121 should_respond_with_content_type 'application/json'
121 should_respond_with_content_type 'application/json'
122
122
123 should 'return a valid JSON string' do
123 should 'return a valid JSON string' do
124 assert ActiveSupport::JSON.decode(response.body)
124 assert ActiveSupport::JSON.decode(response.body)
125 end
125 end
126 end
126 end
127
127
128 context "POST /issues.xml" do
128 context "POST /issues.xml" do
129 setup do
129 setup do
130 @issue_count = Issue.count
130 @issue_count = Issue.count
131 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
131 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
132 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
132 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
133 end
133 end
134
134
135 should_respond_with :created
135 should_respond_with :created
136 should_respond_with_content_type 'application/xml'
136 should_respond_with_content_type 'application/xml'
137
137
138 should "create an issue with the attributes" do
138 should "create an issue with the attributes" do
139 assert_equal Issue.count, @issue_count + 1
139 assert_equal Issue.count, @issue_count + 1
140
140
141 issue = Issue.first(:order => 'id DESC')
141 issue = Issue.first(:order => 'id DESC')
142 @attributes.each do |attribute, value|
142 @attributes.each do |attribute, value|
143 assert_equal value, issue.send(attribute)
143 assert_equal value, issue.send(attribute)
144 end
144 end
145 end
145 end
146 end
146 end
147
147
148 context "POST /issues.xml with failure" do
148 context "POST /issues.xml with failure" do
149 setup do
149 setup do
150 @attributes = {:project_id => 1}
150 @attributes = {:project_id => 1}
151 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
151 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
152 end
152 end
153
153
154 should_respond_with :unprocessable_entity
154 should_respond_with :unprocessable_entity
155 should_respond_with_content_type 'application/xml'
155 should_respond_with_content_type 'application/xml'
156
156
157 should "have an errors tag" do
157 should "have an errors tag" do
158 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
158 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
159 end
159 end
160 end
160 end
161
161
162 context "POST /issues.json" do
162 context "POST /issues.json" do
163 setup do
163 setup do
164 @issue_count = Issue.count
164 @issue_count = Issue.count
165 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
165 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
166 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
166 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
167 end
167 end
168
168
169 should_respond_with :created
169 should_respond_with :created
170 should_respond_with_content_type 'application/json'
170 should_respond_with_content_type 'application/json'
171
171
172 should "create an issue with the attributes" do
172 should "create an issue with the attributes" do
173 assert_equal Issue.count, @issue_count + 1
173 assert_equal Issue.count, @issue_count + 1
174
174
175 issue = Issue.first(:order => 'id DESC')
175 issue = Issue.first(:order => 'id DESC')
176 @attributes.each do |attribute, value|
176 @attributes.each do |attribute, value|
177 assert_equal value, issue.send(attribute)
177 assert_equal value, issue.send(attribute)
178 end
178 end
179 end
179 end
180 end
180 end
181
181
182 context "POST /issues.json with failure" do
182 context "POST /issues.json with failure" do
183 setup do
183 setup do
184 @attributes = {:project_id => 1}
184 @attributes = {:project_id => 1}
185 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
185 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
186 end
186 end
187
187
188 should_respond_with :unprocessable_entity
188 should_respond_with :unprocessable_entity
189 should_respond_with_content_type 'application/json'
189 should_respond_with_content_type 'application/json'
190
190
191 should "have an errors element" do
191 should "have an errors element" do
192 json = ActiveSupport::JSON.decode(response.body)
192 json = ActiveSupport::JSON.decode(response.body)
193 assert_equal "can't be blank", json.first['subject']
193 assert_equal "can't be blank", json.first['subject']
194 end
194 end
195 end
195 end
196
196
197 context "PUT /issues/1.xml" do
197 context "PUT /issues/1.xml" do
198 setup do
198 setup do
199 @issue_count = Issue.count
199 @issue_count = Issue.count
200 @journal_count = Journal.count
200 @journal_count = Journal.count
201 @attributes = {:subject => 'API update', :notes => 'A new note'}
201 @attributes = {:subject => 'API update', :notes => 'A new note'}
202
202
203 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
203 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
204 end
204 end
205
205
206 should_respond_with :ok
206 should_respond_with :ok
207 should_respond_with_content_type 'application/xml'
207 should_respond_with_content_type 'application/xml'
208
208
209 should "not create a new issue" do
209 should "not create a new issue" do
210 assert_equal Issue.count, @issue_count
210 assert_equal Issue.count, @issue_count
211 end
211 end
212
212
213 should "create a new journal" do
213 should "create a new journal" do
214 assert_equal Journal.count, @journal_count + 1
214 assert_equal Journal.count, @journal_count + 1
215 end
215 end
216
216
217 should "add the note to the journal" do
217 should "add the note to the journal" do
218 journal = Journal.last
218 journal = Journal.last
219 assert_equal "A new note", journal.notes
219 assert_equal "A new note", journal.notes
220 end
220 end
221
221
222 should "update the issue" do
222 should "update the issue" do
223 issue = Issue.find(1)
223 issue = Issue.find(1)
224 @attributes.each do |attribute, value|
224 @attributes.each do |attribute, value|
225 assert_equal value, issue.send(attribute) unless attribute == :notes
225 assert_equal value, issue.send(attribute) unless attribute == :notes
226 end
226 end
227 end
227 end
228
228
229 end
229 end
230
230
231 context "PUT /issues/1.xml with failed update" do
231 context "PUT /issues/1.xml with failed update" do
232 setup do
232 setup do
233 @attributes = {:subject => ''}
233 @attributes = {:subject => ''}
234 @issue_count = Issue.count
234 @issue_count = Issue.count
235 @journal_count = Journal.count
235 @journal_count = Journal.count
236
236
237 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
237 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
238 end
238 end
239
239
240 should_respond_with :unprocessable_entity
240 should_respond_with :unprocessable_entity
241 should_respond_with_content_type 'application/xml'
241 should_respond_with_content_type 'application/xml'
242
242
243 should "not create a new issue" do
243 should "not create a new issue" do
244 assert_equal Issue.count, @issue_count
244 assert_equal Issue.count, @issue_count
245 end
245 end
246
246
247 should "not create a new journal" do
247 should "not create a new journal" do
248 assert_equal Journal.count, @journal_count
248 assert_equal Journal.count, @journal_count
249 end
249 end
250
250
251 should "have an errors tag" do
251 should "have an errors tag" do
252 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
252 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
253 end
253 end
254 end
254 end
255
255
256 context "PUT /issues/1.json" do
256 context "PUT /issues/1.json" do
257 setup do
257 setup do
258 @issue_count = Issue.count
258 @issue_count = Issue.count
259 @journal_count = Journal.count
259 @journal_count = Journal.count
260 @attributes = {:subject => 'API update', :notes => 'A new note'}
260 @attributes = {:subject => 'API update', :notes => 'A new note'}
261
261
262 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
262 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
263 end
263 end
264
264
265 should_respond_with :ok
265 should_respond_with :ok
266 should_respond_with_content_type 'application/json'
266 should_respond_with_content_type 'application/json'
267
267
268 should "not create a new issue" do
268 should "not create a new issue" do
269 assert_equal Issue.count, @issue_count
269 assert_equal Issue.count, @issue_count
270 end
270 end
271
271
272 should "create a new journal" do
272 should "create a new journal" do
273 assert_equal Journal.count, @journal_count + 1
273 assert_equal Journal.count, @journal_count + 1
274 end
274 end
275
275
276 should "add the note to the journal" do
276 should "add the note to the journal" do
277 journal = Journal.last
277 journal = Journal.last
278 assert_equal "A new note", journal.notes
278 assert_equal "A new note", journal.notes
279 end
279 end
280
280
281 should "update the issue" do
281 should "update the issue" do
282 issue = Issue.find(1)
282 issue = Issue.find(1)
283 @attributes.each do |attribute, value|
283 @attributes.each do |attribute, value|
284 assert_equal value, issue.send(attribute) unless attribute == :notes
284 assert_equal value, issue.send(attribute) unless attribute == :notes
285 end
285 end
286 end
286 end
287
287
288 end
288 end
289
289
290 context "PUT /issues/1.json with failed update" do
290 context "PUT /issues/1.json with failed update" do
291 setup do
291 setup do
292 @attributes = {:subject => ''}
292 @attributes = {:subject => ''}
293 @issue_count = Issue.count
293 @issue_count = Issue.count
294 @journal_count = Journal.count
294 @journal_count = Journal.count
295
295
296 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
296 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
297 end
297 end
298
298
299 should_respond_with :unprocessable_entity
299 should_respond_with :unprocessable_entity
300 should_respond_with_content_type 'application/json'
300 should_respond_with_content_type 'application/json'
301
301
302 should "not create a new issue" do
302 should "not create a new issue" do
303 assert_equal Issue.count, @issue_count
303 assert_equal Issue.count, @issue_count
304 end
304 end
305
305
306 should "not create a new journal" do
306 should "not create a new journal" do
307 assert_equal Journal.count, @journal_count
307 assert_equal Journal.count, @journal_count
308 end
308 end
309
309
310 should "have an errors attribute" do
310 should "have an errors attribute" do
311 json = ActiveSupport::JSON.decode(response.body)
311 json = ActiveSupport::JSON.decode(response.body)
312 assert_equal "can't be blank", json.first['subject']
312 assert_equal "can't be blank", json.first['subject']
313 end
313 end
314 end
314 end
315
315
316 context "DELETE /issues/1.xml" do
316 context "DELETE /issues/1.xml" do
317 setup do
317 setup do
318 @issue_count = Issue.count
318 @issue_count = Issue.count
319 delete '/issues/1.xml', {}, :authorization => credentials('jsmith')
319 delete '/issues/1.xml', {}, :authorization => credentials('jsmith')
320 end
320 end
321
321
322 should_respond_with :ok
322 should_respond_with :ok
323 should_respond_with_content_type 'application/xml'
323 should_respond_with_content_type 'application/xml'
324
324
325 should "delete the issue" do
325 should "delete the issue" do
326 assert_equal Issue.count, @issue_count -1
326 assert_equal Issue.count, @issue_count -1
327 assert_nil Issue.find_by_id(1)
327 assert_nil Issue.find_by_id(1)
328 end
328 end
329 end
329 end
330
330
331 context "DELETE /issues/1.json" do
331 context "DELETE /issues/1.json" do
332 setup do
332 setup do
333 @issue_count = Issue.count
333 @issue_count = Issue.count
334 delete '/issues/1.json', {}, :authorization => credentials('jsmith')
334 delete '/issues/1.json', {}, :authorization => credentials('jsmith')
335 end
335 end
336
336
337 should_respond_with :ok
337 should_respond_with :ok
338 should_respond_with_content_type 'application/json'
338 should_respond_with_content_type 'application/json'
339
339
340 should "delete the issue" do
340 should "delete the issue" do
341 assert_equal Issue.count, @issue_count -1
341 assert_equal Issue.count, @issue_count -1
342 assert_nil Issue.find_by_id(1)
342 assert_nil Issue.find_by_id(1)
343 end
343 end
344 end
344 end
345
345
346 def credentials(user, password=nil)
346 def credentials(user, password=nil)
347 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
347 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
348 end
348 end
349 end
349 end
@@ -1,99 +1,99
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 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.dirname(__FILE__)}/../test_helper"
18 require "#{File.dirname(__FILE__)}/../../test_helper"
19
19
20 class ProjectsApiTest < 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
24
24
25 def setup
25 def setup
26 Setting.rest_api_enabled = '1'
26 Setting.rest_api_enabled = '1'
27 end
27 end
28
28
29 def test_index
29 def test_index
30 get '/projects.xml'
30 get '/projects.xml'
31 assert_response :success
31 assert_response :success
32 assert_equal 'application/xml', @response.content_type
32 assert_equal 'application/xml', @response.content_type
33 end
33 end
34
34
35 def test_show
35 def test_show
36 get '/projects/1.xml'
36 get '/projects/1.xml'
37 assert_response :success
37 assert_response :success
38 assert_equal 'application/xml', @response.content_type
38 assert_equal 'application/xml', @response.content_type
39 end
39 end
40
40
41 def test_create
41 def test_create
42 attributes = {:name => 'API test', :identifier => 'api-test'}
42 attributes = {:name => 'API test', :identifier => 'api-test'}
43 assert_difference 'Project.count' do
43 assert_difference 'Project.count' do
44 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
44 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
45 end
45 end
46 assert_response :created
46 assert_response :created
47 assert_equal 'application/xml', @response.content_type
47 assert_equal 'application/xml', @response.content_type
48 project = Project.first(:order => 'id DESC')
48 project = Project.first(:order => 'id DESC')
49 attributes.each do |attribute, value|
49 attributes.each do |attribute, value|
50 assert_equal value, project.send(attribute)
50 assert_equal value, project.send(attribute)
51 end
51 end
52 end
52 end
53
53
54 def test_create_failure
54 def test_create_failure
55 attributes = {:name => 'API test'}
55 attributes = {:name => 'API test'}
56 assert_no_difference 'Project.count' do
56 assert_no_difference 'Project.count' do
57 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
57 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
58 end
58 end
59 assert_response :unprocessable_entity
59 assert_response :unprocessable_entity
60 assert_equal 'application/xml', @response.content_type
60 assert_equal 'application/xml', @response.content_type
61 assert_tag :errors, :child => {:tag => 'error', :content => "Identifier can't be blank"}
61 assert_tag :errors, :child => {:tag => 'error', :content => "Identifier can't be blank"}
62 end
62 end
63
63
64 def test_update
64 def test_update
65 attributes = {:name => 'API update'}
65 attributes = {:name => 'API update'}
66 assert_no_difference 'Project.count' do
66 assert_no_difference 'Project.count' do
67 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
67 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
68 end
68 end
69 assert_response :ok
69 assert_response :ok
70 assert_equal 'application/xml', @response.content_type
70 assert_equal 'application/xml', @response.content_type
71 project = Project.find(1)
71 project = Project.find(1)
72 attributes.each do |attribute, value|
72 attributes.each do |attribute, value|
73 assert_equal value, project.send(attribute)
73 assert_equal value, project.send(attribute)
74 end
74 end
75 end
75 end
76
76
77 def test_update_failure
77 def test_update_failure
78 attributes = {:name => ''}
78 attributes = {:name => ''}
79 assert_no_difference 'Project.count' do
79 assert_no_difference 'Project.count' do
80 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
80 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
81 end
81 end
82 assert_response :unprocessable_entity
82 assert_response :unprocessable_entity
83 assert_equal 'application/xml', @response.content_type
83 assert_equal 'application/xml', @response.content_type
84 assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
84 assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
85 end
85 end
86
86
87 def test_destroy
87 def test_destroy
88 assert_difference 'Project.count', -1 do
88 assert_difference 'Project.count', -1 do
89 delete '/projects/2.xml', {}, :authorization => credentials('admin')
89 delete '/projects/2.xml', {}, :authorization => credentials('admin')
90 end
90 end
91 assert_response :ok
91 assert_response :ok
92 assert_equal 'application/xml', @response.content_type
92 assert_equal 'application/xml', @response.content_type
93 assert_nil Project.find_by_id(2)
93 assert_nil Project.find_by_id(2)
94 end
94 end
95
95
96 def credentials(user, password=nil)
96 def credentials(user, password=nil)
97 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
97 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
98 end
98 end
99 end
99 end
@@ -1,80 +1,80
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2
2
3 class ApiTokenLoginTest < ActionController::IntegrationTest
3 class ApiTest::TokenAuthenticationTest < ActionController::IntegrationTest
4 fixtures :all
4 fixtures :all
5
5
6 def setup
6 def setup
7 Setting.rest_api_enabled = '1'
7 Setting.rest_api_enabled = '1'
8 Setting.login_required = '1'
8 Setting.login_required = '1'
9 end
9 end
10
10
11 def teardown
11 def teardown
12 Setting.rest_api_enabled = '0'
12 Setting.rest_api_enabled = '0'
13 Setting.login_required = '0'
13 Setting.login_required = '0'
14 end
14 end
15
15
16 # Using the NewsController because it's a simple API.
16 # Using the NewsController because it's a simple API.
17 context "get /news" do
17 context "get /news" do
18
18
19 context "in :xml format" do
19 context "in :xml format" do
20 context "with a valid api token" do
20 context "with a valid api token" do
21 setup do
21 setup do
22 @user = User.generate_with_protected!
22 @user = User.generate_with_protected!
23 @token = Token.generate!(:user => @user, :action => 'api')
23 @token = Token.generate!(:user => @user, :action => 'api')
24 get "/news.xml?key=#{@token.value}"
24 get "/news.xml?key=#{@token.value}"
25 end
25 end
26
26
27 should_respond_with :success
27 should_respond_with :success
28 should_respond_with_content_type :xml
28 should_respond_with_content_type :xml
29 should "login as the user" do
29 should "login as the user" do
30 assert_equal @user, User.current
30 assert_equal @user, User.current
31 end
31 end
32 end
32 end
33
33
34 context "with an invalid api token" do
34 context "with an invalid api token" do
35 setup do
35 setup do
36 @user = User.generate_with_protected!
36 @user = User.generate_with_protected!
37 @token = Token.generate!(:user => @user, :action => 'feeds')
37 @token = Token.generate!(:user => @user, :action => 'feeds')
38 get "/news.xml?key=#{@token.value}"
38 get "/news.xml?key=#{@token.value}"
39 end
39 end
40
40
41 should_respond_with :unauthorized
41 should_respond_with :unauthorized
42 should_respond_with_content_type :xml
42 should_respond_with_content_type :xml
43 should "not login as the user" do
43 should "not login as the user" do
44 assert_equal User.anonymous, User.current
44 assert_equal User.anonymous, User.current
45 end
45 end
46 end
46 end
47 end
47 end
48
48
49 context "in :json format" do
49 context "in :json format" do
50 context "with a valid api token" do
50 context "with a valid api token" do
51 setup do
51 setup do
52 @user = User.generate_with_protected!
52 @user = User.generate_with_protected!
53 @token = Token.generate!(:user => @user, :action => 'api')
53 @token = Token.generate!(:user => @user, :action => 'api')
54 get "/news.json?key=#{@token.value}"
54 get "/news.json?key=#{@token.value}"
55 end
55 end
56
56
57 should_respond_with :success
57 should_respond_with :success
58 should_respond_with_content_type :json
58 should_respond_with_content_type :json
59 should "login as the user" do
59 should "login as the user" do
60 assert_equal @user, User.current
60 assert_equal @user, User.current
61 end
61 end
62 end
62 end
63
63
64 context "with an invalid api token" do
64 context "with an invalid api token" do
65 setup do
65 setup do
66 @user = User.generate_with_protected!
66 @user = User.generate_with_protected!
67 @token = Token.generate!(:user => @user, :action => 'feeds')
67 @token = Token.generate!(:user => @user, :action => 'feeds')
68 get "/news.json?key=#{@token.value}"
68 get "/news.json?key=#{@token.value}"
69 end
69 end
70
70
71 should_respond_with :unauthorized
71 should_respond_with :unauthorized
72 should_respond_with_content_type :json
72 should_respond_with_content_type :json
73 should "not login as the user" do
73 should "not login as the user" do
74 assert_equal User.anonymous, User.current
74 assert_equal User.anonymous, User.current
75 end
75 end
76 end
76 end
77 end
77 end
78
78
79 end
79 end
80 end
80 end
@@ -1,188 +1,192
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 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 ENV["RAILS_ENV"] = "test"
18 ENV["RAILS_ENV"] = "test"
19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
20 require 'test_help'
20 require 'test_help'
21 require File.expand_path(File.dirname(__FILE__) + '/helper_testcase')
21 require File.expand_path(File.dirname(__FILE__) + '/helper_testcase')
22 require File.join(RAILS_ROOT,'test', 'mocks', 'open_id_authentication_mock.rb')
22 require File.join(RAILS_ROOT,'test', 'mocks', 'open_id_authentication_mock.rb')
23
23
24 require File.expand_path(File.dirname(__FILE__) + '/object_daddy_helpers')
24 require File.expand_path(File.dirname(__FILE__) + '/object_daddy_helpers')
25 include ObjectDaddyHelpers
25 include ObjectDaddyHelpers
26
26
27 class ActiveSupport::TestCase
27 class ActiveSupport::TestCase
28 # Transactional fixtures accelerate your tests by wrapping each test method
28 # Transactional fixtures accelerate your tests by wrapping each test method
29 # in a transaction that's rolled back on completion. This ensures that the
29 # in a transaction that's rolled back on completion. This ensures that the
30 # test database remains unchanged so your fixtures don't have to be reloaded
30 # test database remains unchanged so your fixtures don't have to be reloaded
31 # between every test method. Fewer database queries means faster tests.
31 # between every test method. Fewer database queries means faster tests.
32 #
32 #
33 # Read Mike Clark's excellent walkthrough at
33 # Read Mike Clark's excellent walkthrough at
34 # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
34 # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
35 #
35 #
36 # Every Active Record database supports transactions except MyISAM tables
36 # Every Active Record database supports transactions except MyISAM tables
37 # in MySQL. Turn off transactional fixtures in this case; however, if you
37 # in MySQL. Turn off transactional fixtures in this case; however, if you
38 # don't care one way or the other, switching from MyISAM to InnoDB tables
38 # don't care one way or the other, switching from MyISAM to InnoDB tables
39 # is recommended.
39 # is recommended.
40 self.use_transactional_fixtures = true
40 self.use_transactional_fixtures = true
41
41
42 # Instantiated fixtures are slow, but give you @david where otherwise you
42 # Instantiated fixtures are slow, but give you @david where otherwise you
43 # would need people(:david). If you don't want to migrate your existing
43 # would need people(:david). If you don't want to migrate your existing
44 # test cases which use the @david style and don't mind the speed hit (each
44 # test cases which use the @david style and don't mind the speed hit (each
45 # instantiated fixtures translates to a database query per test method),
45 # instantiated fixtures translates to a database query per test method),
46 # then set this back to true.
46 # then set this back to true.
47 self.use_instantiated_fixtures = false
47 self.use_instantiated_fixtures = false
48
48
49 # Add more helper methods to be used by all tests here...
49 # Add more helper methods to be used by all tests here...
50
50
51 def log_user(login, password)
51 def log_user(login, password)
52 User.anonymous
52 User.anonymous
53 get "/login"
53 get "/login"
54 assert_equal nil, session[:user_id]
54 assert_equal nil, session[:user_id]
55 assert_response :success
55 assert_response :success
56 assert_template "account/login"
56 assert_template "account/login"
57 post "/login", :username => login, :password => password
57 post "/login", :username => login, :password => password
58 assert_equal login, User.find(session[:user_id]).login
58 assert_equal login, User.find(session[:user_id]).login
59 end
59 end
60
60
61 def uploaded_test_file(name, mime)
61 def uploaded_test_file(name, mime)
62 ActionController::TestUploadedFile.new(ActiveSupport::TestCase.fixture_path + "/files/#{name}", mime)
62 ActionController::TestUploadedFile.new(ActiveSupport::TestCase.fixture_path + "/files/#{name}", mime)
63 end
63 end
64
64
65 # Mock out a file
65 # Mock out a file
66 def self.mock_file
66 def self.mock_file
67 file = 'a_file.png'
67 file = 'a_file.png'
68 file.stubs(:size).returns(32)
68 file.stubs(:size).returns(32)
69 file.stubs(:original_filename).returns('a_file.png')
69 file.stubs(:original_filename).returns('a_file.png')
70 file.stubs(:content_type).returns('image/png')
70 file.stubs(:content_type).returns('image/png')
71 file.stubs(:read).returns(false)
71 file.stubs(:read).returns(false)
72 file
72 file
73 end
73 end
74
74
75 def mock_file
75 def mock_file
76 self.class.mock_file
76 self.class.mock_file
77 end
77 end
78
78
79 # Use a temporary directory for attachment related tests
79 # Use a temporary directory for attachment related tests
80 def set_tmp_attachments_directory
80 def set_tmp_attachments_directory
81 Dir.mkdir "#{RAILS_ROOT}/tmp/test" unless File.directory?("#{RAILS_ROOT}/tmp/test")
81 Dir.mkdir "#{RAILS_ROOT}/tmp/test" unless File.directory?("#{RAILS_ROOT}/tmp/test")
82 Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
82 Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
83 Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
83 Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
84 end
84 end
85
85
86 def with_settings(options, &block)
86 def with_settings(options, &block)
87 saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h}
87 saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h}
88 options.each {|k, v| Setting[k] = v}
88 options.each {|k, v| Setting[k] = v}
89 yield
89 yield
90 saved_settings.each {|k, v| Setting[k] = v}
90 saved_settings.each {|k, v| Setting[k] = v}
91 end
91 end
92
92
93 def change_user_password(login, new_password)
93 def change_user_password(login, new_password)
94 user = User.first(:conditions => {:login => login})
94 user = User.first(:conditions => {:login => login})
95 user.password, user.password_confirmation = new_password, new_password
95 user.password, user.password_confirmation = new_password, new_password
96 user.save!
96 user.save!
97 end
97 end
98
98
99 def self.ldap_configured?
99 def self.ldap_configured?
100 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
100 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
101 return @test_ldap.bind
101 return @test_ldap.bind
102 rescue Exception => e
102 rescue Exception => e
103 # LDAP is not listening
103 # LDAP is not listening
104 return nil
104 return nil
105 end
105 end
106
106
107 # Returns the path to the test +vendor+ repository
107 # Returns the path to the test +vendor+ repository
108 def self.repository_path(vendor)
108 def self.repository_path(vendor)
109 File.join(RAILS_ROOT.gsub(%r{config\/\.\.}, ''), "/tmp/test/#{vendor.downcase}_repository")
109 File.join(RAILS_ROOT.gsub(%r{config\/\.\.}, ''), "/tmp/test/#{vendor.downcase}_repository")
110 end
110 end
111
111
112 # Returns true if the +vendor+ test repository is configured
112 # Returns true if the +vendor+ test repository is configured
113 def self.repository_configured?(vendor)
113 def self.repository_configured?(vendor)
114 File.directory?(repository_path(vendor))
114 File.directory?(repository_path(vendor))
115 end
115 end
116
116
117 def assert_error_tag(options={})
117 def assert_error_tag(options={})
118 assert_tag({:tag => 'p', :attributes => { :id => 'errorExplanation' }}.merge(options))
118 assert_tag({:tag => 'p', :attributes => { :id => 'errorExplanation' }}.merge(options))
119 end
119 end
120
120
121 # Shoulda macros
121 # Shoulda macros
122 def self.should_render_404
122 def self.should_render_404
123 should_respond_with :not_found
123 should_respond_with :not_found
124 should_render_template 'common/error'
124 should_render_template 'common/error'
125 end
125 end
126
126
127 def self.should_have_before_filter(expected_method, options = {})
127 def self.should_have_before_filter(expected_method, options = {})
128 should_have_filter('before', expected_method, options)
128 should_have_filter('before', expected_method, options)
129 end
129 end
130
130
131 def self.should_have_after_filter(expected_method, options = {})
131 def self.should_have_after_filter(expected_method, options = {})
132 should_have_filter('after', expected_method, options)
132 should_have_filter('after', expected_method, options)
133 end
133 end
134
134
135 def self.should_have_filter(filter_type, expected_method, options)
135 def self.should_have_filter(filter_type, expected_method, options)
136 description = "have #{filter_type}_filter :#{expected_method}"
136 description = "have #{filter_type}_filter :#{expected_method}"
137 description << " with #{options.inspect}" unless options.empty?
137 description << " with #{options.inspect}" unless options.empty?
138
138
139 should description do
139 should description do
140 klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
140 klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
141 expected = klass.new(:filter, expected_method.to_sym, options)
141 expected = klass.new(:filter, expected_method.to_sym, options)
142 assert_equal 1, @controller.class.filter_chain.select { |filter|
142 assert_equal 1, @controller.class.filter_chain.select { |filter|
143 filter.method == expected.method && filter.kind == expected.kind &&
143 filter.method == expected.method && filter.kind == expected.kind &&
144 filter.options == expected.options && filter.class == expected.class
144 filter.options == expected.options && filter.class == expected.class
145 }.size
145 }.size
146 end
146 end
147 end
147 end
148
148
149 def self.should_show_the_old_and_new_values_for(prop_key, model, &block)
149 def self.should_show_the_old_and_new_values_for(prop_key, model, &block)
150 context "" do
150 context "" do
151 setup do
151 setup do
152 if block_given?
152 if block_given?
153 instance_eval &block
153 instance_eval &block
154 else
154 else
155 @old_value = model.generate!
155 @old_value = model.generate!
156 @new_value = model.generate!
156 @new_value = model.generate!
157 end
157 end
158 end
158 end
159
159
160 should "use the new value's name" do
160 should "use the new value's name" do
161 @detail = JournalDetail.generate!(:property => 'attr',
161 @detail = JournalDetail.generate!(:property => 'attr',
162 :old_value => @old_value.id,
162 :old_value => @old_value.id,
163 :value => @new_value.id,
163 :value => @new_value.id,
164 :prop_key => prop_key)
164 :prop_key => prop_key)
165
165
166 assert_match @new_value.name, show_detail(@detail, true)
166 assert_match @new_value.name, show_detail(@detail, true)
167 end
167 end
168
168
169 should "use the old value's name" do
169 should "use the old value's name" do
170 @detail = JournalDetail.generate!(:property => 'attr',
170 @detail = JournalDetail.generate!(:property => 'attr',
171 :old_value => @old_value.id,
171 :old_value => @old_value.id,
172 :value => @new_value.id,
172 :value => @new_value.id,
173 :prop_key => prop_key)
173 :prop_key => prop_key)
174
174
175 assert_match @old_value.name, show_detail(@detail, true)
175 assert_match @old_value.name, show_detail(@detail, true)
176 end
176 end
177 end
177 end
178 end
178 end
179
179
180 def self.should_create_a_new_user(&block)
180 def self.should_create_a_new_user(&block)
181 should "create a new user" do
181 should "create a new user" do
182 user = instance_eval &block
182 user = instance_eval &block
183 assert user
183 assert user
184 assert_kind_of User, user
184 assert_kind_of User, user
185 assert !user.new_record?
185 assert !user.new_record?
186 end
186 end
187 end
187 end
188 end
188 end
189
190 # Simple module to "namespace" all of the API tests
191 module ApiTest
192 end
General Comments 0
You need to be logged in to leave comments. Login now