Skip to content

Commit 1f30ce8

Browse files
simbabqueoalders
authored andcommitted
allow undef files when Content is present
This commit bumps HTML::Form to 6.08 to fix a bug that would not allow us to set the content from a header without the file argument present. It also fixes another bug where the code blew up if a non-existent field was requested.
1 parent 57b845b commit 1f30ce8

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

Changes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Revision history for WWW::Mechanize
22

33
{{$NEXT}}
4+
[FIXED]
5+
- File upload fields now correctly handle overwriting the file name and
6+
passing in content without a real file (GH#249) (Gil Magno and Julien
7+
Fiegehenn)
8+
- HTML::Form bumped to 6.08 (GH#347) (Julien Fiegehenn)
9+
410
[ENHANCEMENTS]
511
- Add autocheck() to enable or disable autochecking at run time in
612
addition to setting it at object creation (GH#232) (Julien Fiegehenn)

dist.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dir = script
2424

2525
[Prereqs / RuntimeRequires]
2626
perl = 5.006
27+
HTML::Form = 6.08
2728
Scalar::Util = 1.14
2829

2930
[Prereqs / TestRequires]

lib/WWW/Mechanize.pm

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,6 +1901,8 @@ These methods allow you to set the values of fields in a given form.
19011901
19021902
=head2 $mech->field( $name, \@values, $number )
19031903
1904+
=head2 $mech->field( $name, \@file_upload_values, $number )
1905+
19041906
Given the name of a field, set its value to the value specified.
19051907
This applies to the current form (as set by the
19061908
C<L<< form_name()|/"$mech->form_name( $name [, \%args ] )" >>> or
@@ -1914,16 +1916,17 @@ If the field is of type "file", its value should be an arrayref. Example:
19141916
Value examples for "file" inputs, followed by explanation of what each
19151917
index mean:
19161918
1919+
# 0: filepath 1: filename 3: headers
19171920
['/tmp/file.txt']
19181921
['/tmp/file.txt', 'filename.txt']
19191922
['/tmp/file.txt', 'filename.txt', @headers]
19201923
['/tmp/file.txt', 'filename.txt', Content => 'some content']
19211924
[undef, 'filename.txt', Content => 'content here']
19221925
1923-
Index 0 is the filepath that will be read from disk. Index 1 is the
1926+
Index 0 is the I<filepath> that will be read from disk. Index 1 is the
19241927
filename which will be used in the HTTP request body; if not given,
1925-
filepath (index 0) is used instead. If "Content => 'content here'" is
1926-
informed as shown, then filepath will be ignored.
1928+
filepath (index 0) is used instead. If C<<Content => 'content here'>> is
1929+
used as shown, then I<filepath> will be ignored.
19271930
19281931
The optional C<$number> parameter is used to distinguish between two fields
19291932
with the same name. The fields are numbered from 1.
@@ -2059,6 +2062,8 @@ sub select {
20592062
20602063
=head2 $mech->set_fields( $name => \$value_instance_number )
20612064
2065+
=head2 $mech->set_fields( $name => \@file_upload )
2066+
20622067
This method sets multiple fields of the current form. It takes a list
20632068
of field name and value pairs. If there is more than one field with
20642069
the same name, the first one found is set. If you want to select which
@@ -2108,7 +2113,7 @@ sub set_fields {
21082113
my $number = 1;
21092114

21102115
if ( ref $value eq 'ARRAY' ) {
2111-
my $input = $form->find_input($field);
2116+
my $input = $form->find_input($field) or next FIELD;
21122117

21132118
# Honor &submit_form's documentation, that says that a
21142119
# "file" input's value can be in the form of

t/file_upload.t

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
use strict;
22
use warnings;
33
use Test::More;
4+
use Test::Exception;
45
use WWW::Mechanize;
56
use URI::file;
67

78
my $file = 't/file_upload.html';
89
my $filename = 'the_file_upload.html';
910
my $mc = WWW::Mechanize->new;
1011
my $uri = URI::file->new_abs( 't/file_upload.html' )->as_string;
11-
my ($form, $input);
12+
my ($form, $input, $as_string);
1213

1314
# &field
15+
$mc->get( $uri );
16+
$mc->field( 'document', [$file] );
17+
($form) = $mc->forms;
18+
$as_string = $form->make_request->as_string;
19+
like( $as_string, qr! filename="$file" !x,
20+
q/$mc->field( 'document', [$file] )/ );
21+
like(
22+
$as_string, qr!<form method="post" enctype="multipart/form-data"!,
23+
'... and the file was sent'
24+
);
1425

1526
$mc->get( $uri );
1627
$mc->field( 'document', [$file, $filename] );
@@ -19,24 +30,46 @@ like( $form->make_request->as_string, qr! filename="$filename" !x,
1930
q/$mc->field( 'document', [$file, $filename] )/ );
2031

2132
$mc->get( $uri );
22-
$mc->field( 'document', [$file, $filename, Content => 'content'] );
33+
$mc->field( 'document', [$file, $filename, Content => 'changed content'] );
2334
($form) = $mc->forms;
24-
like( $form->make_request->as_string, qr! filename="$filename" !x,
25-
q/$mc->field( 'document', [$file, $filename, Content => 'content'] )/ );
35+
$as_string = $form->make_request->as_string;
36+
like( $as_string, qr! filename="$filename" !x,
37+
q/$mc->field( 'document', [$file, $filename, Content => 'changed content'] )/ );
38+
like(
39+
$as_string, qr!changed content!,
40+
'... and the Content header was sent instead of the file'
41+
);
42+
2643

2744
# &set_fields
2845

46+
$mc->get( $uri );
47+
$mc->set_fields( 'document' => [$file] );
48+
($form) = $mc->forms;
49+
$as_string = $form->make_request->as_string;
50+
like( $as_string, qr! filename="$file" !x,
51+
q/$mc->set_fields( 'document', [$file] )/ );
52+
like(
53+
$as_string, qr!<form method="post" enctype="multipart/form-data"!,
54+
'... and the file was sent'
55+
);
56+
2957
$mc->get( $uri );
3058
$mc->set_fields( 'document' => [ $file, $filename ] );
3159
($form) = $mc->forms;
3260
like( $form->make_request->as_string, qr! filename="$filename" !x,
3361
q/$mc->set_fields( 'document' => [ $file, $filename ] )/ );
3462

3563
$mc->get( $uri );
36-
$mc->set_fields( 'document' => [ $file, $filename, Content => 'content' ] );
64+
$mc->set_fields( 'document' => [ $file, $filename, Content => 'my content' ] );
3765
($form) = $mc->forms;
38-
like( $form->make_request->as_string, qr! filename="$filename" !x,
39-
q/$mc->set_fields( 'document' => [ $file, $filename, Content => 'content' ] )/ );
66+
$as_string = $form->make_request->as_string;
67+
like( $as_string, qr! filename="$filename" !x,
68+
q/$mc->set_fields( 'document' => [ $file, $filename, Content => 'my content' ] )/ );
69+
like(
70+
$as_string, qr!my content!,
71+
'... and the Content header was sent instead of the file'
72+
);
4073

4174
$mc->get( $uri );
4275
$mc->set_fields( 'document' => [[ $file, $filename ], 1] );
@@ -51,4 +84,21 @@ $mc->set_fields
5184
like( $form->make_request->as_string, qr! filename="$filename" !x,
5285
q/$mc->set_fields( 'document' => [[ $file, $filename, Content => 'content' ], 1] )/ );
5386

87+
$mc->get( $uri );
88+
$mc->set_fields
89+
( 'document' => [[ undef, $filename, Content => 'content' ], 1] );
90+
($form) = $mc->forms;
91+
$as_string = $form->make_request->as_string;
92+
like( $as_string, qr! filename="$filename" !x,
93+
q/$mc->set_fields( 'document' => [[ undef, $filename, Content => 'content' ], 1] )/ );
94+
95+
# field does not exist
96+
$mc->get( $uri );
97+
lives_ok { $mc->set_fields( 'does_not_exist' => [ [$file], 1 ] ) }
98+
'setting a field that does not exist lives';
99+
($form) = $mc->forms;
100+
$as_string = $form->make_request->as_string;
101+
unlike( $as_string, qr! filename="$file" !x,
102+
q/$mc->set_fields( 'does_not_exist' => [ [$file], 1 ] )/ );
103+
54104
done_testing;

0 commit comments

Comments
 (0)