File Coverage

blib/lib/Test/Mojo/Role/Slovo.pm
Criterion Covered Total %
statement 128 148 86.4
branch 12 18 66.6
condition 5 12 41.6
subroutine 22 25 88.0
pod 0 9 0.0
total 167 212 78.7


line stmt bran cond sub pod time code
1             package Test::Mojo::Role::Slovo;
2              
3 13     13   8972 use Mojo::Base -role, -signatures;
  13         37  
  13         118  
4              
5             BEGIN {
6 13     13   57838 binmode STDOUT => ':encoding(UTF8)';
  13     13   84  
  13         30  
  13         159  
7 13         14652 binmode STDERR => ':encoding(UTF8)';
8             }
9 13     13   888 use Test::More;
  13         38  
  13         156  
10 13     13   3645 use Mojo::File qw(path tempdir);
  13         27  
  13         713  
11 13     13   81 use Mojo::ByteStream 'b';
  13         31  
  13         693  
12 13     13   100 use Mojo::Util qw(encode sha1_sum);
  13         26  
  13         731  
13 13     13   98 use Mojo::IOLoop::Server;
  13         25  
  13         248  
14 13     13   7314 use Slovo;
  13         46  
  13         164  
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 1436 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 73 unuse_Slovo(); #if $INC{'Slovo.pm'};
37              
38 12         104 my $t = Test::Mojo::new(@_);
39 12         2320 ok($t->app->dbx->migrations->migrate, 'migrated');
40 12         188854 return $t;
41             }
42              
43             sub install (
44 12         36 $class,
45 12         25 $from = $default_from,
46 12         67 $to_tempdir = "$random_tempdir/slovo",
47 12         632 $dir_mode = 0700
48             )
49 12     12 0 16591 {
  12         23  
50 12   33     37 $from //= $default_from;
51 12 50       136 -d $from || Carp::croak "Directory $from does not exist!";
52 12         342 note 'installing $from: ' . $from;
53 12         9996 $MOJO_HOME = path($to_tempdir);
54 12         229 note ' to: ' . $MOJO_HOME;
55              
56             # idempotent
57 12         4255 $MOJO_HOME->remove_tree->make_path({mode => $dir_mode});
58 12         4220 ok(-d $MOJO_HOME, "created $MOJO_HOME");
59 12 50       6849 $MOJO_HOME->child('log')->make_path({mode => $dir_mode})
60             if $to_tempdir eq $random_tempdir;
61 12         538 $MOJO_HOME->child('domove/localhost')->make_path({mode => $dir_mode});
62             path($from, 'domove/localhost')->list_tree({dir => 1})
63 12     0   3219 ->each(sub { _copy_to(@_, $from, $dir_mode) });
  0         0  
64 12         1283 $MOJO_HOME->child('data')->make_path({mode => $dir_mode});
65 12         1980 $MOJO_HOME->child('t')->make_path({mode => $dir_mode});
66 12     0   1985 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         1005 $MOJO_HOME->child('script')->make_path({mode => $dir_mode});
73             path($from, 'script')->list_tree({dir => 1})
74 12     12   1908 ->each(sub { _copy_to(@_, $from, $dir_mode) });
  12         3486  
75 12     2724   134 path($from, 'lib')->list_tree({dir => 1})->each(sub { _copy_to(@_, $from, $dir_mode) });
  2724         123481  
76 12         1445 unshift @INC, path($to_tempdir, 'lib')->to_string;
77 12         603 return $class;
78             }
79              
80 2736     2736   3873 sub _copy_to ($f, $i, $root, $dir_mode) {
  2736         4515  
  2736         3650  
  2736         3558  
  2736         3474  
  2736         3539  
81 2736 50       7144 $f =~ /\.sqlite$/ && return; # do not copy existing database
82 2736 50       17495 $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         72548 my ($f_rel) = $f =~ s|\Q$root\E/?||r;
87              
88             # warn $f_rel;
89 2736         52432 my $new = $MOJO_HOME->child($f_rel);
90              
91             # warn $new;
92 2736 100       54051 (-d $f) && $new->make_path({mode => $dir_mode});
93 2736 100       199608 eval { (-f $f) && $f->copy_to($new); 1; } || Carp::carp $@;
  2736 100       11196  
  2724         952304  
94 2736         22540 return;
95             }
96              
97             # use this method for the side effect of having a logged in user
98 2     2 0 647 sub login_ok ($t, $login_name = '', $login_password = '', $host = '') {
  2         8  
  2         8  
  2         4  
  2         5  
  2         5  
99             subtest login_ok => sub {
100 2     2   2323 my $login_url = $t->app->url_for('sign_in');
101 2         1622 $t->get_ok($host . '/manage')->status_is(302)
102             ->header_is(Location => $login_url, 'Location is /in');
103 2         957 $t->get_ok($host . '/in')->status_is(200)->text_is('fieldset legend' => 'Входъ');
104 2         1122 my $form = $t->fill_in_login_form($login_name, $login_password, $host);
105 2         164 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         1011 $t->authenticated($body eq '');
110 2         26 };
111 2         3690 return $t;
112             }
113              
114 8     8 0 27 sub fill_in_login_form ($t, $login_name = '', $login_password = '', $host = '') {
  8         30  
  8         26  
  8         20  
  8         27  
  8         17  
115 8   66     70 $login_name ||= $t->login_name;
116 8   66     39 $login_password ||= $t->login_password;
117             my $csrf_token = $t->ua->get($host . $t->app->url_for('sign_in'))
118 8         68 ->res->dom->at('#sign_in [name="csrf_token"]')->{value};
119              
120             return {
121 8         108297 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 22972 sub login ($t, $login_name = '', $login_password = '') {
  6         31  
  6         27  
  6         20  
  6         18  
129 6         47 my $form = $t->fill_in_login_form($login_name, $login_password);
130 6         217 my $body
131             = $t->post_ok($t->app->url_for('sign_in') => {} => form => $form)->tx->res->body;
132 6         30345 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 165512 sub meta_names_ok ($t) {
  2         6  
  2         5  
171 2         8 for (qw(author description keywords generator viewport )) {
172 10         3933 my $selector = qq'head meta[name="$_"]';
173 10         43 $t->element_exists($selector, $selector . ' exists')
174             ->attr_like($selector => 'content', qr/.+/ => $selector . ' has content');
175             }
176              
177             # OpenGraph
178 2         964 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         8719 my $selector = qq'head meta[property="$_"]';
182 20         124 $t->element_exists($selector, $selector . ' exists')
183             ->attr_like($selector => 'content', qr/.+/ => $selector . ' has content');
184              
185             }
186 2         1235 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 37 my $class = 'Slovo';
193 12         100 my $symtab = $class . '::';
194             {
195 13     13   25040 no strict 'refs'; # we're fiddling with the symbol table
  13         40  
  13         3517  
  12         35  
196 12         30 @{$class . '::ISA'} = ();
  12         423  
197              
198             # Delete all symbols except other namespaces
199 12         294 for my $symbol (keys %$symtab) {
200 363 100       935 next if $symbol =~ /\A[^:]+::\z/;
201 324         4893 delete $symtab->{$symbol};
202             }
203             }
204              
205 12         181 my $inc_file = join('/', split /(?:'|::)/, $class) . '.pm';
206 12         53 delete $INC{$inc_file};
207              
208 12         38 return 1;
209             }
210             1;