Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 15
- Log:
Attempt to update Typo to a Typo SVN HEAD release from around the
time the prototype installation was set up on the RISC OS Open Limited
web site. Timestamps place this at 04-Jul so a revision from 05-Jul or
earlier was pulled and copied over the 2.6.0 tarball stable code.
- Author:
- adh
- Date:
- Sat Jul 22 23:27:35 +0100 2006
- Size:
- 10410 Bytes
1 | require 'logger' |
2 | require 'test/unit' |
3 | require 'cgi' |
4 | require 'stringio' |
5 | |
6 | DEBUG=false |
7 | |
8 | def test_logger |
9 | if DEBUG then ActionController::Base.logger = Logger.new(STDERR) |
10 | else ActionController::Base.logger = Logger.new(StringIO.new) |
11 | end |
12 | end |
13 | |
14 | # Provide a static version of the Controllers module instead of the auto-loading version. |
15 | # We don't want these tests to fail when dependencies are to blame. |
16 | module Controllers |
17 | class EmptyController < ActionController::Base |
18 | end |
19 | class ApplicationController < ActionController::Base |
20 | end |
21 | |
22 | class MockController < ActionController::Base |
23 | def initialize |
24 | super |
25 | @session = {:uploads => {}} |
26 | @params = {} |
27 | end |
28 | end |
29 | |
30 | class SingleUploadController < ActionController::Base |
31 | upload_status_for :one |
32 | |
33 | def one; end |
34 | end |
35 | |
36 | class DoubleUploadController < ActionController::Base |
37 | upload_status_for :one, :two |
38 | |
39 | def one; end |
40 | def two; end |
41 | end |
42 | |
43 | class DoubleStatusUploadController < ActionController::Base |
44 | upload_status_for :one, :two, :status => :custom_status |
45 | |
46 | def one; end |
47 | def two; end |
48 | end |
49 | |
50 | class DoubleSeperateController < ActionController::Base |
51 | upload_status_for :one |
52 | upload_status_for :two |
53 | |
54 | def one; end |
55 | def two; end |
56 | end |
57 | |
58 | class UploadController < ActionController::Base |
59 | upload_status_for :norendered, :rendered, :redirected, :finish_param_dict, :finish_param_string, :finish_param_number |
60 | |
61 | def norendered |
62 | end |
63 | |
64 | def rendered |
65 | render_text("rendered") |
66 | end |
67 | |
68 | def redirected |
69 | redirect_to "/redirected/" |
70 | end |
71 | |
72 | def finish_param_dict |
73 | finish_upload_status "{a: 'b'}" |
74 | end |
75 | |
76 | def finish_param_string |
77 | finish_upload_status "'a string'" |
78 | end |
79 | |
80 | def finish_param_number |
81 | finish_upload_status 123 |
82 | end |
83 | |
84 | def finish_param_number_redirect |
85 | redirect_to "/redirected/" |
86 | finish_upload_status 123 |
87 | end |
88 | end |
89 | end |
90 | |
91 | class MockIO < StringIO |
92 | def initialize(data='', &block) |
93 | test_logger.debug("MockIO inializing data: #{data[0..20]}") |
94 | |
95 | @block = block |
96 | super(data) |
97 | end |
98 | |
99 | def write(data) |
100 | test_logger.debug("MockIO write #{data.size} data: #{data[0..20]}") |
101 | super |
102 | end |
103 | def read(size) |
104 | test_logger.debug("MockIO getting data from super") |
105 | data = super |
106 | |
107 | test_logger.debug("Calling read callback") |
108 | @block.call |
109 | |
110 | test_logger.debug("Returning data: #{data.size}") |
111 | data |
112 | end |
113 | end |
114 | |
115 | class MockCGI < CGI |
116 | BOUNDARY = '----------0xKhTmLbOuNdArY' |
117 | FILENAME = 'dummy.nul' |
118 | |
119 | attr_reader :upload_id, :session_options, :session_id |
120 | |
121 | def initialize(size=1000, url='/test', &block) |
122 | @url = url |
123 | @env = {} |
124 | @sio = MockIO.new('') { block.call(self) if block_given? } |
125 | |
126 | @upload_id = '1' |
127 | |
128 | add_param('param1', 'value1') |
129 | add_data(size) |
130 | add_param('param1', 'value2') |
131 | add_end_boundary |
132 | init_env |
133 | @sio.rewind |
134 | super() |
135 | end |
136 | |
137 | #def stdinput_without_progress |
138 | # @sio |
139 | #end |
140 | |
141 | def stdinput |
142 | @sio |
143 | end |
144 | |
145 | def env_table |
146 | @env |
147 | end |
148 | |
149 | private |
150 | def init_env |
151 | @env['HTTP_HOST'] = 'localhost' |
152 | @env['SERVER_PORT'] = '80' |
153 | @env['REQUEST_METHOD'] = "POST" |
154 | @env['QUERY_STRING'] = @url.split('?')[1] || "upload_id=#{upload_id}&query_param=query_value" |
155 | @env['REQUEST_URI'] = @url |
156 | @env['SCRIPT_NAME'] = @url.split('?').first.split('/').last |
157 | @env['PATH_INFO'] = @url.split('?').first |
158 | @env['CONTENT_TYPE'] = "multipart/form-data; boundary=#{BOUNDARY}" |
159 | @env['CONTENT_LENGTH'] = @sio.tell - EOL.size |
160 | |
161 | @session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.inject({}) { |options, pair| |
162 | options[pair.first.to_s] = pair.last; options |
163 | } |
164 | session = CGI::Session.new({}, @session_options.merge({'new_session' => true})) |
165 | @session_id = session.session_id |
166 | @env['COOKIE'] = "_session_id=#{session.session_id}" |
167 | session.close |
168 | end |
169 | |
170 | def add_param(name, value) |
171 | add_boundary |
172 | @sio << "Content-Disposition: form-data; name=\"#{name}\"" << EOL << EOL |
173 | @sio << value.to_s << EOL |
174 | end |
175 | |
176 | def add_data(size) |
177 | add_boundary |
178 | @sio << "Content-Disposition: form-data; name=\"file\"; filename=\"#{FILENAME}\"" << EOL |
179 | @sio << "Content-Type: application/octet-stream" << EOL << EOL |
180 | @sio << "." * size |
181 | @sio << EOL |
182 | end |
183 | |
184 | def add_boundary |
185 | @sio << "--" << BOUNDARY << EOL |
186 | end |
187 | |
188 | def add_end_boundary |
189 | @sio << "--" << BOUNDARY << "--" << EOL |
190 | end |
191 | end |
192 | |
193 | class MultipartProgressTest < Test::Unit::TestCase |
194 | |
195 | def test_domain_language_single |
196 | c = Controllers::SingleUploadController.new |
197 | assert_respond_to(c, :one) |
198 | assert_respond_to(c, :upload_status) |
199 | assert_respond_to(c, :finish_upload_status) |
200 | end |
201 | |
202 | def test_domain_language_double |
203 | c = Controllers::DoubleUploadController.new |
204 | assert_respond_to(c, :one) |
205 | assert_respond_to(c, :two) |
206 | assert_respond_to(c, :upload_status) |
207 | assert_respond_to(c, :finish_upload_status) |
208 | end |
209 | |
210 | def test_domain_language_double_status |
211 | c = Controllers::DoubleStatusUploadController.new |
212 | assert_respond_to(c, :one) |
213 | assert_respond_to(c, :two) |
214 | assert_respond_to(c, :custom_status) |
215 | assert_respond_to(c, :finish_upload_status) |
216 | end |
217 | |
218 | def test_domain_language_double_seperate |
219 | c = Controllers::DoubleSeperateController.new |
220 | assert_respond_to(c, :one) |
221 | assert_respond_to(c, :two) |
222 | assert_respond_to(c, :upload_status) |
223 | assert_respond_to(c, :finish_upload_status) |
224 | end |
225 | |
226 | def test_finish_status_norendered |
227 | # Fails to render the upload finish script because there is no view associated with this action |
228 | test_logger.debug('test_finish_status_norendered') |
229 | |
230 | res = process(:action => 'norendered', :upload_id => 1) |
231 | assert_match(/ActionView::ActionViewError/s, res.body) |
232 | |
233 | res = process(:action => :upload_status, :upload_id => 1) |
234 | assert_match(/Upload finished/s, res.body) |
235 | |
236 | res = process(:action => :norendered) |
237 | assert_match(/ActionView::ActionViewError/s, res.body) |
238 | end |
239 | |
240 | def test_finish_status_rendered |
241 | test_logger.debug('test_finish_status_rendered') |
242 | |
243 | res = process(:action => :rendered, :upload_id => 1) |
244 | assert_match(/stop\(\)/s, res.body) |
245 | assert_no_match(/rendered/s, res.body) |
246 | |
247 | res = process(:action => :upload_status, :upload_id => 1) |
248 | assert_match(/Upload finished/s, res.body) |
249 | |
250 | res = process(:action => :rendered) |
251 | assert_no_match(/stop\(\)/s, res.body) |
252 | assert_match(/rendered/, res.body) |
253 | end |
254 | |
255 | def test_finish_status_redirected |
256 | test_logger.debug('test_finish_status_redirected') |
257 | |
258 | res = process(:action => :redirected, :upload_id => 1) |
259 | assert_match(/location\.replace/s, res.body) |
260 | |
261 | res = process(:action => :redirected) |
262 | assert_no_match(/location\.replace/s, res.body) |
263 | assert_match(/\/redirected\//s, res.headers['location']) |
264 | assert_match(/302 .*$/, res.headers['Status']) |
265 | |
266 | res = process(:action => :upload_status, :upload_id => 1) |
267 | assert_match(/Upload finished/s, res.body) |
268 | end |
269 | |
270 | def test_finish_status_finish_param |
271 | test_logger.debug('test_finish_status_param') |
272 | |
273 | res = process(:action => :finish_param_string, :upload_id => 1) |
274 | assert_match(/stop\('a string'\)/s, res.body) |
275 | assert_no_redirect res |
276 | |
277 | res = process(:action => :finish_param_dict, :upload_id => 1) |
278 | assert_match(/stop\(\{a: 'b'\}\)/s, res.body) |
279 | assert_no_redirect res |
280 | |
281 | res = process(:action => :finish_param_number, :upload_id => 1) |
282 | assert_match(/stop\(123\)/s, res.body) |
283 | assert_no_redirect res |
284 | |
285 | res = process(:action => :finish_param_number_redirect, :upload_id => 1) |
286 | test_logger.debug('test_finish_status_param: ' + res.body) |
287 | assert_match(/stop\(123\)/s, res.body) |
288 | assert_match(/replace\('\http:\/\/localhost\/redirected\/'\).*?/s, res.body) |
289 | assert_no_redirect res |
290 | end |
291 | |
292 | def test_basic_setup |
293 | test_logger.debug('test_basic_setup') |
294 | |
295 | cgi, request, response = new_request(100000) |
296 | assert_not_nil(request.session) |
297 | assert_not_nil(request.session[:uploads], "uploads collection not set") |
298 | assert_not_nil(request.session[:uploads][cgi.upload_id], "upload id not set") |
299 | progress = request.session[:uploads][cgi.upload_id] |
300 | assert_equal(true, progress.finished?) |
301 | end |
302 | |
303 | def test_params |
304 | test_logger.debug('test_params') |
305 | |
306 | cgi, request, response = new_request(1000) |
307 | assert(!request.params.empty?) |
308 | assert(!request.params['param1'].empty?) |
309 | end |
310 | |
311 | def test_share_session |
312 | cgi, request, response = new_request(100000) do |cgi, req| |
313 | if cgi.stdinput.tell > 50000 |
314 | # force a save |
315 | cgi.stdinput.save_progress rescue flunk('Something else is wrong, our wrapper isnt setup, is ActionController::Base.logger set?') |
316 | |
317 | other_session = CGI::Session.new(cgi, cgi.session_options.merge({'session_id' => cgi.session_id})) |
318 | assert_not_nil(other_session[:uploads]) |
319 | assert_not_nil(other_session[:uploads][cgi.upload_id]) |
320 | assert_in_delta(cgi.stdinput.session[:uploads][cgi.upload_id].bitrate, other_session[:uploads][cgi.upload_id].bitrate, 1000.0, "Seperate session does not share data from original session") |
321 | |
322 | other_session.close |
323 | end |
324 | end |
325 | end |
326 | |
327 | def test_upload_ids |
328 | c = Controllers::MockController.new |
329 | (1..222).each do |id| |
330 | c.params = {} |
331 | |
332 | assert_equal((id-1).to_s, c.last_upload_id, "last_upload_id is out of sync") |
333 | assert_equal(id.to_s, c.next_upload_id, "next_upload_id is out of sync") |
334 | assert_equal(id.to_s, c.current_upload_id, "current_upload_id is out of sync") |
335 | |
336 | c.params = {:upload_id => (id-1).to_s} |
337 | assert_equal((id-1).to_s, c.current_upload_id, "current_upload_id is out of sync") |
338 | |
339 | c.session[:uploads][id] = {} |
340 | end |
341 | end |
342 | |
343 | private |
344 | def new_request(size=1000, url='/test', &block) |
345 | test_logger.debug('Creating MockCGI') |
346 | cgi = MockCGI.new(size, url) do |cgi| |
347 | block.call(cgi) if block_given? |
348 | end |
349 | |
350 | assert(cgi.private_methods.include?("read_multipart_with_progress")) |
351 | return [cgi, ActionController::CgiRequest.new(cgi), ActionController::CgiResponse.new(cgi)] |
352 | end |
353 | |
354 | def process(options = {}) |
355 | Controllers::UploadController.process(*(new_request(1000, '/upload?' + options.map {|k,v| "#{k}=#{v}"}.join('&'))[1..2])) |
356 | end |
357 | |
358 | def assert_no_redirect(res) |
359 | assert_nil(res.redirected_to) |
360 | assert_nil(res.headers['location']) |
361 | assert_match(/200 .*$/, res.headers['Status']) |
362 | end |
363 | |
364 | end |