/
FoswikiFnTestCase.pm
268 lines (219 loc) · 7.85 KB
/
FoswikiFnTestCase.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# See bottom of file for license and copyright
package FoswikiFnTestCase;
=begin TML
---+ package FoswikiFnTestCase
This base class layers some extra stuff on FoswikiTestCase to
try and make life for Foswiki testers even easier at higher levels.
Normally this will be the base class for tests that require an almost
complete user environment. However it does quite a lot of relatively
slow setup, so should not be used for simpler tests (such as those
targeting single classes).
1. Do not be afraid to modify Foswiki::cfg. You cannot break other
tests that way.
2. Never, ever write to any webs except the test_web and
users_web, or any other test webs you create and remove
(following the pattern shown below)
3. The password manager is set to HtPasswdUser, and you can create
users as shown in the creation of {test_user}
4. A single user has been pre-registered, wikinamed 'ScumBag'
=cut
use Foswiki();
use Unit::Request();
use Unit::Response();
use Foswiki::UI::Register();
use Try::Tiny;
use Carp qw(cluck);
our @mails;
use Moo;
use namespace::clean;
extends qw(FoswikiTestCase);
has testSuite => (
is => 'ro',
required => 1,
);
has test_web => (
is => 'rw',
lazy => 1,
clearer => 1,
builder => sub {
my $testSuite = $_[0]->testSuite;
return 'Temporary' . $testSuite . 'TestWeb' . $testSuite;
},
);
has test_topic => (
is => 'rw',
lazy => 1,
builder => sub { return 'TestTopic' . $_[0]->testSuite; },
);
has users_web => (
is => 'rw',
lazy => 1,
builder => sub { return 'Temporary' . $_[0]->testSuite . 'UsersWeb'; },
);
has test_user_forename => ( is => 'rw', );
has test_user_surname => ( is => 'rw', );
has test_user_wikiname => ( is => 'rw', );
has test_user_login => ( is => 'rw', );
has test_user_email => ( is => 'rw', );
has test_user_cuid => ( is => 'rw', );
has response => (
is => 'rw',
clearer => 1,
predicate => 1,
isa => Foswiki::Object::isaCLASS( 'response', 'Unit::Response' ),
);
=begin TML
---++ ObjectMethod loadExtraConfig()
This method can be overridden (overrides should call up to the base class)
to add extra stuff to Foswiki::cfg.
=cut
around loadExtraConfig => sub {
my $orig = shift;
my $this = shift;
$orig->( $this, @_ );
#$Foswiki::cfg{Store}{Implementation} = "Foswiki::Store::RcsLite";
$Foswiki::cfg{Store}{Implementation} = "Foswiki::Store::PlainFile";
$Foswiki::cfg{RCS}{AutoAttachPubFiles} = 0;
$Foswiki::cfg{Register}{AllowLoginName} = 1;
$Foswiki::cfg{Htpasswd}{FileName} = "$Foswiki::cfg{WorkingDir}/htpasswd";
unless ( -e $Foswiki::cfg{Htpasswd}{FileName} ) {
my $fh;
open( $fh, ">:encoding(utf-8)", $Foswiki::cfg{Htpasswd}{FileName} )
|| die $!;
close($fh) || die $!;
}
$Foswiki::cfg{PasswordManager} = 'Foswiki::Users::HtPasswdUser';
$Foswiki::cfg{Htpasswd}{GlobalCache} = 0;
$Foswiki::cfg{UserMappingManager} = 'Foswiki::Users::TopicUserMapping';
$Foswiki::cfg{LoginManager} = 'Foswiki::LoginManager::TemplateLogin';
$Foswiki::cfg{Register}{EnableNewUserRegistration} = 1;
$Foswiki::cfg{RenderLoggedInButUnknownUsers} = 0;
$Foswiki::cfg{Register}{NeedVerification} = 0;
$Foswiki::cfg{MinPasswordLength} = 0;
$Foswiki::cfg{UsersWebName} = $this->users_web;
};
around set_up => sub {
my $orig = shift;
my $this = shift;
$orig->( $this, @_ );
my $query = Unit::Request->new( initializer => "" );
$query->path_info( "/" . $this->test_web . "/" . $this->test_topic );
# Note: some tests are testing Foswiki::UI which also creates a session
$this->createNewFoswikiSession( undef, $query );
$this->response( new Unit::Response() );
@mails = ();
$this->session->net->setMailHandler( \&FoswikiFnTestCase::sentMail );
my $webObject = $this->populateNewWeb( $this->test_web );
$webObject->finish();
$this->clear_test_topicObject;
$this->test_topicObject(
Foswiki::Func::readTopic( $this->test_web, $this->test_topic ) );
$this->test_topicObject->text("BLEEGLE\n");
$this->test_topicObject->save( forcedate => ( time() + 60 ) );
$webObject = $this->populateNewWeb( $this->users_web );
$webObject->finish();
$this->test_user_forename('Scum');
$this->test_user_surname('Bag');
$this->test_user_wikiname(
$this->test_user_forename . $this->test_user_surname );
$this->test_user_login('scum');
$this->test_user_email('scumbag@example.com');
$this->registerUser(
$this->test_user_login, $this->test_user_forename,
$this->test_user_surname, $this->test_user_email
);
$this->test_user_cuid(
$this->session->users->getCanonicalUserID( $this->test_user_login ) );
};
around tear_down => sub {
my $orig = shift;
my $this = shift;
$this->removeWebFixture( $this->session, $this->test_web );
$this->removeWebFixture( $this->session, $Foswiki::cfg{UsersWebName} );
unlink( $Foswiki::cfg{Htpasswd}{FileName} );
$orig->( $this, @_ );
};
=begin TML
---++ ObjectMethod removeWeb($web)
Remove a temporary web fixture (data and pub)
=cut
sub removeWeb {
my ( $this, $web ) = @_;
$this->removeWebFixture( $this->session, $web );
}
=begin TML
---++ StaticMethod sentMail($net, $mess)
Default implementation for the callback used by Net.pm. Sent mails are
pushed onto a global variable @FoswikiFnTestCase::mails.
=cut
sub sentMail {
my ( $net, $mess ) = @_;
push( @mails, $mess );
return undef;
}
=begin TML
---++ ObjectMethod registerUser($loginname, $forename, $surname, $email)
Can be used by subclasses to register test users.
=cut
sub registerUser {
my ( $this, $loginname, $forename, $surname, $email ) = @_;
my $q = $this->session->request;
my $params = {
'TopicName' => ['UserRegistration'],
'Twk1Email' => [$email],
'Twk1WikiName' => ["$forename$surname"],
'Twk1Name' => ["$forename $surname"],
'Twk0Comment' => [''],
'Twk1FirstName' => [$forename],
'Twk1LastName' => [$surname],
'action' => ['register']
};
if ( $Foswiki::cfg{Register}{AllowLoginName} ) {
$params->{"Twk1LoginName"} = $loginname;
}
my $query = Unit::Request->new($params);
$query->path_info( "/" . $this->users_web . "/UserRegistration" );
$this->createNewFoswikiSession( undef, $query );
$this->assert(
$this->session->topicExists(
$this->test_web, $Foswiki::cfg{WebPrefsTopicName}
)
);
$this->session->net->setMailHandler( \&FoswikiFnTestCase::sentMail );
try {
$this->captureWithKey(
register_cgi => \&Foswiki::UI::Register::register_cgi,
$this->session
);
}
catch {
my $e = $_;
if ( $e->isa('Foswiki::OopsException') ) {
if ( $this->check_dependency('Foswiki,<,1.2') ) {
$this->assert_str_equals( "attention", $e->{template},
$e->stringify() );
$this->assert_str_equals( "thanks", $e->{def},
$e->stringify() );
}
else {
$this->assert_str_equals( "register", $e->{template},
$e->stringify() );
$this->assert_str_equals( "thanks", $e->{def},
$e->stringify() );
}
}
elsif ( $e->isa('Foswiki::AccessControlException') ) {
$this->assert( 0, $e->stringify );
}
elsif ( $e->isa('Foswiki::Exception') ) {
$this->assert( 0, $e->stringify );
}
else {
$this->assert( 0, "expected an oops redirect" );
}
};
# Reload caches
$this->createNewFoswikiSession( undef, $q );
$this->session->net->setMailHandler( \&FoswikiFnTestCase::sentMail );
}
1;