line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::Mojo::Role::Slovo; |
2
|
|
|
|
|
|
|
|
3
|
13
|
|
|
13
|
|
7665
|
use Mojo::Base -role, -signatures; |
|
13
|
|
|
|
|
30
|
|
|
13
|
|
|
|
|
95
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
BEGIN { |
6
|
13
|
|
|
13
|
|
48997
|
binmode STDOUT => ':encoding(UTF8)'; |
|
13
|
|
|
13
|
|
83
|
|
|
13
|
|
|
|
|
19
|
|
|
13
|
|
|
|
|
84
|
|
7
|
13
|
|
|
|
|
12547
|
binmode STDERR => ':encoding(UTF8)'; |
8
|
|
|
|
|
|
|
} |
9
|
13
|
|
|
13
|
|
719
|
use Test::More; |
|
13
|
|
|
|
|
26
|
|
|
13
|
|
|
|
|
151
|
|
10
|
13
|
|
|
13
|
|
3216
|
use Mojo::File qw(path tempdir); |
|
13
|
|
|
|
|
24
|
|
|
13
|
|
|
|
|
593
|
|
11
|
13
|
|
|
13
|
|
68
|
use Mojo::ByteStream 'b'; |
|
13
|
|
|
|
|
21
|
|
|
13
|
|
|
|
|
583
|
|
12
|
13
|
|
|
13
|
|
73
|
use Mojo::Util qw(encode sha1_sum); |
|
13
|
|
|
|
|
37
|
|
|
13
|
|
|
|
|
656
|
|
13
|
13
|
|
|
13
|
|
75
|
use Mojo::IOLoop::Server; |
|
13
|
|
|
|
|
24
|
|
|
13
|
|
|
|
|
222
|
|
14
|
13
|
|
|
13
|
|
6375
|
use Slovo; |
|
13
|
|
|
|
|
38
|
|
|
13
|
|
|
|
|
166
|
|
15
|
|
|
|
|
|
|
my $default_from = Slovo->home->to_abs->realpath; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $random_tempdir = tempdir('slovoXXXX', TMPDIR => 1, CLEANUP => 1); |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
has authenticated => 0; |
20
|
|
|
|
|
|
|
has login_name => 'краси'; |
21
|
|
|
|
|
|
|
has login_password => 'беров'; |
22
|
2
|
|
|
2
|
0
|
1215
|
sub domain_aliases { return 'some.domain alias.domain alias2.domain' }; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Class method |
25
|
|
|
|
|
|
|
# Install the app from a path to a temporary path. Creates a log directory in |
26
|
|
|
|
|
|
|
# installation directory to hide log output from screen and put it to slovo.log |
27
|
|
|
|
|
|
|
# if $to_tempdir equals $random_tempdir. |
28
|
|
|
|
|
|
|
# You can pass '/tmp/slovo' after $from. The tmp/slovo will not be |
29
|
|
|
|
|
|
|
# automatically deleted and you can debug the installed application. |
30
|
|
|
|
|
|
|
my $MOJO_HOME; |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub new { |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# class Test::Mojo__WITH__Test::Mojo::Role::Slovo |
35
|
|
|
|
|
|
|
# Unload the used already Slovo to require it from its newly installed location |
36
|
12
|
|
|
12
|
0
|
60
|
unuse_Slovo(); #if $INC{'Slovo.pm'}; |
37
|
|
|
|
|
|
|
|
38
|
12
|
|
|
|
|
89
|
my $t = Test::Mojo::new(@_); |
39
|
12
|
|
|
|
|
2147
|
ok($t->app->dbx->migrations->migrate, 'migrated'); |
40
|
12
|
|
|
|
|
165527
|
return $t; |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub install ( |
44
|
12
|
|
|
|
|
24
|
$class, |
45
|
12
|
|
|
|
|
23
|
$from = $default_from, |
46
|
12
|
|
|
|
|
77
|
$to_tempdir = "$random_tempdir/slovo", |
47
|
12
|
|
|
|
|
498
|
$dir_mode = 0700 |
48
|
|
|
|
|
|
|
) |
49
|
12
|
|
|
12
|
0
|
13911
|
{ |
|
12
|
|
|
|
|
19
|
|
50
|
12
|
|
33
|
|
|
35
|
$from //= $default_from; |
51
|
12
|
50
|
|
|
|
110
|
-d $from || Carp::croak "Directory $from does not exist!"; |
52
|
12
|
|
|
|
|
295
|
note 'installing $from: ' . $from; |
53
|
12
|
|
|
|
|
6880
|
$MOJO_HOME = path($to_tempdir); |
54
|
12
|
|
|
|
|
187
|
note ' to: ' . $MOJO_HOME; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# idempotent |
57
|
12
|
|
|
|
|
3138
|
$MOJO_HOME->remove_tree->make_path({mode => $dir_mode}); |
58
|
12
|
|
|
|
|
3801
|
ok(-d $MOJO_HOME, "created $MOJO_HOME"); |
59
|
12
|
50
|
|
|
|
5276
|
$MOJO_HOME->child('log')->make_path({mode => $dir_mode}) |
60
|
|
|
|
|
|
|
if $to_tempdir eq $random_tempdir; |
61
|
12
|
|
|
|
|
508
|
$MOJO_HOME->child('domove/localhost')->make_path({mode => $dir_mode}); |
62
|
|
|
|
|
|
|
path($from, 'domove/localhost')->list_tree({dir => 1}) |
63
|
12
|
|
|
0
|
|
2726
|
->each(sub { _copy_to(@_, $from, $dir_mode) }); |
|
0
|
|
|
|
|
0
|
|
64
|
12
|
|
|
|
|
1189
|
$MOJO_HOME->child('data')->make_path({mode => $dir_mode}); |
65
|
12
|
|
|
|
|
1774
|
$MOJO_HOME->child('t')->make_path({mode => $dir_mode}); |
66
|
12
|
|
|
0
|
|
1633
|
path($from, 't')->list_tree({dir => 1})->each(sub { _copy_to(@_, $from, $dir_mode) }); |
|
0
|
|
|
|
|
0
|
|
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# warn $/ . '$script_dir:' . $script_dir; |
69
|
|
|
|
|
|
|
# warn 'Cwd::getcwd:' . Cwd::getcwd; |
70
|
|
|
|
|
|
|
# warn ' $from:' . $from; |
71
|
|
|
|
|
|
|
# warn 'slovo exists:' . (-f $script_dir->child('slovo')); |
72
|
12
|
|
|
|
|
882
|
$MOJO_HOME->child('script')->make_path({mode => $dir_mode}); |
73
|
|
|
|
|
|
|
path($from, 'script')->list_tree({dir => 1}) |
74
|
12
|
|
|
12
|
|
1619
|
->each(sub { _copy_to(@_, $from, $dir_mode) }); |
|
12
|
|
|
|
|
3339
|
|
75
|
12
|
|
|
2724
|
|
106
|
path($from, 'lib')->list_tree({dir => 1})->each(sub { _copy_to(@_, $from, $dir_mode) }); |
|
2724
|
|
|
|
|
108337
|
|
76
|
12
|
|
|
|
|
1199
|
unshift @INC, path($to_tempdir, 'lib')->to_string; |
77
|
12
|
|
|
|
|
494
|
return $class; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
2736
|
|
|
2736
|
|
3360
|
sub _copy_to ($f, $i, $root, $dir_mode) { |
|
2736
|
|
|
|
|
3521
|
|
|
2736
|
|
|
|
|
2952
|
|
|
2736
|
|
|
|
|
2947
|
|
|
2736
|
|
|
|
|
2845
|
|
|
2736
|
|
|
|
|
2824
|
|
81
|
2736
|
50
|
|
|
|
5950
|
$f =~ /\.sqlite$/ && return; # do not copy existing database |
82
|
2736
|
50
|
|
|
|
14430
|
$f =~ /cached/ && return; # do not copy cached files |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Leave the relative part from $from to append it to $MOJO_HOME. |
85
|
|
|
|
|
|
|
# warn $root; |
86
|
2736
|
|
|
|
|
59442
|
my ($f_rel) = $f =~ s|\Q$root\E/?||r; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# warn $f_rel; |
89
|
2736
|
|
|
|
|
44890
|
my $new = $MOJO_HOME->child($f_rel); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# warn $new; |
92
|
2736
|
100
|
|
|
|
45360
|
(-d $f) && $new->make_path({mode => $dir_mode}); |
93
|
2736
|
100
|
|
|
|
168644
|
eval { (-f $f) && $f->copy_to($new); 1; } || Carp::carp $@; |
|
2736
|
100
|
|
|
|
9690
|
|
|
2724
|
|
|
|
|
806534
|
|
94
|
2736
|
|
|
|
|
17318
|
return; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
# use this method for the side effect of having a logged in user |
98
|
2
|
|
|
2
|
0
|
393
|
sub login_ok ($t, $login_name = '', $login_password = '', $host = '') { |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
4
|
|
99
|
|
|
|
|
|
|
subtest login_ok => sub { |
100
|
2
|
|
|
2
|
|
1739
|
my $login_url = $t->app->url_for('sign_in'); |
101
|
2
|
|
|
|
|
1237
|
$t->get_ok($host . '/manage')->status_is(302) |
102
|
|
|
|
|
|
|
->header_is(Location => $login_url, 'Location is /in'); |
103
|
2
|
|
|
|
|
716
|
$t->get_ok($host . '/in')->status_is(200)->text_is('fieldset legend' => 'Входъ'); |
104
|
2
|
|
|
|
|
729
|
my $form = $t->fill_in_login_form($login_name, $login_password, $host); |
105
|
2
|
|
|
|
|
93
|
my $body |
106
|
|
|
|
|
|
|
= $t->post_ok($host . $login_url, {} => form => $form)->status_is(302) |
107
|
|
|
|
|
|
|
->header_is(Location => '/' . b('manage')->encode->url_escape, 'Location: /manage') |
108
|
|
|
|
|
|
|
->content_is('', 'empty content')->tx->res->body; |
109
|
2
|
|
|
|
|
765
|
$t->authenticated($body eq ''); |
110
|
2
|
|
|
|
|
20
|
}; |
111
|
2
|
|
|
|
|
2730
|
return $t; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
8
|
|
|
8
|
0
|
20
|
sub fill_in_login_form ($t, $login_name = '', $login_password = '', $host = '') { |
|
8
|
|
|
|
|
21
|
|
|
8
|
|
|
|
|
20
|
|
|
8
|
|
|
|
|
19
|
|
|
8
|
|
|
|
|
22
|
|
|
8
|
|
|
|
|
16
|
|
115
|
8
|
|
66
|
|
|
35
|
$login_name ||= $t->login_name; |
116
|
8
|
|
66
|
|
|
30
|
$login_password ||= $t->login_password; |
117
|
|
|
|
|
|
|
my $csrf_token = $t->ua->get($host . $t->app->url_for('sign_in')) |
118
|
8
|
|
|
|
|
53
|
->res->dom->at('#sign_in [name="csrf_token"]')->{value}; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
return { |
121
|
8
|
|
|
|
|
73747
|
login_name => $login_name, |
122
|
|
|
|
|
|
|
csrf_token => $csrf_token, |
123
|
|
|
|
|
|
|
digest => |
124
|
|
|
|
|
|
|
sha1_sum($csrf_token . sha1_sum(encode('utf8', "$login_name$login_password"))), |
125
|
|
|
|
|
|
|
}; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
6
|
|
|
6
|
0
|
20415
|
sub login ($t, $login_name = '', $login_password = '') { |
|
6
|
|
|
|
|
22
|
|
|
6
|
|
|
|
|
22
|
|
|
6
|
|
|
|
|
15
|
|
|
6
|
|
|
|
|
20
|
|
129
|
6
|
|
|
|
|
35
|
my $form = $t->fill_in_login_form($login_name, $login_password); |
130
|
6
|
|
|
|
|
268
|
my $body |
131
|
|
|
|
|
|
|
= $t->post_ok($t->app->url_for('sign_in') => {} => form => $form)->tx->res->body; |
132
|
6
|
|
|
|
|
28183
|
return $t->authenticated($body eq '')->authenticated; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Tests creation of a domove record and returns the URL for GET, PUT, DELETE |
136
|
|
|
|
|
|
|
## no critic (ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters) |
137
|
0
|
|
|
0
|
0
|
0
|
sub create_edit_domain_ok ($t) { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
#authenticate user if not authenticated |
140
|
0
|
0
|
|
|
|
0
|
if (!$t->authenticated) { |
141
|
0
|
|
|
|
|
0
|
ok($t->login(), 'logged in'); |
142
|
|
|
|
|
|
|
} |
143
|
0
|
|
|
|
|
0
|
$t->get_ok($t->app->url_for('create_domove'))->status_is(200); |
144
|
0
|
|
|
|
|
0
|
my $store_url = $t->app->url_for('store_domove'); |
145
|
0
|
|
0
|
|
|
0
|
my $TEST_DOMAIN = $ENV{TEST_DOMAIN} || $t->domain_aliases; |
146
|
0
|
|
|
|
|
0
|
my $domain = [split /\s+/, $TEST_DOMAIN]; |
147
|
0
|
|
|
|
|
0
|
my $form = { |
148
|
|
|
|
|
|
|
domain => $domain->[0], |
149
|
|
|
|
|
|
|
aliases => $TEST_DOMAIN, |
150
|
|
|
|
|
|
|
site_name => 'У дома', |
151
|
|
|
|
|
|
|
description => 'Съвсем у дома', |
152
|
|
|
|
|
|
|
owner_id => 5, |
153
|
|
|
|
|
|
|
group_id => 5, |
154
|
|
|
|
|
|
|
published => 2, |
155
|
|
|
|
|
|
|
templates => 'themes/malka' |
156
|
|
|
|
|
|
|
}; |
157
|
0
|
|
|
|
|
0
|
my $edit_url = $t->post_ok($store_url => form => $form)->status_is(302) |
158
|
|
|
|
|
|
|
->tx->res->headers->location; |
159
|
0
|
|
|
|
|
0
|
$t->get_ok($edit_url)->text_is('h2' => "1:$form->{domain}"); |
160
|
|
|
|
|
|
|
|
161
|
0
|
|
|
|
|
0
|
$form->{aliases} .= ' alias2.domain'; |
162
|
0
|
|
|
|
|
0
|
$t->put_ok($edit_url => form => $form)->status_is(302) |
163
|
|
|
|
|
|
|
->header_is(Location => $edit_url); |
164
|
0
|
|
|
|
|
0
|
my $body = $t->get_ok($edit_url)->tx->res->body; |
165
|
0
|
|
|
|
|
0
|
like($body => qr/$form->{aliases}/ => 'aliases changed'); |
166
|
0
|
|
|
|
|
0
|
like($body => qr/$form->{templates}/ => 'templates changed'); |
167
|
0
|
|
|
|
|
0
|
return $edit_url; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
|
170
|
2
|
|
|
2
|
0
|
134422
|
sub meta_names_ok ($t) { |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
4
|
|
171
|
2
|
|
|
|
|
6
|
for (qw(author description keywords generator viewport )) { |
172
|
10
|
|
|
|
|
3383
|
my $selector = qq'head meta[name="$_"]'; |
173
|
10
|
|
|
|
|
46
|
$t->element_exists($selector, $selector . ' exists') |
174
|
|
|
|
|
|
|
->attr_like($selector => 'content', qr/.+/ => $selector . ' has content'); |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# OpenGraph |
178
|
2
|
|
|
|
|
844
|
for (qw(og:type og:site_name og:title og:url og:type og:article:author og:description |
179
|
|
|
|
|
|
|
og:locale og:article:published_time og:article:modified_time)) |
180
|
|
|
|
|
|
|
{ |
181
|
20
|
|
|
|
|
7719
|
my $selector = qq'head meta[property="$_"]'; |
182
|
20
|
|
|
|
|
80
|
$t->element_exists($selector, $selector . ' exists') |
183
|
|
|
|
|
|
|
->attr_like($selector => 'content', qr/.+/ => $selector . ' has content'); |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
} |
186
|
2
|
|
|
|
|
1177
|
return $t; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Stollen from Class::Unload and modified. Thanks! |
190
|
|
|
|
|
|
|
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines,TestingAndDebugging::ProhibitNoStrict) |
191
|
|
|
|
|
|
|
sub unuse_Slovo { |
192
|
12
|
|
|
12
|
0
|
33
|
my $class = 'Slovo'; |
193
|
12
|
|
|
|
|
38
|
my $symtab = $class . '::'; |
194
|
|
|
|
|
|
|
{ |
195
|
13
|
|
|
13
|
|
21109
|
no strict 'refs'; # we're fiddling with the symbol table |
|
13
|
|
|
|
|
29
|
|
|
13
|
|
|
|
|
3091
|
|
|
12
|
|
|
|
|
28
|
|
196
|
12
|
|
|
|
|
24
|
@{$class . '::ISA'} = (); |
|
12
|
|
|
|
|
358
|
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Delete all symbols except other namespaces |
199
|
12
|
|
|
|
|
236
|
for my $symbol (keys %$symtab) { |
200
|
363
|
100
|
|
|
|
763
|
next if $symbol =~ /\A[^:]+::\z/; |
201
|
324
|
|
|
|
|
3857
|
delete $symtab->{$symbol}; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
12
|
|
|
|
|
148
|
my $inc_file = join('/', split /(?:'|::)/, $class) . '.pm'; |
206
|
12
|
|
|
|
|
46
|
delete $INC{$inc_file}; |
207
|
|
|
|
|
|
|
|
208
|
12
|
|
|
|
|
30
|
return 1; |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
1; |