[Rt-commit] rt branch 5.0/shred-more-objects created. rt-5.0.3-226-g5b9a956a19

BPS Git Server git at git.bestpractical.com
Tue Jan 3 14:42:03 UTC 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/shred-more-objects has been created
        at  5b9a956a19969257771dd1debdb5efed32dbb670 (commit)

- Log -----------------------------------------------------------------
commit 5b9a956a19969257771dd1debdb5efed32dbb670
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jan 3 22:20:22 2023 +0800

    Test shredder for ObjectCustomRoles of queues

diff --git a/t/shredder/02queue.t b/t/shredder/02queue.t
index 9ab06c2c61..5b2f185403 100644
--- a/t/shredder/02queue.t
+++ b/t/shredder/02queue.t
@@ -100,9 +100,33 @@ diag 'queue with a right granted' if $ENV{TEST_VERBOSE};
 
 diag 'queue with a watcher' if $ENV{TEST_VERBOSE};
 {
+    my $ticket_custom_role = RT::CustomRole->new( RT->SystemUser );
+    my ( $id, $msg ) = $ticket_custom_role->Create(
+        Name       => 'ticket custom role',
+        Type       => 'Freeform',
+        LookupType => RT::Ticket->CustomFieldLookupType,
+    );
+    ok( $id, 'created asset custom role' ) or diag "error: $msg";
+
+    my $asset_custom_role = RT::CustomRole->new( RT->SystemUser );
+    ( $id, $msg ) = $asset_custom_role->Create(
+        Name       => 'asset custom role',
+        Type       => 'Freeform',
+        LookupType => RT::Asset->CustomFieldLookupType,
+    );
+    ok( $id, 'created asset custom role' ) or diag "error: $msg";
+
+    # By default there are 2 queues and 1 catalog created.  So we need
+    # to create 1 extra catalog to catch up the queue id.
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    ok( $catalog->Create( Name => "catalog $_" ), "created catalog $_" ) for 2 .. 3;
+    is( $catalog->id, 3, 'Loaded catalog with the same to-be-created queue id=3' );
+    ( $id, $msg ) = $asset_custom_role->AddToObject( $catalog->Id );
+    ok( $id, 'applied custom role to catalog' ) or diag "error: $msg";
+
     $test->create_savepoint('clean');
     my $group = RT::Group->new( RT->SystemUser );
-    my ($id, $msg) = $group->CreateUserDefinedGroup(Name => 'my group');
+    ($id, $msg) = $group->CreateUserDefinedGroup(Name => 'my group');
     ok($id, 'created group') or diag "error: $msg";
 
     $test->create_savepoint('bqcreate');
@@ -110,6 +134,9 @@ diag 'queue with a watcher' if $ENV{TEST_VERBOSE};
     ($id, $msg) = $queue->Create( Name => 'my queue' );
     ok($id, 'created queue') or diag "error: $msg";
 
+    ( $id, $msg ) = $ticket_custom_role->AddToObject( $queue->Id );
+    ok( $id, 'applied custom role to queue' ) or diag "error: $msg";
+
     ($id, $msg) = $queue->AddWatcher(
         Type   => 'Cc',
         PrincipalId => $group->id,

commit 7f9977c51d54068eee405305243930068b72eca4
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jan 3 21:48:56 2023 +0800

    Uncomment test code that works now
    
    The FIXME comment was 15 years ago, which is obsolete.

diff --git a/t/shredder/02queue.t b/t/shredder/02queue.t
index 08a1b61a68..9ab06c2c61 100644
--- a/t/shredder/02queue.t
+++ b/t/shredder/02queue.t
@@ -100,8 +100,7 @@ diag 'queue with a right granted' if $ENV{TEST_VERBOSE};
 
 diag 'queue with a watcher' if $ENV{TEST_VERBOSE};
 {
-# XXX, FIXME: if uncomment these lines then we'll get 'Bizarre...'
-#    $test->create_savepoint('clean');
+    $test->create_savepoint('clean');
     my $group = RT::Group->new( RT->SystemUser );
     my ($id, $msg) = $group->CreateUserDefinedGroup(Name => 'my group');
     ok($id, 'created group') or diag "error: $msg";
@@ -123,9 +122,9 @@ diag 'queue with a watcher' if $ENV{TEST_VERBOSE};
     $test->db_is_valid;
     cmp_deeply( $test->dump_current_and_savepoint('bqcreate'), "current DB equal to savepoint");
 
-#    $shredder->PutObjects( Objects => $group );
-#    $shredder->WipeoutAll;
-#    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint");
+    $shredder->PutObjects( Objects => $group );
+    $shredder->WipeoutAll;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint");
 }
 
 diag 'queue with custom fields' if $ENV{TEST_VERBOSE};

commit 7620d327e3d975bea52b2c480f24c8b969155e1e
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jan 3 21:46:39 2023 +0800

    Shred only ticket roles on shredding queues

diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 1f3af9c9d0..562be74858 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -1129,6 +1129,7 @@ sub __DependsOn {
 
 # Object Custom Roles
     $objs = RT::ObjectCustomRoles->new( $self->CurrentUser );
+    $objs->LimitToLookupType( RT::Ticket->CustomFieldLookupType );
     $objs->LimitToObjectId($self->Id);
     push( @$list, $objs );
 

commit f6c52dfbf15200bb4ce2b33229fd8ab1664a1f97
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jan 3 21:29:57 2023 +0800

    Test shredder for catalog/asset objects

diff --git a/lib/RT/Test/Shredder.pm b/lib/RT/Test/Shredder.pm
index d49f4fa9cd..028b5b86e3 100644
--- a/lib/RT/Test/Shredder.pm
+++ b/lib/RT/Test/Shredder.pm
@@ -275,7 +275,7 @@ sub dump_sqlite_exceptions {
     my $table = shift;
 
     my $special_wheres = {
-        attributes => " WHERE Name != 'QueueCacheNeedsUpdate'"
+        attributes => " WHERE Name NOT LIKE '%CacheNeedsUpdate'"
     };
 
     return $special_wheres->{lc $table}||'';
diff --git a/t/shredder/02asset.t b/t/shredder/02asset.t
new file mode 100644
index 0000000000..468025ad7f
--- /dev/null
+++ b/t/shredder/02asset.t
@@ -0,0 +1,56 @@
+use strict;
+use warnings;
+
+use Test::Deep;
+use RT::Test::Shredder tests => undef;
+my $test = "RT::Test::Shredder";
+
+my $catalog = RT::Catalog->new( RT->SystemUser );
+$catalog->Load('General assets');
+ok( $catalog->Id, 'loaded catalog General' );
+
+diag 'simple asset' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+
+    my $asset = RT::Asset->new( RT->SystemUser );
+    my ( $id, $msg ) = $asset->Create( Catalog => $catalog->Id, Name => 'test 1' );
+    ok( $id, 'created asset' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $asset );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'asset with custom fields' if $ENV{TEST_VERBOSE};
+{
+    my $cf = RT::CustomField->new( RT->SystemUser );
+    my ( $id, $msg ) = $cf->Create(
+        Name       => 'asset custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Asset->CustomFieldLookupType,
+        MaxValues  => 1,
+    );
+    ok( $id, 'created asset custom field' ) or diag "error: $msg";
+
+    # apply the custom fields to the catalog.
+    ( $id, $msg ) = $cf->AddToObject($catalog);
+    ok( $id, 'applied cf to catalog' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $asset = RT::Asset->new( RT->SystemUser );
+    ( $id, $msg ) = $asset->Create( Catalog => $catalog->Id, Name => 'test 1', 'CustomField-' . $cf->Id => 'test' );
+    ok( $id, 'created asset' ) or diag "error: $msg";
+    is( $asset->FirstCustomFieldValue('asset custom field'), 'test', 'asset cf is set' );
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $asset );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+done_testing;
diff --git a/t/shredder/02catalog.t b/t/shredder/02catalog.t
new file mode 100644
index 0000000000..2d219725db
--- /dev/null
+++ b/t/shredder/02catalog.t
@@ -0,0 +1,112 @@
+use strict;
+use warnings;
+
+use Test::Deep;
+
+use RT::Test::Shredder tests => undef;
+my $test = "RT::Test::Shredder";
+
+
+diag 'simple catalog' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    my ( $id, $msg ) = $catalog->Create( Name => 'my catalog' );
+    ok( $id, 'created catalog' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $catalog );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'catalog with a right granted' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    my ( $id, $msg ) = $catalog->Create( Name => 'my catalog' );
+    ok( $id, 'created catalog' ) or diag "error: $msg";
+
+    my $group = RT::Group->new( RT->SystemUser );
+    $group->LoadSystemInternalGroup('Everyone');
+    ok( $group->id, 'loaded group' );
+
+    ( $id, $msg ) = $group->PrincipalObj->GrantRight(
+        Right  => 'CreateAsset',
+        Object => $catalog,
+    );
+    ok( $id, 'granted right' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $catalog );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'catalog with a watcher' if $ENV{TEST_VERBOSE};
+{
+    my $group = RT::Group->new( RT->SystemUser );
+    my ( $id, $msg ) = $group->CreateUserDefinedGroup( Name => 'my group' );
+    ok( $id, 'created group' ) or diag "error: $msg";
+
+    $test->create_savepoint('bqcreate');
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    ( $id, $msg ) = $catalog->Create( Name => 'my catalog' );
+    ok( $id, 'created catalog' ) or diag "error: $msg";
+
+    ( $id, $msg ) = $catalog->AddRoleMember(
+        Type        => 'Contact',
+        PrincipalId => $group->id,
+    );
+    ok( $id, 'added watcher' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $catalog );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('bqcreate'), "current DB equal to savepoint" );
+}
+
+diag 'catalog with custom fields' if $ENV{TEST_VERBOSE};
+{
+    my $asset_custom_field = RT::CustomField->new( RT->SystemUser );
+    my ( $id, $msg ) = $asset_custom_field->Create(
+        Name       => 'asset custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Asset->CustomFieldLookupType,
+        MaxValues  => 1,
+    );
+    ok( $id, 'created asset custom field' ) or diag "error: $msg";
+
+    my $catalog_custom_field = RT::CustomField->new( RT->SystemUser );
+    ( $id, $msg ) = $catalog_custom_field->Create(
+        Name       => 'catalog custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Catalog->CustomFieldLookupType,
+        MaxValues  => '1',
+    );
+    ok( $id, 'created catalog custom field' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    ( $id, $msg ) = $catalog->Create( Name => 'my catalog' );
+    ok( $id, 'created catalog' ) or diag "error: $msg";
+
+    # apply the custom fields to the catalog.
+    ( $id, $msg ) = $asset_custom_field->AddToObject($catalog);
+    ok( $id, 'applied asset cf to catalog' ) or diag "error: $msg";
+
+    ( $id, $msg ) = $catalog_custom_field->AddToObject($catalog);
+    ok( $id, 'applied catalog cf to catalog' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $catalog );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+done_testing;

commit 29aa4636c2ababf5d209bc4b0ce607780db8db14
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Jan 3 21:08:34 2023 +0800

    Support to shred catalog/asset objects

diff --git a/lib/RT/Asset.pm b/lib/RT/Asset.pm
index c29e58f67d..f513613264 100644
--- a/lib/RT/Asset.pm
+++ b/lib/RT/Asset.pm
@@ -731,6 +731,32 @@ sub CategoryObj {
     return $self->CatalogObj;
 }
 
+sub __DependsOn {
+    my $self = shift;
+    my %args = (
+        Shredder     => undef,
+        Dependencies => undef,
+        @_,
+    );
+    my $deps = $args{'Dependencies'};
+    my $list = [];
+
+    # Asset role groups
+    my $objs = RT::Groups->new( $self->CurrentUser );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Asset-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
+    push( @$list, $objs );
+
+    $deps->_PushDependencies(
+        BaseObject    => $self,
+        Flags         => RT::Shredder::Constants::DEPENDS_ON,
+        TargetObjects => $list,
+        Shredder      => $args{'Shredder'}
+    );
+
+    return $self->SUPER::__DependsOn(%args);
+}
+
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/Catalog.pm b/lib/RT/Catalog.pm
index 415042330d..dd1149e9c7 100644
--- a/lib/RT/Catalog.pm
+++ b/lib/RT/Catalog.pm
@@ -552,6 +552,49 @@ sub PreInflate {
     return 1;
 }
 
+sub __DependsOn {
+    my $self = shift;
+    my %args = (
+        Shredder     => undef,
+        Dependencies => undef,
+        @_,
+    );
+    my $deps = $args{'Dependencies'};
+    my $list = [];
+
+    # Assets
+    my $objs = RT::Assets->new( $self->CurrentUser );
+    $objs->{'allow_deleted_search'} = 1;
+    $objs->Limit( FIELD => 'Catalog', VALUE => $self->Id );
+    push( @$list, $objs );
+
+    # Catalog role groups
+    $objs = RT::Groups->new( $self->CurrentUser );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Catalog-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
+    push( @$list, $objs );
+
+    # Object Custom Fields
+    $objs = RT::ObjectCustomFields->new( $self->CurrentUser );
+    $objs->LimitToLookupType( $_->CustomFieldLookupType ) for qw/RT::Catalog RT::Asset/;
+    $objs->LimitToObjectId( $self->id );
+    push( @$list, $objs );
+
+    # Object Custom Roles
+    $objs = RT::ObjectCustomRoles->new( $self->CurrentUser );
+    $objs->LimitToLookupType( RT::Asset->CustomFieldLookupType );
+    $objs->LimitToObjectId( $self->Id );
+    push( @$list, $objs );
+
+    $deps->_PushDependencies(
+        BaseObject    => $self,
+        Flags         => RT::Shredder::Constants::DEPENDS_ON,
+        TargetObjects => $list,
+        Shredder      => $args{'Shredder'}
+    );
+    return $self->SUPER::__DependsOn(%args);
+}
+
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/Shredder.pm b/lib/RT/Shredder.pm
index 54989df0dc..241f618177 100644
--- a/lib/RT/Shredder.pm
+++ b/lib/RT/Shredder.pm
@@ -255,6 +255,8 @@ our @SUPPORTED_OBJECTS = qw(
     Class
     Article
     Topic
+    Catalog
+    Asset
 );
 
 =head3 GENERIC

commit a8f1e196a0cc45b481471ac97dafc041accf53ec
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Dec 30 05:42:12 2022 +0800

    Test shredder for class/topic/article objects

diff --git a/t/shredder/02article.t b/t/shredder/02article.t
new file mode 100644
index 0000000000..dc1f9a110d
--- /dev/null
+++ b/t/shredder/02article.t
@@ -0,0 +1,76 @@
+use strict;
+use warnings;
+
+use Test::Deep;
+use RT::Test::Shredder tests => undef;
+my $test = "RT::Test::Shredder";
+
+my $class = RT::Class->new( RT->SystemUser );
+$class->Load('General');
+ok( $class->Id, 'loaded class General' );
+
+diag 'simple article' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+
+    my $article = RT::Article->new( RT->SystemUser );
+    my ( $id, $msg ) = $article->Create( Class => $class->Id, Name => 'test 1' );
+    ok( $id, 'created article' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $article );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'article with custom fields' if $ENV{TEST_VERBOSE};
+{
+    my $cf = RT::CustomField->new( RT->SystemUser );
+    my ( $id, $msg ) = $cf->Create(
+        Name       => 'article custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Article->CustomFieldLookupType,
+        MaxValues  => 1,
+    );
+    ok( $id, 'created article custom field' ) or diag "error: $msg";
+
+    # apply the custom fields to the class.
+    ( $id, $msg ) = $cf->AddToObject($class);
+    ok( $id, 'applied cf to class' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $article = RT::Article->new( RT->SystemUser );
+    ( $id, $msg ) = $article->Create( Class => $class->Id, Name => 'test 1', 'CustomField-' . $cf->Id => 'test' );
+    ok( $id, 'created article' ) or diag "error: $msg";
+    is( $article->FirstCustomFieldValue('article custom field'), 'test', 'article cf is set' );
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $article );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'article with topics' if $ENV{TEST_VERBOSE};
+{
+    my $topic = RT::Topic->new( RT->SystemUser );
+    my ( $id, $msg ) = $topic->Create( ObjectType => 'RT::Class', ObjectId => $class->Id );
+    ok( $id, 'created topic' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $article = RT::Article->new( RT->SystemUser );
+    ( $id, $msg ) = $article->Create( Class => $class->Id, Name => 'test 1', 'Topics' => [ $topic->Id ] );
+    ok( $id, 'created article' ) or diag "error: $msg";
+    is( $article->Topics->First->Id, $topic->Id, 'article topic is set' );
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $article );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+done_testing;
diff --git a/t/shredder/02class.t b/t/shredder/02class.t
new file mode 100644
index 0000000000..1217869c42
--- /dev/null
+++ b/t/shredder/02class.t
@@ -0,0 +1,148 @@
+use strict;
+use warnings;
+
+use Test::Deep;
+use RT::Test::Shredder tests => undef;
+my $test = "RT::Test::Shredder";
+
+diag 'simple class' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+    my $class = RT::Class->new( RT->SystemUser );
+    my ( $id, $msg ) = $class->Create( Name => 'my class' );
+    ok( $id, 'created class' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $class );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'class with a right granted' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+    my $class = RT::Class->new( RT->SystemUser );
+    my ( $id, $msg ) = $class->Create( Name => 'my class' );
+    ok( $id, 'created class' ) or diag "error: $msg";
+
+    my $group = RT::Group->new( RT->SystemUser );
+    $group->LoadSystemInternalGroup('Everyone');
+    ok( $group->id, 'loaded group' );
+
+    ( $id, $msg ) = $group->PrincipalObj->GrantRight(
+        Right  => 'CreateArticle',
+        Object => $class,
+    );
+    ok( $id, 'granted right' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $class );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'class with custom fields' if $ENV{TEST_VERBOSE};
+{
+    my $class_custom_field = RT::CustomField->new( RT->SystemUser );
+    my ( $id, $msg ) = $class_custom_field->Create(
+        Name       => 'class custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Class->CustomFieldLookupType,
+        MaxValues  => 1,
+    );
+    ok( $id, 'created class custom field' ) or diag "error: $msg";
+
+    my $article_custom_field = RT::CustomField->new( RT->SystemUser );
+    ( $id, $msg ) = $article_custom_field->Create(
+        Name       => 'article custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Article->CustomFieldLookupType,
+        MaxValues  => 1,
+    );
+    ok( $id, 'created article custom field' ) or diag "error: $msg";
+
+    # Create an ObjectCustomField for assets with the same ObjectId, to make sure it's not shredded.
+    my $asset_custom_field = RT::CustomField->new( RT->SystemUser );
+    ( $id, $msg ) = $asset_custom_field->Create(
+        Name       => 'asset custom field',
+        Type       => 'Freeform',
+        LookupType => RT::Asset->CustomFieldLookupType,
+        MaxValues  => '1',
+    );
+    ok( $id, 'created asset custom field' ) or diag "error: $msg";
+
+    my $catalog = RT::Catalog->new( RT->SystemUser );
+    ok( $catalog->Create( Name => "catalog 2" ), "created catalog 2" );
+    ( $id, $msg ) = $asset_custom_field->AddToObject($catalog);
+    ok( $id, 'applied asset cf to catalog' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $class = RT::Class->new( RT->SystemUser );
+    ( $id, $msg ) = $class->Create( Name => 'my class' );
+    ok( $id, 'created class' ) or diag "error: $msg";
+
+    # apply the custom fields to the class.
+    ( $id, $msg ) = $class_custom_field->AddToObject($class);
+    ok( $id, 'applied class cf to class' ) or diag "error: $msg";
+
+    # apply the custom fields to the class.
+    ( $id, $msg ) = $article_custom_field->AddToObject($class);
+    ok( $id, 'applied article cf to class' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $class );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'class with articles' if $ENV{TEST_VERBOSE};
+{
+
+    my $article = RT::Article->new( RT->SystemUser );
+    my ( $id, $msg ) = $article->Create( Class => 'General', Name => 'test 1' );
+    ok( $id, 'created article' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $class = RT::Class->new( RT->SystemUser );
+    ( $id, $msg ) = $class->Create( Name => 'my class' );
+    ok( $id, 'created class' ) or diag "error: $msg";
+
+    ( $id, $msg ) = $article->Create( Class => $class->Id, Name => 'test 2' );
+    ok( $id, 'created article' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $class );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+
+diag 'class with topics' if $ENV{TEST_VERBOSE};
+{
+    my $topic = RT::Topic->new( RT->SystemUser );
+    my ( $id, $msg ) = $topic->Create( ObjectType => 'RT::Class', ObjectId => 0 );
+    ok( $id, 'created topic' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $class = RT::Class->new( RT->SystemUser );
+    ( $id, $msg ) = $class->Create( Name => 'my class' );
+    ok( $id, 'created class' ) or diag "error: $msg";
+
+    ( $id, $msg ) = $topic->Create( ObjectType => 'RT::Class', ObjectId => $class->Id );
+    ok( $id, 'created topic' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $class );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+done_testing;
diff --git a/t/shredder/02topic.t b/t/shredder/02topic.t
new file mode 100644
index 0000000000..4ec47fd5b0
--- /dev/null
+++ b/t/shredder/02topic.t
@@ -0,0 +1,49 @@
+use strict;
+use warnings;
+
+use Test::Deep;
+use RT::Test::Shredder tests => undef;
+my $test = "RT::Test::Shredder";
+
+my $class = RT::Class->new( RT->SystemUser );
+$class->Load('General');
+ok( $class->Id, 'loaded class General' );
+
+diag 'simple topic' if $ENV{TEST_VERBOSE};
+{
+    $test->create_savepoint('clean');
+
+    my $topic = RT::Topic->new( RT->SystemUser );
+    my ( $id, $msg ) = $topic->Create( ObjectType => 'RT::Class', ObjectId => $class->Id );
+    ok( $id, 'created topic' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $topic );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+diag 'topic with articles' if $ENV{TEST_VERBOSE};
+{
+    my $article = RT::Article->new( RT->SystemUser );
+    my ( $id, $msg ) = $article->Create( Class => 'General', Name => 'test 1' );
+    ok( $id, 'created article' ) or diag "error: $msg";
+
+    $test->create_savepoint('clean');
+    my $topic = RT::Topic->new( RT->SystemUser );
+    ( $id, $msg ) = $topic->Create( ObjectType => 'RT::Class', ObjectId => $class->Id );
+    ok( $id, 'created topic' ) or diag "error: $msg";
+
+    ( $id, $msg ) = $article->AddTopic( Topic => $topic->Id );
+    ok( $id, 'added topic' ) or diag "error: $msg";
+
+    my $shredder = $test->shredder_new();
+    $shredder->PutObjects( Objects => $topic );
+    $shredder->WipeoutAll;
+    $test->db_is_valid;
+
+    cmp_deeply( $test->dump_current_and_savepoint('clean'), "current DB equal to savepoint" );
+}
+
+done_testing;

commit 96d65581ad55f4e29c4432232f5cb446dc89ed33
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Dec 30 04:19:12 2022 +0800

    Support to shred class/topic/article objects

diff --git a/lib/RT/Article.pm b/lib/RT/Article.pm
index 590b4fb989..dbd2b97683 100644
--- a/lib/RT/Article.pm
+++ b/lib/RT/Article.pm
@@ -899,6 +899,31 @@ sub Load {
     }
 }
 
+sub __DependsOn {
+    my $self = shift;
+    my %args = (
+        Shredder     => undef,
+        Dependencies => undef,
+        @_,
+    );
+    my $deps = $args{'Dependencies'};
+    my $list = [];
+
+    # ObjectTopics
+    my $objs = RT::ObjectTopics->new( $self->CurrentUser );
+    $objs->LimitToObject($self);
+    push( @$list, $objs );
+
+    $deps->_PushDependencies(
+        BaseObject    => $self,
+        Flags         => RT::Shredder::Constants::DEPENDS_ON,
+        TargetObjects => $list,
+        Shredder      => $args{'Shredder'}
+    );
+
+    return $self->SUPER::__DependsOn(%args);
+}
+
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/Class.pm b/lib/RT/Class.pm
index 236d8548d9..7f39859cd6 100644
--- a/lib/RT/Class.pm
+++ b/lib/RT/Class.pm
@@ -596,6 +596,47 @@ sub CustomFieldLookupType {
     "RT::Class";
 }
 
+sub __DependsOn {
+    my $self = shift;
+    my %args = (
+        Shredder     => undef,
+        Dependencies => undef,
+        @_,
+    );
+    my $deps = $args{'Dependencies'};
+    my $list = [];
+
+    # Articles
+    my $objs = RT::Articles->new( $self->CurrentUser );
+    $objs->FindAllRows;
+    $objs->Limit( FIELD => 'Class', VALUE => $self->Id );
+    push( @$list, $objs );
+
+    # ObjectClasses
+    $objs = RT::ObjectClasses->new( $self->CurrentUser );
+    $objs->LimitToClass( $self->id );
+    push( @$list, $objs );
+
+    # ObjectCustomFields
+    $objs = RT::ObjectCustomFields->new( $self->CurrentUser );
+    $objs->LimitToLookupType( $_->CustomFieldLookupType ) for qw/RT::Class RT::Article/;
+    $objs->LimitToObjectId( $self->id );
+    push( @$list, $objs );
+
+    # Topics
+    $objs = RT::Topics->new( $self->CurrentUser );
+    $objs->LimitToObject($self);
+    push( @$list, $objs );
+
+    $deps->_PushDependencies(
+        BaseObject    => $self,
+        Flags         => RT::Shredder::Constants::DEPENDS_ON,
+        TargetObjects => $list,
+        Shredder      => $args{'Shredder'}
+    );
+    return $self->SUPER::__DependsOn(%args);
+}
+
 RT::Base->_ImportOverlays();
 
 1;
diff --git a/lib/RT/Shredder.pm b/lib/RT/Shredder.pm
index 9a103ee3a3..54989df0dc 100644
--- a/lib/RT/Shredder.pm
+++ b/lib/RT/Shredder.pm
@@ -252,6 +252,9 @@ our @SUPPORTED_OBJECTS = qw(
     Ticket
     Transaction
     User
+    Class
+    Article
+    Topic
 );
 
 =head3 GENERIC
diff --git a/lib/RT/Topic.pm b/lib/RT/Topic.pm
index 79edc1511f..2b03489919 100644
--- a/lib/RT/Topic.pm
+++ b/lib/RT/Topic.pm
@@ -362,5 +362,29 @@ sub FindDependencies {
     $deps->Add( out => $self->Object );
 }
 
+sub __DependsOn {
+    my $self = shift;
+    my %args = (
+        Shredder     => undef,
+        Dependencies => undef,
+        @_,
+    );
+    my $deps = $args{'Dependencies'};
+    my $list = [];
+
+    # Object Topics
+    my $objs = RT::ObjectTopics->new( $self->CurrentUser );
+    $objs->LimitToTopic( $self->Id );
+    push( @$list, $objs );
+
+    $deps->_PushDependencies(
+        BaseObject    => $self,
+        Flags         => RT::Shredder::Constants::DEPENDS_ON,
+        TargetObjects => $list,
+        Shredder      => $args{'Shredder'}
+    );
+    return $self->SUPER::__DependsOn(%args);
+}
+
 RT::Base->_ImportOverlays();
 1;

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list