twurl 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Twurl::Options::Test < Test::Unit::TestCase
4
+ attr_reader :options
5
+ def setup
6
+ @options = Twurl::Options.new
7
+ end
8
+
9
+ def test_base_url_is_built_from_protocol_and_host
10
+ options.protocol = 'http'
11
+ options.host = 'api.twitter.com'
12
+
13
+ assert_equal 'http://api.twitter.com', options.base_url
14
+ end
15
+
16
+ def test_ssl_is_enabled_if_the_protocol_is_https
17
+ options.protocol = 'http'
18
+ assert !options.ssl?
19
+
20
+ options.protocol = 'https'
21
+ assert options.ssl?
22
+ end
23
+ end
data/test/cli_test.rb ADDED
@@ -0,0 +1,129 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Twurl::CLI::OptionParsingTest < Test::Unit::TestCase
4
+ module CommandParsingTests
5
+ def test_no_command_specified_falls_to_default_command
6
+ options = Twurl::CLI.parse_options(['/1/url/does/not/matter.xml'])
7
+ assert_equal Twurl::CLI::DEFAULT_COMMAND, options.command
8
+ end
9
+
10
+ def test_supported_command_specified_extracts_the_command
11
+ expected_command = Twurl::CLI::SUPPORTED_COMMANDS.first
12
+ options = Twurl::CLI.parse_options([expected_command])
13
+ assert_equal expected_command, options.command
14
+ end
15
+
16
+ def test_unsupported_command_specified_sets_default_command
17
+ unsupported_command = 'unsupported'
18
+ options = Twurl::CLI.parse_options([unsupported_command])
19
+ assert_equal Twurl::CLI::DEFAULT_COMMAND, options.command
20
+ end
21
+ end
22
+ include CommandParsingTests
23
+
24
+ module RequestMethodParsingTests
25
+ def test_request_method_is_default_if_unspecified
26
+ options = Twurl::CLI.parse_options(['/1/url/does/not/matter.xml'])
27
+ assert_equal Twurl::Options::DEFAULT_REQUEST_METHOD, options.request_method
28
+ end
29
+
30
+ def test_specifying_a_request_method_extracts_and_normalizes_request_method
31
+ variations = [%w[-X put], %w[-X PUT], %w[--request-method PUT], %w[--request-method put]]
32
+ variations.each do |option_variation|
33
+ path = '/1/url/does/not/matter.xml'
34
+ order_variant_1 = [option_variation, path].flatten
35
+ order_variant_2 = [path, option_variation].flatten
36
+ [order_variant_1, order_variant_2].each do |args|
37
+ options = Twurl::CLI.parse_options(args)
38
+ assert_equal 'put', options.request_method
39
+ end
40
+ end
41
+ end
42
+
43
+ def test_specifying_unsupported_request_method_returns_an_error
44
+ Twurl::CLI.parse_options(['-X', 'UNSUPPORTED'])
45
+ end
46
+ end
47
+ include RequestMethodParsingTests
48
+
49
+ module OAuthClientOptionParsingTests
50
+ def test_extracting_the_consumer_key
51
+ mock(Twurl::CLI).prompt_for('Consumer key').never
52
+
53
+ options = Twurl::CLI.parse_options(['-c', 'the-key'])
54
+ assert_equal 'the-key', options.consumer_key
55
+ end
56
+
57
+ def test_consumer_key_option_with_no_value_prompts_user_for_value
58
+ mock(Twurl::CLI).prompt_for('Consumer key').times(1) { 'inputted-key'}
59
+ options = Twurl::CLI.parse_options(['-c'])
60
+ assert_equal 'inputted-key', options.consumer_key
61
+ end
62
+ end
63
+ include OAuthClientOptionParsingTests
64
+
65
+ module DataParsingTests
66
+ def test_extracting_a_single_key_value_pair
67
+ options = Twurl::CLI.parse_options(['-d', 'key=value'])
68
+ assert_equal({'key' => 'value'}, options.data)
69
+
70
+ options = Twurl::CLI.parse_options(['--data', 'key=value'])
71
+ assert_equal({'key' => 'value'}, options.data)
72
+ end
73
+
74
+ def test_passing_data_and_no_explicit_request_method_defaults_request_method_to_post
75
+ options = Twurl::CLI.parse_options(['-d', 'key=value'])
76
+ assert_equal 'post', options.request_method
77
+ end
78
+
79
+ def test_passing_data_and_an_explicit_request_method_uses_the_specified_method
80
+ options = Twurl::CLI.parse_options(['-d', 'key=value', '-X', 'DELETE'])
81
+ assert_equal({'key' => 'value'}, options.data)
82
+ assert_equal 'delete', options.request_method
83
+ end
84
+
85
+ def test_multiple_pairs_when_option_is_specified_multiple_times_on_command_line_collects_all
86
+ options = Twurl::CLI.parse_options(['-d', 'key=value', '-d', 'another=pair'])
87
+ assert_equal({'key' => 'value', 'another' => 'pair'}, options.data)
88
+ end
89
+
90
+ def test_multiple_pairs_separated_by_ampersand_are_all_captured
91
+ options = Twurl::CLI.parse_options(['-d', 'key=value&another=pair'])
92
+ assert_equal({'key' => 'value', 'another' => 'pair'}, options.data)
93
+ end
94
+ end
95
+ include DataParsingTests
96
+
97
+ module SSLDisablingTests
98
+ def test_ssl_is_on_by_default
99
+ options = Twurl::CLI.parse_options([])
100
+ assert options.ssl?
101
+ end
102
+
103
+ def test_passing_no_ssl_option_disables_ssl
104
+ ['-U', '--no-ssl'].each do |switch|
105
+ options = Twurl::CLI.parse_options([switch])
106
+ assert !options.ssl?
107
+ end
108
+ end
109
+ end
110
+ include SSLDisablingTests
111
+
112
+ module HostOptionTests
113
+ def test_not_specifying_host_sets_it_to_the_default
114
+ options = Twurl::CLI.parse_options([])
115
+ assert_equal Twurl::Options::DEFAULT_HOST, options.host
116
+ end
117
+
118
+ def test_setting_host_updates_to_requested_value
119
+ custom_host = 'localhost:3000'
120
+ assert_not_equal Twurl::Options::DEFAULT_HOST, custom_host
121
+
122
+ [['-H', custom_host], ['--host', custom_host]].each do |option_combination|
123
+ options = Twurl::CLI.parse_options(option_combination)
124
+ assert_equal custom_host, options.host
125
+ end
126
+ end
127
+ end
128
+ include HostOptionTests
129
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Twurl::ConfigurationController::DispatchTest < Test::Unit::TestCase
4
+ def test_error_message_is_displayed_if_setting_is_unrecognized
5
+ options = Twurl::Options.test_exemplar
6
+ client = Twurl::OAuthClient.test_exemplar
7
+
8
+ options.subcommands = ['unrecognized', 'value']
9
+
10
+ mock(Twurl::CLI).puts(Twurl::ConfigurationController::UNRECOGNIZED_SETTING_MESSAGE % 'unrecognized').times(1)
11
+ mock(Twurl::OAuthClient.rcfile).save.times(0)
12
+
13
+ controller = Twurl::ConfigurationController.new(client, options)
14
+ controller.dispatch
15
+ end
16
+ end
17
+
18
+ class Twurl::ConfigurationController::DispatchDefaultSettingTest < Test::Unit::TestCase
19
+ def test_setting_default_profile_just_by_username
20
+ options = Twurl::Options.test_exemplar
21
+ client = Twurl::OAuthClient.test_exemplar
22
+
23
+ options.subcommands = ['default', client.username]
24
+ mock(Twurl::OAuthClient).load_client_for_username(client.username).times(1) { client }
25
+ mock(Twurl::OAuthClient.rcfile).default_profile = client
26
+ mock(Twurl::OAuthClient.rcfile).save.times(1)
27
+
28
+ controller = Twurl::ConfigurationController.new(client, options)
29
+ controller.dispatch
30
+ end
31
+
32
+ def test_setting_default_profile_by_username_and_consumer_key
33
+ options = Twurl::Options.test_exemplar
34
+ client = Twurl::OAuthClient.test_exemplar
35
+
36
+ options.subcommands = ['default', client.username, client.consumer_key]
37
+ mock(Twurl::OAuthClient).load_client_for_username_and_consumer_key(client.username, client.consumer_key).times(1) { client }
38
+ mock(Twurl::OAuthClient.rcfile).default_profile = client
39
+ mock(Twurl::OAuthClient.rcfile).save.times(1)
40
+
41
+ controller = Twurl::ConfigurationController.new(client, options)
42
+ controller.dispatch
43
+ end
44
+ end
@@ -0,0 +1,162 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Twurl::OAuthClient::AbstractOAuthClientTest < Test::Unit::TestCase
4
+ attr_reader :client, :options
5
+ def setup
6
+ Twurl::OAuthClient.instance_variable_set(:@rcfile, nil)
7
+
8
+ @options = Twurl::Options.test_exemplar
9
+ @client = Twurl::OAuthClient.test_exemplar
10
+ options.base_url = 'api.twitter.com'
11
+ options.request_method = 'get'
12
+ options.path = '/path/does/not/matter.xml'
13
+ options.data = {}
14
+
15
+ Twurl.options = options
16
+ end
17
+
18
+ def teardown
19
+ super
20
+ Twurl.options = Twurl::Options.new
21
+ # Make sure we don't do any disk IO in these tests
22
+ assert !File.exists?(Twurl::RCFile.file_path)
23
+ end
24
+
25
+ def test_nothing
26
+ # Appeasing test/unit
27
+ end
28
+ end
29
+
30
+ class Twurl::OAuthClient::BasicRCFileLoadingTest < Twurl::OAuthClient::AbstractOAuthClientTest
31
+ def test_rcfile_is_memoized
32
+ mock.proxy(Twurl::RCFile).new.times(1)
33
+
34
+ Twurl::OAuthClient.rcfile
35
+ Twurl::OAuthClient.rcfile
36
+ end
37
+
38
+ def test_forced_reloading
39
+ mock.proxy(Twurl::RCFile).new.times(2)
40
+
41
+ Twurl::OAuthClient.rcfile
42
+ Twurl::OAuthClient.rcfile(:reload)
43
+ Twurl::OAuthClient.rcfile
44
+ end
45
+ end
46
+
47
+ class Twurl::OAuthClient::ClientLoadingFromOptionsTest < Twurl::OAuthClient::AbstractOAuthClientTest
48
+ def test_if_username_is_supplied_and_no_profile_exists_for_username_then_new_client_is_created
49
+ mock(Twurl::OAuthClient).load_client_for_username(options.username).never
50
+ mock(Twurl::OAuthClient).load_new_client_from_options(options).times(1)
51
+ mock(Twurl::OAuthClient).load_default_client.never
52
+
53
+ Twurl::OAuthClient.load_from_options(options)
54
+ end
55
+
56
+ def test_if_username_is_supplied_and_profile_exists_for_username_then_client_is_loaded
57
+ mock(Twurl::OAuthClient.rcfile).save.times(1)
58
+ Twurl::OAuthClient.rcfile << client
59
+
60
+ mock(Twurl::OAuthClient).load_client_for_username_and_consumer_key(options.username, options.consumer_key).times(1)
61
+ mock(Twurl::OAuthClient).load_new_client_from_options(options).never
62
+ mock(Twurl::OAuthClient).load_default_client.never
63
+
64
+ Twurl::OAuthClient.load_from_options(options)
65
+ end
66
+
67
+ def test_if_username_is_not_provided_then_the_default_client_is_loaded
68
+ options.username = nil
69
+
70
+ mock(Twurl::OAuthClient).load_client_for_username(options.username).never
71
+ mock(Twurl::OAuthClient).load_new_client_from_options(options).never
72
+ mock(Twurl::OAuthClient).load_default_client.times(1)
73
+
74
+ Twurl::OAuthClient.load_from_options(options)
75
+ end
76
+ end
77
+
78
+ class Twurl::OAuthClient::ClientLoadingForUsernameTest < Twurl::OAuthClient::AbstractOAuthClientTest
79
+ def test_attempting_to_load_a_username_that_is_not_in_the_file_fails
80
+ assert_nil Twurl::OAuthClient.rcfile[client.username]
81
+
82
+ assert_raises Twurl::Exception do
83
+ Twurl::OAuthClient.load_client_for_username_and_consumer_key(client.username, client.consumer_key)
84
+ end
85
+ end
86
+
87
+ def test_loading_a_username_that_exists
88
+ mock(Twurl::OAuthClient.rcfile).save.times(1)
89
+
90
+ Twurl::OAuthClient.rcfile << client
91
+
92
+ client_from_file = Twurl::OAuthClient.load_client_for_username_and_consumer_key(client.username, client.consumer_key)
93
+ assert_equal client.to_hash, client_from_file.to_hash
94
+ end
95
+ end
96
+
97
+ class Twurl::OAuthClient::DefaultClientLoadingTest < Twurl::OAuthClient::AbstractOAuthClientTest
98
+ def test_loading_default_client_when_there_is_none_fails
99
+ assert_nil Twurl::OAuthClient.rcfile.default_profile
100
+
101
+ assert_raises Twurl::Exception do
102
+ Twurl::OAuthClient.load_default_client
103
+ end
104
+ end
105
+
106
+ def test_loading_default_client_from_file
107
+ mock(Twurl::OAuthClient.rcfile).save.times(1)
108
+
109
+ Twurl::OAuthClient.rcfile << client
110
+ assert_equal [client.username, client.consumer_key], Twurl::OAuthClient.rcfile.default_profile
111
+
112
+ client_from_file = Twurl::OAuthClient.load_default_client
113
+
114
+ assert_equal client.to_hash, client_from_file.to_hash
115
+ end
116
+ end
117
+
118
+ class Twurl::OAuthClient::NewClientLoadingFromOptionsTest < Twurl::OAuthClient::AbstractOAuthClientTest
119
+ attr_reader :new_client
120
+ def setup
121
+ super
122
+ @new_client = Twurl::OAuthClient.load_new_client_from_options(options)
123
+ end
124
+
125
+ def test_password_is_included
126
+ assert_equal options.password, new_client.password
127
+ end
128
+
129
+ def test_oauth_options_are_passed_through
130
+ assert_equal client.to_hash, new_client.to_hash
131
+ end
132
+ end
133
+
134
+ class Twurl::OAuthClient::PerformingRequestsFromOptionsTest < Twurl::OAuthClient::AbstractOAuthClientTest
135
+ def test_request_is_made_using_request_method_and_path_and_data_in_options
136
+ client = Twurl::OAuthClient.test_exemplar
137
+ mock(client).get(options.path, options.data)
138
+
139
+ client.perform_request_from_options(options)
140
+ end
141
+ end
142
+
143
+ class Twurl::OAuthClient::CredentialsForAccessTokenExchangeTest < Twurl::OAuthClient::AbstractOAuthClientTest
144
+ def test_successful_exchange_parses_token_and_secret_from_response_body
145
+ parsed_response = {:oauth_token => "123456789",
146
+ :oauth_token_secret => "abcdefghi",
147
+ :user_id => "3191321",
148
+ :screen_name => "noradio",
149
+ :x_auth_expires => "0"}
150
+
151
+ mock(client.consumer).
152
+ token_request(:post,
153
+ client.consumer.access_token_path,
154
+ nil,
155
+ {},
156
+ client.client_auth_parameters) { parsed_response }
157
+
158
+ assert client.needs_to_authorize?
159
+ client.exchange_credentials_for_access_token
160
+ assert !client.needs_to_authorize?
161
+ end
162
+ end
@@ -0,0 +1,141 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Twurl::RCFile::PathConstructionTest < Test::Unit::TestCase
4
+ def test_file_path_appends_file_to_directory
5
+ assert_equal File.join(Twurl::RCFile.directory, Twurl::RCFile::FILE), Twurl::RCFile.file_path
6
+ end
7
+ end
8
+
9
+ class Twurl::RCFile::LoadingTest < Test::Unit::TestCase
10
+ def test_load_parses_and_loads_file_if_it_exists
11
+ mock(YAML).load_file(Twurl::RCFile.file_path).times(1)
12
+ mock(Twurl::RCFile).default_rcfile_structure.never
13
+
14
+ Twurl::RCFile.load
15
+ end
16
+
17
+ def test_load_returns_default_file_structure_if_file_does_not_exist
18
+ mock(YAML).load_file(Twurl::RCFile.file_path) { raise Errno::ENOENT }.times(1)
19
+ mock(Twurl::RCFile).default_rcfile_structure.times(1)
20
+
21
+ Twurl::RCFile.load
22
+ end
23
+ end
24
+
25
+ class Twurl::RCFile::InitializationTest < Test::Unit::TestCase
26
+ def test_initializing_when_the_file_does_not_exist_loads_default_rcfile_structure
27
+ mock(YAML).load_file(Twurl::RCFile.file_path) { raise Errno::ENOENT }.times(1)
28
+
29
+ rcfile = Twurl::RCFile.new
30
+ assert_equal Twurl::RCFile.default_rcfile_structure, rcfile.data
31
+ end
32
+
33
+ def test_initializing_when_the_file_does_exists_loads_content_of_file
34
+ mock_content_of_rcfile = {'this data' => 'does not matter'}
35
+ mock(YAML).load_file(Twurl::RCFile.file_path) { mock_content_of_rcfile }.times(1)
36
+ mock(Twurl::RCFile).default_rcfile_structure.never
37
+
38
+ rcfile = Twurl::RCFile.new
39
+ assert_equal mock_content_of_rcfile, rcfile.data
40
+ end
41
+ end
42
+
43
+ class Twurl::RCFile::DefaultProfileFromDefaultRCFileTest < Test::Unit::TestCase
44
+ attr_reader :rcfile
45
+ def setup
46
+ mock(YAML).load_file(Twurl::RCFile.file_path) { raise Errno::ENOENT }.times(1)
47
+ mock.proxy(Twurl::RCFile).default_rcfile_structure.times(any_times)
48
+
49
+ @rcfile = Twurl::RCFile.new
50
+ end
51
+
52
+ def test_default_rcfile_structure_has_no_default_profile
53
+ assert_nil rcfile.default_profile
54
+ end
55
+
56
+ def test_rcfile_is_considered_empty_at_first
57
+ assert rcfile.empty?
58
+ end
59
+
60
+ def test_setting_default_profile
61
+ options = Twurl::Options.test_exemplar
62
+
63
+ client = Twurl::OAuthClient.load_new_client_from_options(options)
64
+ rcfile.default_profile = client
65
+ assert_equal [options.username, options.consumer_key], rcfile.default_profile
66
+ end
67
+ end
68
+
69
+ class Twurl::RCFile::UpdatingTest < Test::Unit::TestCase
70
+ attr_reader :rcfile
71
+ def setup
72
+ mock(YAML).load_file(Twurl::RCFile.file_path) { raise Errno::ENOENT }.times(1)
73
+
74
+ @rcfile = Twurl::RCFile.new
75
+ assert rcfile.profiles.empty?
76
+ assert_nil rcfile.default_profile
77
+ mock(rcfile).save.times(any_times)
78
+ end
79
+
80
+ def test_adding_the_first_client_sets_it_as_default_profile
81
+ client = Twurl::OAuthClient.test_exemplar
82
+
83
+ rcfile << client
84
+ assert_equal [client.username, client.consumer_key], rcfile.default_profile
85
+ assert rcfile.has_oauth_profile_for_username_with_consumer_key?(client.username, client.consumer_key)
86
+ assert_equal({client.username => {client.consumer_key => client.to_hash}}, rcfile.profiles)
87
+ end
88
+
89
+ def test_adding_additional_clients_does_not_change_default_profile
90
+ first_client = Twurl::OAuthClient.test_exemplar
91
+
92
+ rcfile << first_client
93
+ assert_equal [first_client.username, first_client.consumer_key], rcfile.default_profile
94
+ assert rcfile.has_oauth_profile_for_username_with_consumer_key?(first_client.username, first_client.consumer_key)
95
+
96
+ additional_client = Twurl::OAuthClient.test_exemplar(:username => 'additional_exemplar_username')
97
+
98
+ rcfile << additional_client
99
+ assert_equal [first_client.username, first_client.consumer_key], rcfile.default_profile
100
+ assert rcfile.has_oauth_profile_for_username_with_consumer_key?(additional_client.username, additional_client.consumer_key)
101
+
102
+ expected_profiles = {
103
+ first_client.username => {first_client.consumer_key => first_client.to_hash},
104
+ additional_client.username => {additional_client.consumer_key => additional_client.to_hash}
105
+ }
106
+
107
+ assert_equal expected_profiles, rcfile.profiles
108
+ end
109
+ end
110
+
111
+ class Twurl::RCFile::SavingTest < Test::Unit::TestCase
112
+ attr_reader :rcfile
113
+ def setup
114
+ delete_rcfile
115
+ assert !rcfile_exists?
116
+ @rcfile = Twurl::RCFile.new
117
+ assert !rcfile_exists?
118
+ end
119
+
120
+ def teardown
121
+ super
122
+ delete_rcfile
123
+ end
124
+
125
+ def test_save_writes_profiles_to_disk
126
+ client = Twurl::OAuthClient.test_exemplar
127
+ rcfile << client
128
+ assert rcfile_exists?
129
+ end
130
+
131
+ private
132
+ def rcfile_exists?
133
+ File.exists?(Twurl::RCFile.file_path)
134
+ end
135
+
136
+ def delete_rcfile
137
+ File.unlink(Twurl::RCFile.file_path)
138
+ rescue Errno::ENOENT
139
+ # Do nothing
140
+ end
141
+ end