impostor 0.2.1 → 1.0.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.
Files changed (108) hide show
  1. data/.gemtest +0 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +47 -0
  7. data/History.txt +8 -0
  8. data/Manifest.txt +87 -55
  9. data/README.txt +11 -11
  10. data/Rakefile +16 -20
  11. data/lib/impostor/auth.rb +103 -0
  12. data/lib/impostor/config.rb +171 -0
  13. data/lib/impostor/errors.rb +67 -0
  14. data/lib/impostor/phpbb2.rb +202 -0
  15. data/lib/impostor/phpbb3.rb +199 -0
  16. data/lib/impostor/post.rb +111 -0
  17. data/lib/impostor/topic.rb +115 -0
  18. data/lib/impostor/wwf79.rb +186 -0
  19. data/lib/impostor/wwf80.rb +190 -0
  20. data/lib/impostor.rb +108 -5
  21. data/spec/auth_spec.rb +148 -0
  22. data/spec/base_spec_helper.rb +12 -0
  23. data/{test/test_helper.rb → spec/caged_net_http.rb} +8 -17
  24. data/spec/config_spec.rb +136 -0
  25. data/spec/fixtures/junk.html +1 -0
  26. data/{test → spec}/fixtures/phpbb2-get-new_topic-form-good-response.html +0 -0
  27. data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-good-response.html +11 -11
  28. data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-malformed-response.html +0 -0
  29. data/{test → spec}/fixtures/phpbb2-index.html +0 -0
  30. data/{test → spec}/fixtures/phpbb2-logged-in.html +0 -0
  31. data/{test → spec}/fixtures/phpbb2-login.html +0 -0
  32. data/{test → spec}/fixtures/phpbb2-not-logged-in.html +0 -0
  33. data/{test → spec}/fixtures/phpbb2-post-new_topic-good-response.html +0 -0
  34. data/{test → spec}/fixtures/phpbb2-post-reply-good-response.html +0 -0
  35. data/{test → spec}/fixtures/phpbb2-post-reply-throttled-response.html +0 -0
  36. data/{test → spec}/fixtures/phpbb2-too-many-posts.html +0 -0
  37. data/{test → spec}/fixtures/phpbb3-get-new-topic-form-good-response.html +0 -0
  38. data/{test → spec}/fixtures/phpbb3-get-reply-form-good-response.html +0 -0
  39. data/{test → spec}/fixtures/phpbb3-logged-in.html +0 -0
  40. data/{test → spec}/fixtures/phpbb3-login.html +0 -0
  41. data/{test → spec}/fixtures/phpbb3-not-logged-in.html +0 -0
  42. data/{test → spec}/fixtures/phpbb3-post-new_topic-good-response.html +0 -0
  43. data/{test → spec}/fixtures/phpbb3-post-reply-good-response.html +0 -0
  44. data/spec/fixtures/vcr_cassettes/phpbb2-should-be-overlimit-creating-topic.yml +1308 -0
  45. data/spec/fixtures/vcr_cassettes/phpbb2-should-create-topic.yml +923 -0
  46. data/spec/fixtures/vcr_cassettes/phpbb2-should-login.yml +360 -0
  47. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-create-new-topic.yml +497 -0
  48. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-login.yml +287 -0
  49. data/spec/fixtures/vcr_cassettes/phpbb2-should-not-post.yml +497 -0
  50. data/spec/fixtures/vcr_cassettes/phpbb2-should-overlimit-error-post.yml +1140 -0
  51. data/spec/fixtures/vcr_cassettes/phpbb2-should-post.yml +751 -0
  52. data/spec/fixtures/vcr_cassettes/phpbb3-should-be-overlimit-creating-topic.yml +995 -0
  53. data/spec/fixtures/vcr_cassettes/phpbb3-should-create-topic.yml +675 -0
  54. data/spec/fixtures/vcr_cassettes/phpbb3-should-login.yml +245 -0
  55. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-create-new-topic.yml +350 -0
  56. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-login.yml +253 -0
  57. data/spec/fixtures/vcr_cassettes/phpbb3-should-not-post.yml +350 -0
  58. data/spec/fixtures/vcr_cassettes/phpbb3-should-overlimit-error-post.yml +1046 -0
  59. data/spec/fixtures/vcr_cassettes/phpbb3-should-post.yml +605 -0
  60. data/{test → spec}/fixtures/wwf79-forum_posts.html +0 -0
  61. data/{test → spec}/fixtures/wwf79-general-new-topic-error.html +0 -0
  62. data/{test → spec}/fixtures/wwf79-general-posting-error.html +0 -0
  63. data/{test → spec}/fixtures/wwf79-good-post-forum_posts.html +1 -1
  64. data/{test → spec}/fixtures/wwf79-index.html +0 -0
  65. data/{test → spec}/fixtures/wwf79-logged-in.html +0 -0
  66. data/{test → spec}/fixtures/wwf79-login.html +0 -0
  67. data/{test → spec}/fixtures/wwf79-new-topic-forum_posts-response.html +0 -0
  68. data/{test → spec}/fixtures/wwf79-new-topic-post_message_form.html +0 -0
  69. data/{test → spec}/fixtures/wwf79-not-logged-in.html +0 -0
  70. data/{test → spec}/fixtures/wwf79-too-many-posts.html +0 -0
  71. data/{test → spec}/fixtures/wwf79-too-many-topics.html +0 -0
  72. data/{test → spec}/fixtures/wwf80-general-posting-error.html +0 -0
  73. data/{test → spec}/fixtures/wwf80-get-new_topic-form-good-response.html +0 -0
  74. data/{test → spec}/fixtures/wwf80-get-viewtopic-for-new-topic-good-response.html +0 -0
  75. data/{test → spec}/fixtures/wwf80-index.html +0 -0
  76. data/{test → spec}/fixtures/wwf80-logged-in.html +0 -0
  77. data/{test → spec}/fixtures/wwf80-login.html +0 -0
  78. data/{test → spec}/fixtures/wwf80-new_reply_form.html +0 -0
  79. data/{test → spec}/fixtures/wwf80-not-logged-in.html +0 -0
  80. data/{test → spec}/fixtures/wwf80-post-new_topic-good-response.html +1 -1
  81. data/{test → spec}/fixtures/wwf80-post-reply-good-response.html +0 -0
  82. data/{test → spec}/fixtures/wwf80-too-many-posts.html +0 -0
  83. data/spec/impostor_spec_helper.rb +162 -0
  84. data/spec/integration/phpbb2_spec.rb +111 -0
  85. data/spec/integration/phpbb3_spec.rb +109 -0
  86. data/spec/integration_spec_helper.rb +7 -0
  87. data/spec/phpbb2_spec.rb +346 -0
  88. data/spec/phpbb3_spec.rb +332 -0
  89. data/spec/post_spec.rb +134 -0
  90. data/spec/spec_helper.rb +2 -0
  91. data/spec/test_impostor.rb +12 -0
  92. data/spec/topic_spec.rb +143 -0
  93. data/spec/wwf79_spec.rb +342 -0
  94. data/spec/wwf80_spec.rb +339 -0
  95. metadata +156 -87
  96. data/lib/www/impostor/phpbb2.rb +0 -258
  97. data/lib/www/impostor/phpbb3.rb +0 -236
  98. data/lib/www/impostor/wwf79.rb +0 -254
  99. data/lib/www/impostor/wwf80.rb +0 -264
  100. data/lib/www/impostor.rb +0 -269
  101. data/test/test_github.rb +0 -12
  102. data/test/test_www_impostor.rb +0 -165
  103. data/test/test_www_impostor_phpbb2.rb +0 -536
  104. data/test/test_www_impostor_phpbb3.rb +0 -483
  105. data/test/test_www_impostor_wwf79.rb +0 -535
  106. data/test/test_www_impostor_wwf80.rb +0 -535
  107. data/vendor/plugins/impostor/lib/autotest/discover.rb +0 -3
  108. data/vendor/plugins/impostor/lib/autotest/impostor.rb +0 -49
