root/branches/release-41/t/61-to_from_xml.t @ 2730

Revision 2730, 11.8 kB (checked in by fumiakiy, 17 months ago)

Unit test update - more strict checking of columns of MT::Trackback, MT::Folder and MT::Category.

Changed the order of the backup so the triggers won't affect the restored objects.

Line 
1#!/usr/bin/perl
2# $Id:$
3use strict;
4use warnings;
5
6use lib 't/lib', 'extlib', 'lib', '../lib', '../extlib';
7use Test::More qw(no_plan);#tests => 3598;
8
9use MT;
10use MT::Tag;
11use MT::Author;
12use MT::Blog;
13use MT::Role;
14use MT::Category;
15use MT::Entry;
16use MT::TBPing;
17use MT::Comment;
18use MT::Test qw(:db :data);
19
20use vars qw( $DB_DIR $T_CFG );
21
22use MT::BackupRestore;
23use Data::Dumper;
24
25system("rm t/db/* 2>null");
26
27my @emails = ( 'fumiakiy@sixapart.jp', 'fyoshimatsu@sixapart.com' );
28my $chuck = MT::Author->load({ name => 'Chuck D' });
29my $bob = MT::Author->load({ name => 'Bob D' });
30my $mel = MT::Author->load({ name => 'Melody' });
31&setup;
32
33my $mt = MT->new( Config => $T_CFG ) or die MT->errstr;
34isa_ok($mt, 'MT');
35
36my $backup_data = '';
37my $printer = sub { $backup_data .= $_[0] };
38
39my %skip = (
40    'session' => 1,
41    'config'  => 1,
42    'schwartz_job' => 1,
43    'schwartz_error' => 1,
44    'schwartz_funcmap' => 1,
45    'schwartz_exitstatus' => 1,
46);
47my %oldies;
48my $types = MT->registry('object_types');
49foreach my $key (keys %$types) {
50    next if exists $skip{$key};
51    next if $key =~ /\w+\.\w+/; # skip subclasses
52    my $iter = MT->model($key)->load_iter;
53    my @data;
54    while ( my $obj = $iter->() ) {
55        push @data, $obj unless $obj->can('class') && ($obj->class ne $key);
56    }
57    $oldies{$key} = \@data;
58}
59
60my @tsnow    = gmtime(time);
61my $metadata = {
62    backup_by => $chuck->name . '(ID: ' . $chuck->id . ')',
63    backup_on => sprintf(
64        "%04d-%02d-%02dT%02d:%02d:%02d",
65        $tsnow[5] + 1900,
66        $tsnow[4] + 1,
67        @tsnow[ 3, 2, 1, 0 ]
68    ),
69    #backup_what    => join( ',', @blog_ids ),
70    schema_version => MT->config->SchemaVersion,
71};
72
73MT::BackupRestore->backup(
74    undef, # no blog_ids
75    $printer, sub {}, sub {}, sub { print $_[0], "\n"; },
76    0, 'UTF-8',
77    $metadata
78);
79
80use IO::String;
81my $h = IO::String->new(\$backup_data);
82my (%objects, %deferred, @errors);
83MT::BackupRestore->restore_process_single_file(
84    $h,
85    \%objects,
86    \%deferred,
87    \@errors,
88    MT->config->SchemaVersion,
89    0,
90    sub { print $_[0], "\n"; }
91);
92
93is(scalar(keys %deferred), 0, 'no deferred objects remain');
94warn join "\n", @errors if @errors;
95is(scalar(@errors), 0, 'no error during backup');
96&checkthemout(\%oldies, \%objects);
97
98&finish;
99require MIME::Base64;
100
101sub checkthemout {
102    my ($oldies, $objects) = @_;
103    foreach my $name (keys %$oldies) {
104        my $old_objects = $oldies->{$name};
105        my %meta;
106        for my $old (@$old_objects) {
107            my $class = MT->model($name);
108            isnt($class, undef, "$name must be valid");
109            if ($class =~ /MT::Asset(::.+)*/) {
110                $class = 'MT::Asset';
111            }
112            my $key = "$class#" . $old->id;
113            my $tmp_obj = $objects->{$key};
114            isnt(undef, $tmp_obj, "$key must not hold undef");
115            my $obj = $class->load($tmp_obj->id, {cached_ok=>0});
116            isnt($obj, undef);
117            for my $col (@{$obj->column_names}) {
118                next if $col eq 'id';
119                if ($col =~ /(\w+)_id$/) {
120                    my $parent_name = $1;
121                    my $parent_class = MT->model($parent_name);
122                    next if !defined($parent_class);
123                    if ('ARRAY' ne ref($parent_class)) {
124                        $parent_class = [ $parent_class ];
125                    }
126                    my $old_parent_id = $old->column($col);
127                    next if !defined($old_parent_id); # like MT::Entry's category_id...
128                    next if $old_parent_id eq '0'; # like MT::Trackback's category_id...
129                    my $parent;
130                    foreach (@$parent_class) {
131                        my $parent_key = $_ . '#' . $old_parent_id;
132                        my $new_parent = $objects->{$parent_key};
133                        next unless $new_parent;
134                        $parent = $_->load($new_parent->id);
135                        last if $parent;
136                    }
137                    unless ($parent) {
138                        # try the other way to find package name for the parents
139                        my $parents_hash = $class->parents;
140                        $parent_class = $parents_hash->{$col} if $parents_hash;
141                        if ( ref($parent_class) eq 'HASH' ) {
142                            $parent_class = $parent_class->{class};
143                        }
144                        if ( !$parent_class && ($col eq 'entry_id') && ('MT::Trackback' eq $class) ) {
145                            $parent_class = [ MT->model('entry'), MT->model('page') ];
146                        }
147                        if ( $parent_class && ( 'ARRAY' eq ref($parent_class) ) ) {
148                            foreach (@$parent_class) {
149                                my $parent_key = $_ . '#' . $old_parent_id;
150                                my $new_parent = $objects->{$parent_key};
151                                next unless $new_parent;
152                                $parent = $_->load($new_parent->id);
153                                last if $parent;
154                            }
155                        }
156                    }
157                    isnt(undef, $parent, "parent object(" . $old->id . ") of $class pointed to by $col should not be undef");
158                } else {
159                    next if (
160                        (defined($old->column($col)) && ($old->column($col) eq '')) &&
161                        (!defined($obj->column($col)))
162                    );
163                    if ($name eq 'category' && ($col eq 'parent') && $old->parent) {
164                        my $parent = $objects->{'MT::Category#' . $old->parent};
165                        is( $obj->$col, $parent->id, 'Category parent restored');
166                        next;
167                    }
168                    if ($name eq 'folder' && ($col eq 'parent') && $old->parent) {
169                        my $parent = $objects->{'MT::Folder#' . $old->parent};
170                        is( $obj->$col, $parent->id, 'Folder parent restored');
171                        next;
172                    }
173                    if ( ($name eq 'trackback') && ($col eq 'is_disabled') ) {
174                        if ( defined($obj->is_disabled) && $obj->is_disabled
175                          && (!defined($obj->entry->allow_pings) || ($obj->entry->allow_pings == 0)) )
176                        {
177                            # is_disabled will be changed upon $entry->save
178                            # and save may occur $comment's post_save trigger
179                            # no harm for the testing purpose, ignore the case.
180                            next;
181                        }
182                    }
183                    if ('HASH' eq ref($old->$col)) {
184                        is(Dumper($old->$col), Dumper($old->$col), $col);
185                    } elsif ('blob' eq $obj->column_defs->{$col}->{type}) {
186                        is(
187                            MIME::Base64::encode_base64($old->$col, ''),
188                            MIME::Base64::encode_base64($obj->$col, ''),
189                            "blob - $col");
190                    } else {
191                        is($old->$col, $obj->$col, "$class<$col>" . $obj->id);
192                    }
193                }
194            }
195            unless ( exists($meta{ref($obj)}) ) {
196                my @metacolumns = MT::Meta->metadata_by_class( ref($obj) );
197                my %metacolumns = map { $_->{name} => $_->{type} } @metacolumns;
198                $meta{ref($obj)} = \%metacolumns
199            }
200            my $metacolumns = $meta{ref($obj)};
201            foreach my $metacol (keys %$metacolumns) {
202                if ( my $type = $metacolumns->{$metacol} ) {
203                    if ( 'vblob' eq $type ) {
204                        if ( defined($old->$metacol) && defined($obj->$metacol) ) {
205                            is(
206                                MIME::Base64::encode_base64($old->$metacol, ''),
207                                MIME::Base64::encode_base64($obj->$metacol, ''),
208                                "vblob - $metacol");
209                        }
210                    }
211                    else {
212                        is($old->$metacol, $obj->$metacol, "$class<meta:$metacol>" . $obj->id);
213                    }
214                }
215            }
216        }
217    }
218}
219
220sub finish {
221    use MT::Notification;
222    MT::Notification->remove({email => $_}) foreach @emails;
223   
224    use MT::TBPing;
225    MT::TBPing->remove({tb_id=>2, blog_id=>1,id=>2});
226   
227    use MT::Role;
228    MT::Role->remove;
229   
230    use MT::Association;
231    MT::Association->remove;
232}
233       
234sub setup {
235    use MT::Notification;
236    my $note = MT::Notification->new;
237    $note->email($emails[0]);
238    $note->blog_id(1);
239    $note->save;
240    $note = undef;
241    my $note2 = MT::Notification->new;
242    $note2->email($emails[1]);
243    $note2->blog_id(1);
244    $note2->save;
245    $note2 = undef;
246
247    my $cat = MT::Category->load({ label => 'bar', blog_id => 1});
248    if ($cat) {
249        $cat->allow_pings(1);
250        $cat->save;
251    }
252   
253    require MT::TBPing;
254    my $ping = MT::TBPing->load(2);
255    if (!$ping) {
256        $ping = new MT::TBPing;
257        $ping->tb_id(2);
258        $ping->blog_id(1);
259        $ping->ip('127.0.0.1');
260        $ping->title('Cat Trackback');
261        $ping->excerpt('Foo Bar Baz Quux');
262        $ping->source_url('http://example.net/');
263        $ping->blog_name("Example Blog 2");
264        $ping->created_on('20050405000000');
265        $ping->id(2);
266        $ping->visible(1);
267        $ping->save
268    }
269
270    my @default_roles = (
271        # { name => 'System Administrator',
272        #   perms => ['administer'] },
273        # { name => 'System Designer',
274        #   perms => ['edit_templates', 'rebuild'] },
275        { name => 'Weblog Administrator',
276          description => 'Can administer the weblog.',
277          perms => ['administer_blog'] },
278        { name => 'Designer',
279          description => 'Can edit, manage and rebuild weblog templates.',
280          perms => ['edit_templates', 'rebuild'] },
281        { name => 'Editor',
282          description => 'Can edit all entries/categories/tags on a weblog and rebuild.',
283          perms => ['edit_all_posts', 'edit_categories', 'rebuild', 'edit_tags'], },
284        { name => 'Editor (can upload)',
285          description => 'Can upload files, edit all entries/categories/tags on a weblog and rebuild.',
286          perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'rebuild', 'upload'], },
287        { name => 'Publisher',
288          description => 'Can upload files, edit all entries/categories/tags on a weblog, rebuild and send notifications.',
289          perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'send_notifications', 'rebuild', 'upload'], },
290#        { name => 'Writer',
291#          description => 'Can create entries and edit their own.',
292#          perms => ['post'], },
293#        { name => 'Writer (can upload)',
294#          description => 'Can create entries, edit their own and upload files.',
295#          perms => ['post', 'upload'], },
296        # { name => 'System Blog Administrator',
297        #   perms => ['administer_blog'] },
298    );
299
300    require MT::Role;
301    foreach my $r (@default_roles) {
302        my $role = MT::Role->new();
303        $role->name(MT->translate($r->{name}));
304        $role->description(MT->translate($r->{description}));
305        $role->clear_full_permissions;
306        $role->set_these_permissions($r->{perms});
307        if ($r->{name} =~ m/^System/) {
308            $role->is_system(1);
309        }
310        $role->save;
311    }
312
313    require MT::Association;
314    my $b1 = MT::Blog->load(1);
315    my $r = MT::Role->load({ name => 'Weblog Administrator' });
316    MT::Association->link($chuck => $r => $b1); # Chuck is a weblog admin
317
318    my $r2 = MT::Role->load({ name => 'Publisher' });
319    MT::Association->link($bob => $r2 => $b1); # Bob is a publisher
320
321    my $r3 = MT::Role->load({ name => 'Writer' });
322    MT::Association->link($mel => $r3 => $b1); # Melody is a writer
323}
Note: See TracBrowser for help on using the browser.