| 1 | #!/usr/bin/perl |
|---|
| 2 | # $Id:$ |
|---|
| 3 | use strict; |
|---|
| 4 | use warnings; |
|---|
| 5 | |
|---|
| 6 | use lib 't/lib', 'extlib', 'lib', '../lib', '../extlib'; |
|---|
| 7 | use Test::More tests => 3598; |
|---|
| 8 | |
|---|
| 9 | use MT; |
|---|
| 10 | use MT::Tag; |
|---|
| 11 | use MT::Author; |
|---|
| 12 | use MT::Blog; |
|---|
| 13 | use MT::Role; |
|---|
| 14 | use MT::Category; |
|---|
| 15 | use MT::Entry; |
|---|
| 16 | use MT::TBPing; |
|---|
| 17 | use MT::Comment; |
|---|
| 18 | use MT::Test qw(:db :data); |
|---|
| 19 | |
|---|
| 20 | use vars qw( $DB_DIR $T_CFG ); |
|---|
| 21 | |
|---|
| 22 | use MT::BackupRestore; |
|---|
| 23 | use Data::Dumper; |
|---|
| 24 | |
|---|
| 25 | system("rm t/db/* 2>null"); |
|---|
| 26 | |
|---|
| 27 | my @emails = ( 'fumiakiy@sixapart.jp', 'fyoshimatsu@sixapart.com' ); |
|---|
| 28 | my $chuck = MT::Author->load({ name => 'Chuck D' }); |
|---|
| 29 | my $bob = MT::Author->load({ name => 'Bob D' }); |
|---|
| 30 | my $mel = MT::Author->load({ name => 'Melody' }); |
|---|
| 31 | &setup; |
|---|
| 32 | |
|---|
| 33 | my $mt = MT->new( Config => $T_CFG ) or die MT->errstr; |
|---|
| 34 | isa_ok($mt, 'MT'); |
|---|
| 35 | |
|---|
| 36 | my $backup_data = ''; |
|---|
| 37 | my $printer = sub { $backup_data .= $_[0] }; |
|---|
| 38 | |
|---|
| 39 | my %skip = ( |
|---|
| 40 | 'session' => 1, |
|---|
| 41 | 'config' => 1, |
|---|
| 42 | 'schwartz_job' => 1, |
|---|
| 43 | 'schwartz_error' => 1, |
|---|
| 44 | 'schwartz_funcmap' => 1, |
|---|
| 45 | 'schwartz_exitstatus' => 1, |
|---|
| 46 | ); |
|---|
| 47 | my %oldies; |
|---|
| 48 | my $types = MT->registry('object_types'); |
|---|
| 49 | foreach my $key (keys %$types) { |
|---|
| 50 | next if exists $skip{$key}; |
|---|
| 51 | my @data = MT->model($key)->load; |
|---|
| 52 | $oldies{$key} = \@data; |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | MT::BackupRestore->backup(undef, $printer, sub {}, sub {}, sub { print $_[0], "\n"; }, 0, 'UTF-8'); |
|---|
| 56 | |
|---|
| 57 | use IO::String; |
|---|
| 58 | my $h = IO::String->new(\$backup_data); |
|---|
| 59 | my (%objects, %deferred, @errors); |
|---|
| 60 | MT::BackupRestore->restore_process_single_file($h, \%objects, \%deferred, \@errors, "4.0", 0, sub { print $_[0], "\n"; }); |
|---|
| 61 | |
|---|
| 62 | is(scalar(keys %deferred), 0); |
|---|
| 63 | print join "\n", @errors; |
|---|
| 64 | is(scalar(@errors), 0, 'no error during backup'); |
|---|
| 65 | |
|---|
| 66 | &checkthemout(\%oldies, \%objects); |
|---|
| 67 | |
|---|
| 68 | &finish; |
|---|
| 69 | require MIME::Base64; |
|---|
| 70 | |
|---|
| 71 | sub checkthemout { |
|---|
| 72 | my ($oldies, $objects) = @_; |
|---|
| 73 | foreach my $name (keys %$oldies) { |
|---|
| 74 | my $old_objects = $oldies->{$name}; |
|---|
| 75 | for my $old (@$old_objects) { |
|---|
| 76 | my $class = MT->model($name); |
|---|
| 77 | isnt($class, undef, "$name must be valid"); |
|---|
| 78 | my $ds = $class->datasource; |
|---|
| 79 | my $root_class = MT->model($ds); |
|---|
| 80 | isnt($root_class, undef, "$ds must be valid"); |
|---|
| 81 | my $key = "$root_class#" . $old->id; |
|---|
| 82 | my $tmp_obj = $objects->{$key}; |
|---|
| 83 | isnt(undef, $tmp_obj, "$key must not hold undef"); |
|---|
| 84 | my $obj = $class->load($tmp_obj->id, {cached_ok=>0}); |
|---|
| 85 | isnt($obj, undef); |
|---|
| 86 | for my $col (@{$obj->column_names}) { |
|---|
| 87 | next if $col eq 'id'; |
|---|
| 88 | if ($col =~ /(\w+)_id$/) { |
|---|
| 89 | my $parent_name = $1; |
|---|
| 90 | my $parent_class = MT->model($parent_name); |
|---|
| 91 | next if !defined($parent_class); |
|---|
| 92 | if ('ARRAY' ne ref($parent_class)) { |
|---|
| 93 | $parent_class = [ $parent_class ]; |
|---|
| 94 | } |
|---|
| 95 | my $old_parent_id = $old->column($col); |
|---|
| 96 | next if !defined($old_parent_id); # like MT::Entry's category_id... |
|---|
| 97 | next if $old_parent_id eq '0'; # like MT::Trackback's category_id... |
|---|
| 98 | my $parent; |
|---|
| 99 | foreach (@$parent_class) { |
|---|
| 100 | my $parent_key = $_ . '#' . $old_parent_id; |
|---|
| 101 | my $new_parent = $objects->{$parent_key}; |
|---|
| 102 | next unless $new_parent; |
|---|
| 103 | $parent = $_->load($new_parent->id); |
|---|
| 104 | last if $parent; |
|---|
| 105 | } |
|---|
| 106 | isnt(undef, $parent); |
|---|
| 107 | } else { |
|---|
| 108 | next if $col eq 'modified_on'; |
|---|
| 109 | next if ( |
|---|
| 110 | (defined($old->column($col)) && ($old->column($col) eq '')) && |
|---|
| 111 | (!defined($obj->column($col))) |
|---|
| 112 | ); |
|---|
| 113 | next if ($ds eq 'category' && ($col eq 'parent')); |
|---|
| 114 | # MT::Trackback will always be created upon MT::Entry->save, |
|---|
| 115 | # and restore will just skip to restore <trackback> data, |
|---|
| 116 | # meaning trackback_created_on will not be restored but newly created. |
|---|
| 117 | next if ($name eq 'trackback' && ($col eq 'created_on')); |
|---|
| 118 | if ('HASH' eq ref($old->$col)) { |
|---|
| 119 | is(Dumper($old->$col), Dumper($old->$col), $col); |
|---|
| 120 | } elsif ('blob' eq $obj->column_defs->{$col}->{type}) { |
|---|
| 121 | is( |
|---|
| 122 | MIME::Base64::encode_base64($old->$col, ''), |
|---|
| 123 | MIME::Base64::encode_base64($obj->$col, ''), |
|---|
| 124 | "blob - $col"); |
|---|
| 125 | } else { |
|---|
| 126 | is($old->$col, $obj->$col, "$class<$col>" . $obj->id); |
|---|
| 127 | } |
|---|
| 128 | } |
|---|
| 129 | } |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | sub finish { |
|---|
| 135 | use MT::Notification; |
|---|
| 136 | MT::Notification->remove({email => $_}) foreach @emails; |
|---|
| 137 | |
|---|
| 138 | use MT::TBPing; |
|---|
| 139 | MT::TBPing->remove({tb_id=>2, blog_id=>1,id=>2}); |
|---|
| 140 | |
|---|
| 141 | use MT::Role; |
|---|
| 142 | MT::Role->remove; |
|---|
| 143 | |
|---|
| 144 | use MT::Association; |
|---|
| 145 | MT::Association->remove; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | sub setup { |
|---|
| 149 | use MT::Notification; |
|---|
| 150 | my $note = MT::Notification->new; |
|---|
| 151 | $note->email($emails[0]); |
|---|
| 152 | $note->blog_id(1); |
|---|
| 153 | $note->save; |
|---|
| 154 | $note = undef; |
|---|
| 155 | my $note2 = MT::Notification->new; |
|---|
| 156 | $note2->email($emails[1]); |
|---|
| 157 | $note2->blog_id(1); |
|---|
| 158 | $note2->save; |
|---|
| 159 | $note2 = undef; |
|---|
| 160 | |
|---|
| 161 | my $cat = MT::Category->load({ label => 'bar', blog_id => 1}); |
|---|
| 162 | if ($cat) { |
|---|
| 163 | $cat->allow_pings(1); |
|---|
| 164 | $cat->save; |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | require MT::TBPing; |
|---|
| 168 | my $ping = MT::TBPing->load(2); |
|---|
| 169 | if (!$ping) { |
|---|
| 170 | $ping = new MT::TBPing; |
|---|
| 171 | $ping->tb_id(2); |
|---|
| 172 | $ping->blog_id(1); |
|---|
| 173 | $ping->ip('127.0.0.1'); |
|---|
| 174 | $ping->title('Cat Trackback'); |
|---|
| 175 | $ping->excerpt('Foo Bar Baz Quux'); |
|---|
| 176 | $ping->source_url('http://example.net/'); |
|---|
| 177 | $ping->blog_name("Example Blog 2"); |
|---|
| 178 | $ping->created_on('20050405000000'); |
|---|
| 179 | $ping->id(2); |
|---|
| 180 | $ping->visible(1); |
|---|
| 181 | $ping->save |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | my @default_roles = ( |
|---|
| 185 | # { name => 'System Administrator', |
|---|
| 186 | # perms => ['administer'] }, |
|---|
| 187 | # { name => 'System Designer', |
|---|
| 188 | # perms => ['edit_templates', 'rebuild'] }, |
|---|
| 189 | { name => 'Weblog Administrator', |
|---|
| 190 | description => 'Can administer the weblog.', |
|---|
| 191 | perms => ['administer_blog'] }, |
|---|
| 192 | { name => 'Designer', |
|---|
| 193 | description => 'Can edit, manage and rebuild weblog templates.', |
|---|
| 194 | perms => ['edit_templates', 'rebuild'] }, |
|---|
| 195 | { name => 'Editor', |
|---|
| 196 | description => 'Can edit all entries/categories/tags on a weblog and rebuild.', |
|---|
| 197 | perms => ['edit_all_posts', 'edit_categories', 'rebuild', 'edit_tags'], }, |
|---|
| 198 | { name => 'Editor (can upload)', |
|---|
| 199 | description => 'Can upload files, edit all entries/categories/tags on a weblog and rebuild.', |
|---|
| 200 | perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'rebuild', 'upload'], }, |
|---|
| 201 | { name => 'Publisher', |
|---|
| 202 | description => 'Can upload files, edit all entries/categories/tags on a weblog, rebuild and send notifications.', |
|---|
| 203 | perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'send_notifications', 'rebuild', 'upload'], }, |
|---|
| 204 | # { name => 'Writer', |
|---|
| 205 | # description => 'Can create entries and edit their own.', |
|---|
| 206 | # perms => ['post'], }, |
|---|
| 207 | # { name => 'Writer (can upload)', |
|---|
| 208 | # description => 'Can create entries, edit their own and upload files.', |
|---|
| 209 | # perms => ['post', 'upload'], }, |
|---|
| 210 | # { name => 'System Blog Administrator', |
|---|
| 211 | # perms => ['administer_blog'] }, |
|---|
| 212 | ); |
|---|
| 213 | |
|---|
| 214 | require MT::Role; |
|---|
| 215 | foreach my $r (@default_roles) { |
|---|
| 216 | my $role = MT::Role->new(); |
|---|
| 217 | $role->name(MT->translate($r->{name})); |
|---|
| 218 | $role->description(MT->translate($r->{description})); |
|---|
| 219 | $role->clear_full_permissions; |
|---|
| 220 | $role->set_these_permissions($r->{perms}); |
|---|
| 221 | if ($r->{name} =~ m/^System/) { |
|---|
| 222 | $role->is_system(1); |
|---|
| 223 | } |
|---|
| 224 | $role->save; |
|---|
| 225 | } |
|---|
| 226 | |
|---|
| 227 | require MT::Association; |
|---|
| 228 | my $b1 = MT::Blog->load(1); |
|---|
| 229 | my $r = MT::Role->load({ name => 'Weblog Administrator' }); |
|---|
| 230 | MT::Association->link($chuck => $r => $b1); # Chuck is a weblog admin |
|---|
| 231 | |
|---|
| 232 | my $r2 = MT::Role->load({ name => 'Publisher' }); |
|---|
| 233 | MT::Association->link($bob => $r2 => $b1); # Bob is a publisher |
|---|
| 234 | |
|---|
| 235 | my $r3 = MT::Role->load({ name => 'Writer' }); |
|---|
| 236 | MT::Association->link($mel => $r3 => $b1); # Melody is a writer |
|---|
| 237 | } |
|---|