root/branches/release-38/t/61-to_from_xml.t @ 2252

Revision 2252, 10.9 kB (checked in by fumiakiy, 19 months ago)

Skip system level custom fields in restoring if fields with the same basename is already in there. BugId:79351

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
60MT::BackupRestore->backup(undef, $printer, sub {}, sub {}, sub { print $_[0], "\n"; }, 0, 'UTF-8');
61
62use IO::String;
63my $h = IO::String->new(\$backup_data);
64my (%objects, %deferred, @errors);
65MT::BackupRestore->restore_process_single_file($h, \%objects, \%deferred, \@errors, "4.0", 0, sub { print $_[0], "\n"; });
66
67is(scalar(keys %deferred), 0, 'no deferred objects remain');
68warn join "\n", @errors if @errors;
69is(scalar(@errors), 0, 'no error during backup');
70&checkthemout(\%oldies, \%objects);
71
72&finish;
73require MIME::Base64;
74
75sub checkthemout {
76    my ($oldies, $objects) = @_;
77    foreach my $name (keys %$oldies) {
78        my $old_objects = $oldies->{$name};
79        my %meta;
80        for my $old (@$old_objects) {
81            my $class = MT->model($name);
82            isnt($class, undef, "$name must be valid");
83            if ($class =~ /MT::Asset(::.+)*/) {
84                $class = 'MT::Asset';
85            }
86            my $key = "$class#" . $old->id;
87            my $tmp_obj = $objects->{$key};
88            isnt(undef, $tmp_obj, "$key must not hold undef");
89            my $obj = $class->load($tmp_obj->id, {cached_ok=>0});
90            isnt($obj, undef);
91            for my $col (@{$obj->column_names}) {
92                next if $col eq 'id';
93                if ($col =~ /(\w+)_id$/) {
94                    my $parent_name = $1;
95                    my $parent_class = MT->model($parent_name);
96                    next if !defined($parent_class);
97                    if ('ARRAY' ne ref($parent_class)) {
98                        $parent_class = [ $parent_class ];
99                    }
100                    my $old_parent_id = $old->column($col);
101                    next if !defined($old_parent_id); # like MT::Entry's category_id...
102                    next if $old_parent_id eq '0'; # like MT::Trackback's category_id...
103                    my $parent;
104                    foreach (@$parent_class) {
105                        my $parent_key = $_ . '#' . $old_parent_id;
106                        my $new_parent = $objects->{$parent_key};
107                        next unless $new_parent;
108                        $parent = $_->load($new_parent->id);
109                        last if $parent;
110                    }
111                    unless ($parent) {
112                        # try the other way to find package name for the parents
113                        my $parents_hash = $class->parents;
114                        $parent_class = $parents_hash->{$col} if $parents_hash;
115                        if ( ref($parent_class) eq 'HASH' ) {
116                            $parent_class = $parent_class->{class};
117                        }
118                        if ( !$parent_class && ($col eq 'entry_id') && ('MT::Trackback' eq $class) ) {
119                            $parent_class = [ MT->model('entry'), MT->model('page') ];
120                        }
121                        if ( $parent_class && ( 'ARRAY' eq ref($parent_class) ) ) {
122                            foreach (@$parent_class) {
123                                my $parent_key = $_ . '#' . $old_parent_id;
124                                my $new_parent = $objects->{$parent_key};
125                                next unless $new_parent;
126                                $parent = $_->load($new_parent->id);
127                                last if $parent;
128                            }
129                        }
130                    }
131                    isnt(undef, $parent, "parent object(" . $old->id . ") of $class pointed to by $col should not be undef");
132                } else {
133                    next if $col eq 'modified_on';
134                    next if (
135                        (defined($old->column($col)) && ($old->column($col) eq '')) &&
136                        (!defined($obj->column($col)))
137                    );
138                    next if ($name eq 'category' && ($col eq 'parent'));
139                    next if ($name eq 'folder' && ($col eq 'parent'));
140                    if ( ($name eq 'trackback') && ($col eq 'is_disabled') ) {
141                        if ( defined($obj->is_disabled) && $obj->is_disabled
142                          && (!defined($obj->entry->allow_pings) || ($obj->entry->allow_pings == 0)) )
143                        {
144                            # is_disabled will be changed upon $entry->save
145                            # and save may occur $comment's post_save trigger
146                            # no harm for the testing purpose, ignore the case.
147                            next;
148                        }
149                    }
150                    if ('HASH' eq ref($old->$col)) {
151                        is(Dumper($old->$col), Dumper($old->$col), $col);
152                    } elsif ('blob' eq $obj->column_defs->{$col}->{type}) {
153                        is(
154                            MIME::Base64::encode_base64($old->$col, ''),
155                            MIME::Base64::encode_base64($obj->$col, ''),
156                            "blob - $col");
157                    } else {
158                        is($old->$col, $obj->$col, "$class<$col>" . $obj->id);
159                    }
160                }
161            }
162            unless ( exists($meta{ref($obj)}) ) {
163                my @metacolumns = MT::Meta->metadata_by_class( ref($obj) );
164                my %metacolumns = map { $_->{name} => $_->{type} } @metacolumns;
165                $meta{ref($obj)} = \%metacolumns
166            }
167            my $metacolumns = $meta{ref($obj)};
168            foreach my $metacol (keys %$metacolumns) {
169                if ( my $type = $metacolumns->{$metacol} ) {
170                    if ( 'vblob' eq $type ) {
171                        if ( defined($old->$metacol) && defined($obj->$metacol) ) {
172                            is(
173                                MIME::Base64::encode_base64($old->$metacol, ''),
174                                MIME::Base64::encode_base64($obj->$metacol, ''),
175                                "vblob - $metacol");
176                        }
177                    }
178                    else {
179                        is($old->$metacol, $obj->$metacol, "$class<meta:$metacol>" . $obj->id);
180                    }
181                }
182            }
183        }
184    }
185}
186
187sub finish {
188    use MT::Notification;
189    MT::Notification->remove({email => $_}) foreach @emails;
190   
191    use MT::TBPing;
192    MT::TBPing->remove({tb_id=>2, blog_id=>1,id=>2});
193   
194    use MT::Role;
195    MT::Role->remove;
196   
197    use MT::Association;
198    MT::Association->remove;
199}
200       
201sub setup {
202    use MT::Notification;
203    my $note = MT::Notification->new;
204    $note->email($emails[0]);
205    $note->blog_id(1);
206    $note->save;
207    $note = undef;
208    my $note2 = MT::Notification->new;
209    $note2->email($emails[1]);
210    $note2->blog_id(1);
211    $note2->save;
212    $note2 = undef;
213
214    my $cat = MT::Category->load({ label => 'bar', blog_id => 1});
215    if ($cat) {
216        $cat->allow_pings(1);
217        $cat->save;
218    }
219   
220    require MT::TBPing;
221    my $ping = MT::TBPing->load(2);
222    if (!$ping) {
223        $ping = new MT::TBPing;
224        $ping->tb_id(2);
225        $ping->blog_id(1);
226        $ping->ip('127.0.0.1');
227        $ping->title('Cat Trackback');
228        $ping->excerpt('Foo Bar Baz Quux');
229        $ping->source_url('http://example.net/');
230        $ping->blog_name("Example Blog 2");
231        $ping->created_on('20050405000000');
232        $ping->id(2);
233        $ping->visible(1);
234        $ping->save
235    }
236
237    my @default_roles = (
238        # { name => 'System Administrator',
239        #   perms => ['administer'] },
240        # { name => 'System Designer',
241        #   perms => ['edit_templates', 'rebuild'] },
242        { name => 'Weblog Administrator',
243          description => 'Can administer the weblog.',
244          perms => ['administer_blog'] },
245        { name => 'Designer',
246          description => 'Can edit, manage and rebuild weblog templates.',
247          perms => ['edit_templates', 'rebuild'] },
248        { name => 'Editor',
249          description => 'Can edit all entries/categories/tags on a weblog and rebuild.',
250          perms => ['edit_all_posts', 'edit_categories', 'rebuild', 'edit_tags'], },
251        { name => 'Editor (can upload)',
252          description => 'Can upload files, edit all entries/categories/tags on a weblog and rebuild.',
253          perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'rebuild', 'upload'], },
254        { name => 'Publisher',
255          description => 'Can upload files, edit all entries/categories/tags on a weblog, rebuild and send notifications.',
256          perms => ['edit_all_posts', 'edit_categories', 'edit_tags', 'send_notifications', 'rebuild', 'upload'], },
257#        { name => 'Writer',
258#          description => 'Can create entries and edit their own.',
259#          perms => ['post'], },
260#        { name => 'Writer (can upload)',
261#          description => 'Can create entries, edit their own and upload files.',
262#          perms => ['post', 'upload'], },
263        # { name => 'System Blog Administrator',
264        #   perms => ['administer_blog'] },
265    );
266
267    require MT::Role;
268    foreach my $r (@default_roles) {
269        my $role = MT::Role->new();
270        $role->name(MT->translate($r->{name}));
271        $role->description(MT->translate($r->{description}));
272        $role->clear_full_permissions;
273        $role->set_these_permissions($r->{perms});
274        if ($r->{name} =~ m/^System/) {
275            $role->is_system(1);
276        }
277        $role->save;
278    }
279
280    require MT::Association;
281    my $b1 = MT::Blog->load(1);
282    my $r = MT::Role->load({ name => 'Weblog Administrator' });
283    MT::Association->link($chuck => $r => $b1); # Chuck is a weblog admin
284
285    my $r2 = MT::Role->load({ name => 'Publisher' });
286    MT::Association->link($bob => $r2 => $b1); # Bob is a publisher
287
288    my $r3 = MT::Role->load({ name => 'Writer' });
289    MT::Association->link($mel => $r3 => $b1); # Melody is a writer
290}
Note: See TracBrowser for help on using the browser.