@@ -0,0 +1,186 @@
1
+ ##
2
+ # Web Wiz Forums version 7.9 of the Impostor
3
+ #
4
+
5
+ class Impostor
6
+
7
+ module Wwf79
8
+
9
+ ##
10
+ # Additional configuration parameters for a Wwf79 compatible agent:
11
+ #
12
+ # :forum_posts_page
13
+ # :post_message_page
14
+ #
15
+ # Typical configuration parameters
16
+ # { :type => :wwf79,
17
+ # :app_root => 'http://example.com/forum/',
18
+ # :login_page => 'login_user.asp',
19
+ # :forum_posts_page => 'forum_posts.asp',
20
+ # :post_message_page => 'post_message_form.asp'
21
+ # :user_agent => 'Windows IE 7',
22
+ # :username => 'myuser',
23
+ # :password => 'mypasswd' }
24
+
25
+ module Auth
26
+
27
+ def login # :nodoc:
28
+ Impostor.not_tested("Impostor::Wwf79::Auth", "login")
29
+ super
30
+ end
31
+
32
+ ##
33
+ # Checks if the agent is already logged by stored cookie
34
+
35
+ def logged_in?(page)
36
+ mm = page.search("//a[@class='nav']")
37
+ !! mm.detect { |m| m.text =~ /Logout \[#{self.config.username}\]/ }
38
+ end
39
+
40
+ ##
41
+ # returns the login form from the login page
42
+
43
+ def get_login_form(page)
44
+ form = page.form('frmLogin')
45
+ raise Impostor::LoginError.new("unknown login page format") unless form
46
+ form
47
+ end
48
+
49
+ ##
50
+ # Sets the user name and pass word on the loing form.
51
+ def set_username_and_password(form)
52
+ button = Mechanize::Form::Button.new('Submit', 'Forum Login')
53
+ form.add_button_to_query(button)
54
+ form['name'] = self.config.username
55
+ form['password'] = self.config.password
56
+ form
57
+ end
58
+
59
+ end
60
+
61
+ module Post
62
+
63
+ def post(forum, topic, message) # :nodoc:
64
+ Impostor.not_tested("Impostor::Wwf79::Post", "post")
65
+ super
66
+ end
67
+
68
+ ##
69
+ # return a uri used to fetch the reply page based on the forum, topic, and
70
+ # message
71
+
72
+ def get_reply_uri(forum, topic)
73
+ uri = URI.join(self.config.app_root, self.config.config(:forum_posts_page))
74
+ uri.query = "TID=#{topic}&TPN=10000"
75
+ uri
76
+ end
77
+
78
+ ##
79
+ # return the form used for posting a message from the reply page
80
+
81
+ def get_post_form(page)
82
+ form = page.form('frmAddMessage')
83
+ raise Impostor::PostError.new("unknown reply page format") unless form
84
+ form
85
+ end
86
+
87
+ ##
88
+ # get post id from the result of posting the message form
89
+ # FIXME this validation is copied into topic module as well
90
+
91
+ def get_post_from_result(page)
92
+ error = page.body =~ /Message Not Posted/
93
+ if error
94
+
95
+ # throttled
96
+ throttled = "You have exceeded the number of posts permitted in the time span"
97
+ too_many = page.body =~ /#{throttled}/
98
+ raise Impostor::ThrottledError.new(throttled) if too_many
99
+
100
+ # general error
101
+ raise Impostor::PostError.new("There was an error making the post")
102
+ end
103
+
104
+ kv = page.links.collect{ |l| l.uri }.compact.
105
+ collect{ |l| l.query }.compact.
106
+ collect{ |q| q.split('&')}.flatten.
107
+ detect{|kv| kv =~ /^PID=/ }
108
+ postid = URI.unescape(kv).split('#').first.split('=').last.to_i
109
+ raise Impostor::PostError.new("Message did not post.") if postid.zero?
110
+ postid
111
+ end
112
+
113
+ end
114
+
115
+ module Topic
116
+
117
+ def new_topic(forum, subject, message) # :nodoc:
118
+ Impostor.not_tested("Impostor::Wwf79::Topic", "new_topic")
119
+ super
120
+ end
121
+
122
+ ##
123
+ # return a uri used to fetch the new topic page based on the forum, subject,
124
+ # and message
125
+
126
+ def get_new_topic_uri(forum, subject, message)
127
+ uri = URI.join(self.config.app_root, self.config.config(:post_message_page))
128
+ uri.query = "FID=#{forum}"
129
+ uri
130
+ end
131
+
132
+ ##
133
+ # Get the the new topic form on the page
134
+
135
+ def get_new_topic_form(page)
136
+ form = page.form('frmAddMessage')
137
+ raise Impostor::TopicError.new("unknown new topic page format") unless form
138
+ form
139
+ end
140
+
141
+ ##
142
+ # Set the subject and message on the new topic form
143
+
144
+ def set_subject_and_message(form, subject, message)
145
+ form.subject = subject
146
+ form.message = message
147
+ form
148
+ end
149
+
150
+ ##
151
+ # validate the result of posting the message form
152
+ # FIXME this validation is copied into post module as well
153
+
154
+ def validate_new_topic_result(page)
155
+ error = page.body =~ /Message Not Posted/
156
+ if error
157
+
158
+ # throttled
159
+ throttled = "You have exceeded the number of posts permitted in the time span"
160
+ too_many = page.body =~ /#{throttled}/
161
+ raise Impostor::ThrottledError.new(throttled) if too_many
162
+
163
+ # general error
164
+ raise Impostor::TopicError.new("There was an error making the post")
165
+ end
166
+
167
+ page
168
+ end
169
+
170
+ ##
171
+ # Get the new topic identifier from the result page
172
+
173
+ def get_topic_from_result(page)
174
+ begin
175
+ tid = page.form('frmAddMessage')['TID'].to_i
176
+ raise StandardError.new("new topic id not found") if tid.zero?
177
+ tid
178
+ rescue StandardError => err
179
+ raise Impostor::TopicError.new(err)
180
+ end
181
+ end
182
+
183
+ end
184
+
185
+ end
186
+ end
@@ -0,0 +1,190 @@
1
+ ##
2
+ # Web Wiz Forums version 8.0 of the Impostor
3
+ #
4
+
5
+ class Impostor
6
+
7
+ module Wwf80
8
+
9
+ ##
10
+ # Additional configuration parameters for a Wwf80 compatible agent:
11
+ #
12
+ # :new_reply_page
13
+ # :new_topic_page
14
+ #
15
+ # Typical configuration parameters
16
+ # { :type => :wwf80,
17
+ # :app_root => 'http://example.com/forum/',
18
+ # :login_page => 'login_user.asp',
19
+ # :new_reply_page => 'new_reply_form.asp',
20
+ # :new_topic_page => 'new_topic_form.asp',
21
+ # :user_agent => 'Windows IE 7',
22
+ # :username => 'myuser',
23
+ # :password => 'mypasswd' }
24
+
25
+ module Auth
26
+
27
+ def login # :nodoc:
28
+ Impostor.not_tested("Impostor::Wwf80::Auth", "login")
29
+ super
30
+ end
31
+
32
+ ##
33
+ # returns the login form from the login page
34
+
35
+ def get_login_form(page)
36
+ form = page.form('frmLogin')
37
+ raise Impostor::LoginError.new("unknown login page format") unless form
38
+ form
39
+ end
40
+
41
+ ##
42
+ # Sets the user name and pass word on the loing form.
43
+ def set_username_and_password(form)
44
+ form['name'] = self.config.username
45
+ form['password'] = self.config.password
46
+ form
47
+ end
48
+
49
+ ##
50
+ # given the state of the page, are we logged in to the forum?
51
+
52
+ def logged_in?(page)
53
+ mm = page.search("//a[@class='nav']")
54
+ !! mm.detect { |m| m.text =~ /Logout \[#{self.config.username}\]/ }
55
+ end
56
+
57
+ end
58
+
59
+ module Post
60
+
61
+ def post(forum, topic, message) # :nodoc:
62
+ Impostor.not_tested("Impostor::Wwf80::Post", "post")
63
+ super
64
+ end
65
+
66
+ ##
67
+ # return a uri used to fetch the reply page based on the forum, topic, and
68
+ # message
69
+
70
+ def get_reply_uri(forum, topic)
71
+ uri = URI.join(self.config.app_root, self.config.config(:new_reply_page))
72
+ uri.query = "TID=#{topic}"
73
+ uri
74
+ end
75
+
76
+ ##
77
+ # return the form used for posting a message from the reply page
78
+
79
+ def get_post_form(page)
80
+ form = page.form('frmMessageForm')
81
+ raise Impostor::PostError.new("unknown reply page format") unless form
82
+ form
83
+ end
84
+
85
+ ##
86
+ # get post id from the result of posting the message form
87
+ # FIXME this validation is copied into topic module as well
88
+
89
+ def get_post_from_result(page)
90
+ error = page.search("//table[@class='errorTable']")
91
+ if error
92
+ msgs = error.search("//td")
93
+
94
+ # throttled
95
+ too_many = msgs.last && msgs.last.text && msgs.last.text =~ /You have exceeded the number of posts permitted in the time span/
96
+ raise ThrottledError.new(msgs.last.text.gsub(/\s+/m,' ').strip) if too_many
97
+
98
+ # general error
99
+ had_error = error.last && error.last.text && error.last.text =~ /Error: Message Not Posted/
100
+ raise Impostor::PostError.new(error.last.text.gsub(/\s+/m,' ').strip) if had_error
101
+ end
102
+
103
+ kv = page.links.collect{ |l| l.uri }.compact.
104
+ collect{ |l| l.query }.compact.
105
+ collect{ |q| q.split('&')}.flatten.
106
+ detect{|kv| kv =~ /^PID=/ }
107
+ postid = URI.unescape(kv).split('#').first.split('=').last.to_i
108
+ raise Impostor::PostError.new("Message did not post.") if postid.zero?
109
+ postid
110
+ end
111
+
112
+ end
113
+
114
+ module Topic
115
+
116
+ def new_topic(forum, subject, message) # :nodoc:
117
+ Impostor.not_tested("Impostor::Wwf80::Topic", "new_topic")
118
+ super
119
+ end
120
+
121
+ ##
122
+ # return a uri used to fetch the new topic page based on the forum, subject,
123
+ # and message
124
+
125
+ def get_new_topic_uri(forum, subject, message)
126
+ uri = URI.join(self.config.app_root, self.config.config(:new_topic_page))
127
+ uri.query = "FID=#{forum}"
128
+ uri
129
+ end
130
+
131
+ ##
132
+ # Get the the new topic form on the page
133
+
134
+ def get_new_topic_form(page)
135
+ form = page.form('frmMessageForm')
136
+ raise Impostor::TopicError.new("unknown new topic page format") unless form
137
+ form
138
+ end
139
+
140
+ ##
141
+ # Set the subject and message on the new topic form
142
+
143
+ def set_subject_and_message(form, subject, message)
144
+ form.subject = subject
145
+ form.message = message
146
+ form
147
+ end
148
+
149
+ ##
150
+ # Validate the result of posting the new topic
151
+ # FIXME this validation is copied into post module as well
152
+
153
+ def validate_new_topic_result(page)
154
+ error = page.search("//table[@class='errorTable']")
155
+ if error
156
+ msgs = error.search("//td")
157
+
158
+ # throttled
159
+ too_many = (msgs.last.text =~
160
+ /You have exceeded the number of posts permitted in the time span/ rescue
161
+ false)
162
+ raise ThrottledError.new(msgs.last.text.gsub(/\s+/m,' ').strip) if too_many
163
+
164
+ # general error
165
+ had_error = (error.last.text =~
166
+ /Error: Message Not Posted/ rescue
167
+ false)
168
+ raise TopicError.new(error.last.text.gsub(/\s+/m,' ').strip) if had_error
169
+ end
170
+
171
+ page
172
+ end
173
+
174
+ ##
175
+ # Get the new topic identifier from the result page
176
+
177
+ def get_topic_from_result(page)
178
+ begin
179
+ tid = page.form('frmMessageForm')['TID'].to_i
180
+ raise StandardError.new("new topic id not found") if tid.zero?
181
+ tid
182
+ rescue StandardError => err
183
+ raise Impostor::TopicError.new(err)
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+ end
data/lib/impostor.rb CHANGED
@@ -1,6 +1,109 @@
1
- # Copyright (c) 2008 by Mike Mondragon (mikemondragon@gmail.com)
2
- #
3
- # Please see the LICENSE file for licensing.
4
- #
1
+ %W{ mechanize nokogiri cgi }.each do |g|
2
+ begin
3
+ require g
4
+ rescue LoadError
5
+ require 'rubygems'
6
+ require g
7
+ end
8
+ end
9
+ require 'logger'
5
10
 
6
- require 'www/impostor'
11
+ Dir.glob(File.join(File.dirname(__FILE__), 'impostor/**/*.rb')).each {|f| require f }
12
+
13
+ class Impostor
14
+
15
+ ##
16
+ # imPOSTor posts messages to non-RESTful forums and blogs
17
+ #
18
+ # == Example
19
+ # require 'rubygems'
20
+ # require 'impostor'
21
+ #
22
+ # # config yaml has options specefic to wwf79, wwf80, phpbb2, etc.
23
+ # # read the impostor docs for options to the kind of forum in use
24
+ # # config can be keyed by symbols or strings
25
+ # post = Impostor.new(YAML.load_file('config.yml'))
26
+ # message = %q!hello world is to application
27
+ # programmers as tea pots are to graphics programmers!
28
+ # # your application store forum and topic ids
29
+ # post.post(forum=5,topic=10,message)
30
+ # # make a new topic
31
+ # subject = "about programmers..."
32
+ # post.new_topic(forum=7,subject,message)
33
+ #
34
+ # keys and values that can be set in the impostor configuration
35
+ #
36
+ # :type - kind of imPOSTor, :phpbb2, :wwf79, :wwf80, etc.
37
+ # :username - forum username
38
+ # :password - forum password
39
+ # :topics_cache - cache of forum topics
40
+ # :user_agent - Mechanize browser user-agent
41
+ # :cookie_jar - saved cookies from Mechanize browser
42
+ # :app_root - url to forum
43
+ # :login_page - forum login page
44
+ # :logger - A logger object or path ot a logger file.
45
+ # :sleep_before_post - Number of seconds delay before posting to forum
46
+ #
47
+ # See documentation for each type of imPOSTor for additional configuration
48
+ # parameters that are needed for the specific kind of imPOSTor. A sample
49
+ # configuration is provided in the documentation for each.
50
+
51
+
52
+ ##
53
+ # Gem version of Impostor
54
+
55
+ VERSION = '1.0.0'
56
+
57
+ ##
58
+ # Pass in a config hash to initialize
59
+
60
+ def initialize(config={})
61
+ @config = Config.new(config)
62
+ @auth = Auth.new(@config)
63
+ @post = Post.new(@config, @auth)
64
+ @topic = Topic.new(@config, @auth)
65
+
66
+ type = @config.type
67
+ raise ConfigError.new("Missing 'type' key in configuration") unless type
68
+
69
+ extend eval("Impostor::#{type.to_s.capitalize}")
70
+ end
71
+
72
+ ##
73
+ # our version
74
+
75
+ def version
76
+ VERSION
77
+ end
78
+
79
+ ##
80
+ # Post the message
81
+
82
+ def post(forum, topic, message)
83
+ @post.post(forum, topic, message)
84
+ end
85
+
86
+ ##
87
+ # Make a new topic
88
+
89
+ def new_topic(forum, subject, message)
90
+ @topic.new_topic(forum, subject, message)
91
+ end
92
+
93
+ ##
94
+ # Login
95
+
96
+ def login
97
+ @auth.login
98
+ end
99
+
100
+ def self.not_tested(who, what)
101
+ warn <<WARNMSG
102
+ !!!!! IMPLEMENTATION WARNING !!!!!
103
+ #{who}##{what} did not have real integration test data to work against in the
104
+ refactoring of Impostor from version 0.2.1 to 1.0.0. Please contact the author
105
+ to help supply live data allowing real integration tests for this method.
106
+ WARNMSG
107
+ end
108
+
109
+ end
data/spec/auth_spec.rb ADDED
@@ -0,0 +1,148 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "impostor's authorization routines" do
4
+
5
+ describe "the no-op test impostor auth without implemented template methods" do
6
+
7
+ it "should logout only if not logged in" do
8
+ auth = self.auth
9
+ auth.should_receive(:authenticated?).once.and_return(false)
10
+ auth.logout.should_not be_true
11
+ end
12
+
13
+ it "should logout" do
14
+ config = self.config
15
+ auth = self.auth(config)
16
+ config.should_receive(:save_topics).once
17
+ config.should_receive(:save_cookie_jar).once
18
+ auth.instance_variable_set("@authenticated", true)
19
+
20
+ auth.logout.should be_true
21
+ auth.authenticated?.should_not be_true
22
+ end
23
+
24
+ it "should login at the server only if not logged in" do
25
+ auth = self.auth
26
+ auth.should_receive(:authenticated?).once.and_return(true)
27
+ auth.login.should be_true
28
+ end
29
+
30
+ it "should raise login failure when login fails" do
31
+ auth = self.auth
32
+ auth.should_receive(:login).once.and_return(false)
33
+ lambda { auth.login_with_raises }.should raise_error(
34
+ Impostor::LoginError,
35
+ "Impostor error: not logged in (StandardError)"
36
+ )
37
+ end
38
+
39
+ it "should not raise login failure when login fails" do
40
+ auth = self.auth
41
+ auth.should_receive(:login).once.and_return(true)
42
+ lambda { auth.login_with_raises }.should_not raise_error
43
+ end
44
+
45
+ it "should not login when template methods are not implemented" do
46
+ config = self.config
47
+ auth = self.auth(config)
48
+ login_uri = URI.parse("http://example.com/login")
49
+ config.agent.should_receive(:get).with(login_uri)
50
+
51
+ lambda { auth.login }.should raise_error(
52
+ Impostor::MissingTemplateMethodError,
53
+ "Impostor error: logged_in? must be implemented (StandardError)"
54
+ )
55
+ end
56
+
57
+ it "should raise not implemented error when logged_in? called" do
58
+ auth = self.auth
59
+ lambda { auth.logged_in?(nil) }.should raise_error(
60
+ Impostor::MissingTemplateMethodError,
61
+ "Impostor error: logged_in? must be implemented (StandardError)"
62
+ )
63
+ end
64
+
65
+ it "should return a page from fetch_login_page" do
66
+ config = self.config
67
+ auth = self.auth(config)
68
+ login_uri = URI.parse("http://example.com/login")
69
+ config.agent.should_receive(:get).with(login_uri)
70
+
71
+ lambda {
72
+ auth.fetch_login_page
73
+ }.should_not raise_error
74
+ end
75
+
76
+ it "should handle an error in fetch_login_page" do
77
+ config = self.config
78
+ auth = self.auth(config)
79
+ login_uri = URI.parse("http://example.com/login")
80
+ config.agent.should_receive(:get).with(login_uri).and_raise(StandardError)
81
+
82
+ lambda {
83
+ auth.fetch_login_page
84
+ }.should raise_error( Impostor::LoginError )
85
+ end
86
+
87
+ it "should raise not implemented error when get_login_form called" do
88
+ auth = self.auth
89
+ lambda { auth.get_login_form(nil) }.should raise_error(
90
+ Impostor::MissingTemplateMethodError,
91
+ "Impostor error: get_login_form must be implemented (StandardError)"
92
+ )
93
+ end
94
+
95
+ it "should raise not implemented error when set_username_and_password called" do
96
+ auth = self.auth
97
+ lambda { auth.set_username_and_password(nil) }.should raise_error(
98
+ Impostor::MissingTemplateMethodError,
99
+ "Impostor error: set_username_and_password must be implemented (StandardError)"
100
+ )
101
+ end
102
+
103
+ it "should raise not implemented error when post_login called" do
104
+ auth = self.auth
105
+ form = mock "form"
106
+ page = mock "page"
107
+ form.should_receive(:submit).and_return(page)
108
+ lambda { auth.post_login(form).should == page }.should_not raise_error
109
+ end
110
+
111
+ it "should login via composed template methods" do
112
+
113
+ auth = self.auth
114
+
115
+ login_page = mock "page"
116
+ logged_in_page = mock "page"
117
+ form = mock "form"
118
+
119
+ auth.should_receive(:authenticated?).once.and_return(false)
120
+ auth.should_receive(:fetch_login_page).once.and_return(login_page)
121
+ auth.should_receive(:logged_in?).with(login_page).once.and_return(false)
122
+ auth.should_receive(:get_login_form).with(login_page).once.and_return(form)
123
+ auth.should_receive(:set_username_and_password).with(form).once
124
+
125
+ auth.should_receive(:post_login).with(form).once.and_return(logged_in_page)
126
+ auth.should_receive(:logged_in?).with(logged_in_page).once.and_return(true)
127
+
128
+ lambda {
129
+ auth.login.should be_true
130
+ }.should_not raise_error
131
+
132
+ end
133
+
134
+ it "should not login via composed template methods if already logged in" do
135
+ auth = self.auth
136
+ auth.should_receive(:authenticated?).once.and_return(true)
137
+
138
+ auth.should_not_receive(:fetch_login_page)
139
+ auth.should_not_receive(:logged_in?)
140
+ auth.should_not_receive(:login_form)
141
+
142
+ lambda {
143
+ auth.login.should be_true
144
+ }.should_not raise_error
145
+ end
146
+ end
147
+
148
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require "impostor"
4
+
5
+ require 'rspec'
6
+ require 'impostor_spec_helper'
7
+ require 'test_impostor'
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ config.include ImpostorSpecHelper
12
+ end
@@ -1,8 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
-
3
- require 'net/http'
4
- require 'net/https'
5
-
6
1
  # monkey patch Net::HTTP so un caged requests don't go over the wire
7
2
  module Net #:nodoc:
8
3
  class HTTP #:nodoc:
@@ -17,22 +12,18 @@ module Net #:nodoc:
17
12
  :port => self.port, :path => query[0]}
18
13
  opts[:query] = query[1] if query[1]
19
14
  uri = uri_cls.build(opts)
20
- raise ArgumentError.new("#{req.method} method to #{uri} not being handled in testing")
15
+ if uri.to_s =~ /^http:\/\/localhost\//
16
+ old_net_http_request(req, body, &block)
17
+ else
18
+ raise ArgumentError.new("#{req.method} method to #{uri} not being handled in testing")
19
+ end
21
20
  end
22
21
 
23
22
  def connect
23
+ if address.to_s == "localhost"
24
+ old_net_http_connect
25
+ end
24
26
  end
25
27
 
26
28
  end
27
29
  end
28
-
29
- module TestHelper
30
-
31
- ##
32
- # helps load pages
33
-
34
- def load_page(file)
35
- IO.readlines("#{File.dirname(__FILE__)}/fixtures/#{file}")
36
- end
37
-
38
- end