[Rt-commit] rt branch, 4.4/core-assets, created. rt-4.2.11-43-g0f24385
Todd Wade
todd at bestpractical.com
Fri Jul 24 10:21:13 EDT 2015
The branch, 4.4/core-assets has been created
at 0f24385d6628e0a6df6533ab2bd9269bf9975c52 (commit)
- Log -----------------------------------------------------------------
commit cdabdbcb17c0999531877dfcc543764dbce63c14
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 13:52:51 2015 -0400
commit rt-extension-assets/xt as rt/t/assets
diff --git a/t/assets/api.t b/t/assets/api.t
new file mode 100644
index 0000000..a36d8a8
--- /dev/null
+++ b/t/assets/api.t
@@ -0,0 +1,180 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+use Test::Warn;
+
+my $catalog;
+
+diag "Create a catalog";
+{
+ $catalog = create_catalog( Name => 'Test Catalog', Disabled => 1 );
+ ok $catalog && $catalog->id, "Created catalog";
+ is $catalog->Name, "Test Catalog", "Name is correct";
+ ok $catalog->Disabled, "Disabled";
+
+ my $asset;
+ warning_like {
+ $asset = create_asset( Name => "Test", Catalog => $catalog->id );
+ } qr/^Failed to create asset .* Invalid catalog/i;
+ ok !$asset, "Couldn't create asset in disabled catalog";
+
+ my ($ok, $msg) = $catalog->SetDisabled(0);
+ ok $ok, "Enabled catalog: $msg";
+ ok !$catalog->Disabled, "Enabled";
+}
+
+diag "Create basic asset (no CFs)";
+{
+ my $asset = RT::Asset->new( RT->SystemUser );
+ my ($id, $msg) = $asset->Create(
+ Name => 'Thinkpad T420s',
+ Description => 'Laptop',
+ Catalog => $catalog->Name,
+ );
+ ok $id, "Created: $msg";
+ is $asset->id, $id, "id matches";
+ is $asset->Name, "Thinkpad T420s", "Name matches";
+ is $asset->Description, "Laptop", "Description matches";
+
+ # Create txn
+ my @txns = @{$asset->Transactions->ItemsArrayRef};
+ is scalar @txns, 1, "One transaction";
+ is $txns[0]->Type, "Create", "... of type Create";
+
+ # Update
+ my ($txnid, $txnmsg) = $asset->SetName("Lenovo Thinkpad T420s");
+ ok $txnid, "Updated Name: $txnmsg";
+ is $asset->Name, "Lenovo Thinkpad T420s", "New Name matches";
+
+ # Set txn
+ @txns = @{$asset->Transactions->ItemsArrayRef};
+ is scalar @txns, 2, "Two transactions";
+ is $txns[1]->Type, "Set", "... the second of which is Set";
+ is $txns[1]->Field, "Name", "... Field is Name";
+ is $txns[1]->OldValue, "Thinkpad T420s", "... OldValue is correct";
+
+ # Delete
+ my ($ok, $err) = $asset->Delete;
+ ok !$ok, "Deletes are prevented: $err";
+ $asset->Load($id);
+ ok $asset->id, "Asset not deleted";
+}
+
+diag "Create with CFs";
+{
+ my $height = create_cf( Name => 'Height' );
+ ok $height->id, "Created CF";
+
+ my $material = create_cf( Name => 'Material' );
+ ok $material->id, "Created CF";
+
+ ok apply_cfs($height, $material), "Applied CFs";
+
+ my $asset = RT::Asset->new( RT->SystemUser );
+ my ($id, $msg) = $asset->Create(
+ Name => 'Standing desk',
+ "CustomField-".$height->id => '46"',
+ "CustomField-Material" => 'pine',
+ Catalog => $catalog->Name,
+ );
+ ok $id, "Created: $msg";
+ is $asset->FirstCustomFieldValue('Height'), '46"', "Found height";
+ is $asset->FirstCustomFieldValue('Material'), 'pine', "Found material";
+ is $asset->Transactions->Count, 1, "Only a single txn";
+}
+
+note "Create/update with Roles";
+{
+ my $root = RT::User->new( RT->SystemUser );
+ $root->Load("root");
+ ok $root->id, "Found root";
+
+ my $bps = RT::Test->load_or_create_user( Name => "BPS" );
+ ok $bps->id, "Created BPS user";
+
+ my $asset = RT::Asset->new( RT->SystemUser );
+ my ($id, $msg) = $asset->Create(
+ Name => 'RT server',
+ HeldBy => $root->PrincipalId,
+ Owner => $bps->PrincipalId,
+ Contact => $bps->PrincipalId,
+ Catalog => $catalog->id,
+ );
+ ok $id, "Created: $msg";
+ is $asset->HeldBy->UserMembersObj->First->Name, "root", "root is Holder";
+ is $asset->Owner->Name, "BPS", "BPS is Owner";
+ is $asset->Contacts->UserMembersObj->First->Name, "BPS", "BPS is Contact";
+
+ my $sysadmins = RT::Group->new( RT->SystemUser );
+ $sysadmins->CreateUserDefinedGroup( Name => 'Sysadmins' );
+ ok $sysadmins->id, "Created group";
+ is $sysadmins->Name, "Sysadmins", "Got group name";
+
+ (my $ok, $msg) = $asset->AddRoleMember(
+ Type => 'Contact',
+ Group => 'Sysadmins',
+ );
+ ok $ok, "Added Sysadmins as Contact: $msg";
+ is $asset->Contacts->MembersObj->Count, 2, "Found two members";
+
+ my @txn = grep { $_->Type eq 'AddWatcher' } @{$asset->Transactions->ItemsArrayRef};
+ ok @txn == 1, "Found one AddWatcher txn";
+ is $txn[0]->Field, "Contact", "... of a Contact";
+ is $txn[0]->NewValue, $sysadmins->PrincipalId, "... for the right principal";
+
+ ($ok, $msg) = $asset->DeleteRoleMember(
+ Type => 'Contact',
+ PrincipalId => $bps->PrincipalId,
+ );
+ ok $ok, "Removed BPS user as Contact: $msg";
+ is $asset->Contacts->MembersObj->Count, 1, "Now just one member";
+ is $asset->Contacts->GroupMembersObj(Recursively => 0)->First->Name, "Sysadmins", "... it's Sysadmins";
+
+ @txn = grep { $_->Type eq 'DelWatcher' } @{$asset->Transactions->ItemsArrayRef};
+ ok @txn == 1, "Found one DelWatcher txn";
+ is $txn[0]->Field, "Contact", "... of a Contact";
+ is $txn[0]->OldValue, $bps->PrincipalId, "... for the right principal";
+}
+
+diag "Custom Field handling";
+{
+ diag "Make sure we don't load queue CFs";
+ my $queue_cf = RT::CustomField->new( RT->SystemUser );
+ my ($ok, $msg) = $queue_cf->Create(
+ Name => "Queue CF",
+ Type => "Text",
+ LookupType => RT::Queue->CustomFieldLookupType,
+ );
+ ok( $queue_cf->Id, "Created test CF: " . $queue_cf->Id);
+
+ my $cf1 = RT::CustomField->new( RT->SystemUser );
+ $cf1->LoadByNameAndCatalog ( Name => "Queue CF" );
+
+ ok( (not $cf1->Id), "Queue CF not loaded with LoadByNameAndCatalog");
+
+ my $cf2 = RT::CustomField->new( RT->SystemUser );
+ $cf2->LoadByNameAndCatalog ( Name => "Height" );
+ ok( $cf2->Id, "Loaded CF id: " . $cf2->Id . " with name");
+ ok( $cf2->Name, "Loaded CF name: " . $cf2->Name . " with name");
+
+ my $cf3 = RT::CustomField->new( RT->SystemUser );
+ ($ok, $msg) = $cf3->LoadByNameAndCatalog ( Name => "Height", Catalog => $catalog->Name );
+ ok( (not $cf3->Id), "CF 'Height'"
+ . " not added to catalog: " . $catalog->Name);
+
+ my $color = create_cf( Name => 'Color' );
+ ok $color->Id, "Created CF " . $color->Name;
+ ($ok, $msg) = $color->AddToObject( $catalog );
+
+ ($ok, $msg) = $color->LoadByNameAndCatalog ( Name => "Color", Catalog => $catalog->Name );
+ ok( $color->Id, "Loaded CF id: " . $color->Id
+ . " for catalog: " . $catalog->Name);
+ ok( $color->Name, "Loaded CF name: " . $color->Name
+ . " for catalog: " . $catalog->Name);
+
+}
+
+
+done_testing;
diff --git a/t/assets/collection.t b/t/assets/collection.t
new file mode 100644
index 0000000..7bf5911
--- /dev/null
+++ b/t/assets/collection.t
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+
+my $user = RT::Test->load_or_create_user( Name => 'testuser' );
+ok $user->id, "Created user";
+
+my $catalog = create_catalog( Name => "BPS" );
+ok $catalog && $catalog->id, "Created catalog";
+
+my $location = create_cf( Name => 'Location' );
+ok $location->id, "Created CF";
+ok apply_cfs($location), "Applied CF";
+
+ok(
+ create_assets(
+ { Name => "Thinkpad T420s", Catalog => $catalog->id, "CustomField-Location" => "Home" },
+ { Name => "Standing desk", Catalog => $catalog->id, "CustomField-Location" => "Office" },
+ { Name => "Chair", Catalog => $catalog->id, "CustomField-Location" => "Office" },
+ ),
+ "Created assets"
+);
+
+diag "Mark chair as deleted";
+{
+ my $asset = RT::Asset->new( RT->SystemUser );
+ $asset->LoadByCols( Name => "Chair" );
+ my ($ok, $msg) = $asset->SetStatus( "deleted" );
+ ok($ok, "Deleted the chair: $msg");
+}
+
+diag "Basic types of limits";
+{
+ my $assets = RT::Assets->new( RT->SystemUser );
+ $assets->Limit( FIELD => 'Name', OPERATOR => 'LIKE', VALUE => 'thinkpad' );
+ is $assets->Count, 1, "Found 1 like thinkpad";
+ is $assets->First->Name, "Thinkpad T420s";
+
+ $assets = RT::Assets->new( RT->SystemUser );
+ $assets->UnLimit;
+ is $assets->Count, 2, "Found 2 total";
+ ok((!grep { $_->Name eq "Chair" } @{$assets->ItemsArrayRef}), "No chair (disabled)");
+
+ $assets = RT::Assets->new( RT->SystemUser );
+ $assets->Limit( FIELD => 'Status', VALUE => 'deleted' );
+ $assets->{allow_deleted_search} = 1;
+ is $assets->Count, 1, "Found 1 deleted";
+ is $assets->First->Name, "Chair", "Found chair";
+
+ $assets = RT::Assets->new( RT->SystemUser );
+ $assets->UnLimit;
+ $assets->LimitCustomField(
+ CUSTOMFIELD => $location->id,
+ VALUE => "Office",
+ );
+ is $assets->Count, 1, "Found 1 in Office";
+ ok $assets->First, "Got record";
+ is $assets->First->Name, "Standing desk", "Found standing desk";
+}
+
+diag "Test ACLs";
+{
+ my $assets = RT::Assets->new( RT::CurrentUser->new($user) );
+ $assets->UnLimit;
+ is scalar @{$assets->ItemsArrayRef}, 0, "Found none";
+}
+
+done_testing;
diff --git a/t/assets/compile.t b/t/assets/compile.t
new file mode 100644
index 0000000..4ab1d21
--- /dev/null
+++ b/t/assets/compile.t
@@ -0,0 +1,11 @@
+use strict;
+use warnings;
+
+use Test::More;
+use lib 'xt/lib';
+
+use_ok('RT::Extension::Assets::Test');
+use_ok('RT::Asset');
+use_ok('RT::Assets');
+use_ok('RT::Catalog');
+use_ok('RT::Catalogs');
diff --git a/t/assets/lib/RT/Extension/Assets/Test.pm b/t/assets/lib/RT/Extension/Assets/Test.pm
new file mode 100644
index 0000000..8dbf044
--- /dev/null
+++ b/t/assets/lib/RT/Extension/Assets/Test.pm
@@ -0,0 +1,96 @@
+use strict;
+use warnings;
+
+### after: use lib qw(@RT_LIB_PATH@);
+use lib qw(/Users/trwww/Documents/waveright/bestpractical/git/rt/local/lib ../rt/lib);
+
+package RT::Extension::Assets::Test;
+use base 'RT::Test';
+
+our @EXPORT = qw(create_catalog create_asset create_assets create_cf apply_cfs);
+
+sub import {
+ my $class = shift;
+ my %args = @_;
+
+ $args{'requires'} ||= [];
+ if ( $args{'testing'} ) {
+ unshift @{ $args{'requires'} }, 'RT::Extension::Assets';
+ } else {
+ $args{'testing'} = 'RT::Extension::Assets';
+ }
+
+ $class->SUPER::import( %args );
+
+ require RT::Extension::Assets;
+ require RT::Asset;
+ __PACKAGE__->export_to_level(1);
+}
+
+sub diag {
+ Test::More::diag(@_) if $ENV{TEST_VERBOSE};
+}
+
+sub create_catalog {
+ my %info = @_;
+ my $catalog = RT::Catalog->new( RT->SystemUser );
+ my ($id, $msg) = $catalog->Create( %info );
+ if ($id) {
+ diag("Created catalog #$id: " . $catalog->Name);
+ return $catalog;
+ } else {
+ my $spec = join "/", map { "$_=$info{$_}" } keys %info;
+ RT->Logger->error("Failed to create catalog ($spec): $msg");
+ return;
+ }
+}
+
+sub create_asset {
+ my %info = @_;
+ my $asset = RT::Asset->new( RT->SystemUser );
+ my ($id, $msg) = $asset->Create( %info );
+ if ($id) {
+ diag("Created asset #$id: " . $asset->Name);
+ return $asset;
+ } else {
+ my $spec = join "/", map { "$_=$info{$_}" } keys %info;
+ RT->Logger->error("Failed to create asset ($spec): $msg");
+ return;
+ }
+}
+
+sub create_assets {
+ my $error = 0;
+ for my $info (@_) {
+ create_asset(%$info)
+ or $error++;
+ }
+ return not $error;
+}
+
+sub create_cf {
+ my %args = (
+ Name => "Test Asset CF ".($$ + rand(1024)),
+ Type => "FreeformSingle",
+ LookupType => RT::Asset->CustomFieldLookupType,
+ @_,
+ );
+ my $cf = RT::CustomField->new( RT->SystemUser );
+ my ($ok, $msg) = $cf->Create(%args);
+ RT->Logger->error("Can't create CF: $msg") unless $ok;
+ return $cf;
+}
+
+sub apply_cfs {
+ my $success = 1;
+ for my $cf (@_) {
+ my ($ok, $msg) = $cf->AddToObject( RT::Catalog->new(RT->SystemUser) );
+ if (not $ok) {
+ RT->Logger->error("Couldn't apply CF: $msg");
+ $success = 0;
+ }
+ }
+ return $success;
+}
+
+1;
diff --git a/t/assets/lib/RT/Extension/Assets/Test.pm.in b/t/assets/lib/RT/Extension/Assets/Test.pm.in
new file mode 100644
index 0000000..0f49438
--- /dev/null
+++ b/t/assets/lib/RT/Extension/Assets/Test.pm.in
@@ -0,0 +1,96 @@
+use strict;
+use warnings;
+
+### after: use lib qw(@RT_LIB_PATH@);
+use lib qw(/opt/rt4/local/lib /opt/rt4/lib);
+
+package RT::Extension::Assets::Test;
+use base 'RT::Test';
+
+our @EXPORT = qw(create_catalog create_asset create_assets create_cf apply_cfs);
+
+sub import {
+ my $class = shift;
+ my %args = @_;
+
+ $args{'requires'} ||= [];
+ if ( $args{'testing'} ) {
+ unshift @{ $args{'requires'} }, 'RT::Extension::Assets';
+ } else {
+ $args{'testing'} = 'RT::Extension::Assets';
+ }
+
+ $class->SUPER::import( %args );
+
+ require RT::Extension::Assets;
+ require RT::Asset;
+ __PACKAGE__->export_to_level(1);
+}
+
+sub diag {
+ Test::More::diag(@_) if $ENV{TEST_VERBOSE};
+}
+
+sub create_catalog {
+ my %info = @_;
+ my $catalog = RT::Catalog->new( RT->SystemUser );
+ my ($id, $msg) = $catalog->Create( %info );
+ if ($id) {
+ diag("Created catalog #$id: " . $catalog->Name);
+ return $catalog;
+ } else {
+ my $spec = join "/", map { "$_=$info{$_}" } keys %info;
+ RT->Logger->error("Failed to create catalog ($spec): $msg");
+ return;
+ }
+}
+
+sub create_asset {
+ my %info = @_;
+ my $asset = RT::Asset->new( RT->SystemUser );
+ my ($id, $msg) = $asset->Create( %info );
+ if ($id) {
+ diag("Created asset #$id: " . $asset->Name);
+ return $asset;
+ } else {
+ my $spec = join "/", map { "$_=$info{$_}" } keys %info;
+ RT->Logger->error("Failed to create asset ($spec): $msg");
+ return;
+ }
+}
+
+sub create_assets {
+ my $error = 0;
+ for my $info (@_) {
+ create_asset(%$info)
+ or $error++;
+ }
+ return not $error;
+}
+
+sub create_cf {
+ my %args = (
+ Name => "Test Asset CF ".($$ + rand(1024)),
+ Type => "FreeformSingle",
+ LookupType => RT::Asset->CustomFieldLookupType,
+ @_,
+ );
+ my $cf = RT::CustomField->new( RT->SystemUser );
+ my ($ok, $msg) = $cf->Create(%args);
+ RT->Logger->error("Can't create CF: $msg") unless $ok;
+ return $cf;
+}
+
+sub apply_cfs {
+ my $success = 1;
+ for my $cf (@_) {
+ my ($ok, $msg) = $cf->AddToObject( RT::Catalog->new(RT->SystemUser) );
+ if (not $ok) {
+ RT->Logger->error("Couldn't apply CF: $msg");
+ $success = 0;
+ }
+ }
+ return $success;
+}
+
+1;
diff --git a/t/assets/links.t b/t/assets/links.t
new file mode 100644
index 0000000..d81fdcc
--- /dev/null
+++ b/t/assets/links.t
@@ -0,0 +1,130 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+use Test::Warn;
+
+my $catalog = create_catalog( Name => "BPS" );
+ok $catalog && $catalog->id, "Created Catalog";
+
+ok(
+ create_assets(
+ { Name => "Thinkpad T420s", Catalog => $catalog->id },
+ { Name => "Standing desk", Catalog => $catalog->id },
+ { Name => "Chair", Catalog => $catalog->id },
+ ),
+ "Created assets"
+);
+
+my $ticket = RT::Test->create_ticket(
+ Queue => 1,
+ Subject => 'a test ticket',
+);
+ok $ticket->id, "Created ticket";
+
+diag "RT::URI::asset";
+{
+ my %uris = (
+ # URI => Asset Name
+ "asset:1" => { id => 1, Name => "Thinkpad T420s" },
+ "asset://example.com/2" => { id => 2, Name => "Standing desk" },
+ "asset:13" => undef,
+ );
+
+ while (my ($url, $expected) = each %uris) {
+ my $uri = RT::URI->new( RT->SystemUser );
+ if ($expected) {
+ my $parsed = $uri->FromURI($url);
+ ok $parsed, "Parsed $url";
+
+ my $asset = $uri->Object;
+ ok $asset, "Got object";
+ is ref($asset), "RT::Asset", "... it's a RT::Asset";
+
+ while (my ($field, $value) = each %$expected) {
+ is $asset->$field, $value, "... $field is $value";
+ }
+ } else {
+ my $parsed;
+ warnings_like {
+ $parsed = $uri->FromURI($url);
+ } [qr/\Q$url\E/, qr/\Q$url\E/], "Caught warnings about unknown URI";
+ ok !$parsed, "Failed to parse $url, as expected";
+ }
+ }
+}
+
+diag "RT::Asset link support";
+{
+ my $chair = RT::Asset->new( RT->SystemUser );
+ $chair->LoadByCols( Name => "Chair" );
+ ok $chair->id, "Loaded asset";
+ is $chair->URI, "asset://example.com/".$chair->id, "->URI works";
+
+ my ($link_id, $msg) = $chair->AddLink( Type => 'MemberOf', Target => 'asset:2' );
+ ok $link_id, "Added link: $msg";
+
+ my $parents = $chair->MemberOf;
+ my $desk = $parents->First->TargetObj;
+ is $parents->Count, 1, "1 parent";
+ is $desk->Name, "Standing desk", "Correct parent asset";
+
+ for my $asset ($chair, $desk) {
+ my $txns = $asset->Transactions;
+ $txns->Limit( FIELD => 'Type', VALUE => 'AddLink' );
+ is $txns->Count, 1, "1 AddLink txn on asset ".$asset->Name;
+ }
+
+ my ($ok, $err) = $chair->DeleteLink( Type => 'MemberOf', Target => 'asset:1' );
+ ok !$ok, "Delete link failed on non-existent: $err";
+
+ my ($deleted, $delete_msg) = $chair->DeleteLink( Type => 'MemberOf', Target => $parents->First->Target );
+ ok $deleted, "Deleted link: $delete_msg";
+
+ for my $asset ($chair, $desk) {
+ my $txns = $asset->Transactions;
+ $txns->Limit( FIELD => 'Type', VALUE => 'DeleteLink' );
+ is $txns->Count, 1, "1 DeleteLink txn on asset ".$asset->Name;
+ }
+};
+
+diag "Linking to tickets";
+{
+ my $laptop = RT::Asset->new( RT->SystemUser );
+ $laptop->LoadByCols( Name => "Thinkpad T420s" );
+
+ my ($ok, $msg) = $ticket->AddLink( Type => 'RefersTo', Target => $laptop->URI );
+ ok $ok, "Ticket refers to asset: $msg";
+
+ my $links = $laptop->ReferredToBy;
+ is $links->Count, 1, "Found a ReferredToBy link via asset";
+
+ ($ok, $msg) = $laptop->DeleteLink( Type => 'RefersTo', Base => $ticket->URI );
+ ok $ok, "Deleted link from opposite side: $msg";
+}
+
+diag "Links on ->Create";
+{
+ my $desk = RT::Asset->new( RT->SystemUser );
+ $desk->LoadByCols( Name => "Standing desk" );
+ ok $desk->id, "Loaded standing desk asset";
+
+ my $asset = create_asset(
+ Name => "Anti-fatigue mat",
+ Catalog => $catalog->id,
+ Parent => $desk->URI,
+ ReferredToBy => [$ticket->id],
+ );
+ ok $asset->id, "Created asset with Parent link";
+
+ my $parents = $asset->MemberOf;
+ is $parents->Count, 1, "Found one Parent";
+ is $parents->First->Target, $desk->URI, "... it's a desk!";
+
+ my $referrals = $asset->ReferredToBy;
+ is $referrals->Count, 1, "Found one ReferredToBy";
+ is $referrals->First->Base, $ticket->URI, "... it's the ticket!";
+}
+
+done_testing;
diff --git a/t/assets/pod.t b/t/assets/pod.t
new file mode 100644
index 0000000..1d2686c
--- /dev/null
+++ b/t/assets/pod.t
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Pod;
+all_pod_files_ok( all_pod_files("lib","doc","etc"));
diff --git a/t/assets/rights.t b/t/assets/rights.t
new file mode 100644
index 0000000..30394b3
--- /dev/null
+++ b/t/assets/rights.t
@@ -0,0 +1,125 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+
+my $user = RT::Test->load_or_create_user( Name => 'testuser' );
+ok $user->id, "Created user";
+
+my $ticket = RT::Test->create_ticket(
+ Queue => 1,
+ Subject => 'a test ticket',
+);
+ok $ticket->id, "Created ticket";
+
+my $catalog_one = create_catalog( Name => "One" );
+ok $catalog_one && $catalog_one->id, "Created catalog one";
+
+my $catalog_two = create_catalog( Name => "Two" );
+ok $catalog_two && $catalog_two->id, "Created catalog two";
+
+ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'ShowCatalog',
+ Object => $catalog_one,
+}), "Granted ShowCatalog");
+
+my $asset = RT::Asset->new( RT::CurrentUser->new($user) );
+
+diag "CreateAsset";
+{
+ my %create = (
+ Name => 'Thinkpad T420s',
+ Contact => 'trs at example.com',
+ Catalog => $catalog_one->id,
+ );
+ my ($id, $msg) = $asset->Create(%create);
+ ok !$id, "Create denied: $msg";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'CreateAsset',
+ Object => $catalog_one,
+ }), "Granted CreateAsset");
+
+ ($id, $msg) = $asset->Create(%create);
+ ok $id, "Created: $msg";
+ is $asset->id, $id, "id matches";
+ is $asset->CatalogObj->Name, $catalog_one->Name, "Catalog matches";
+};
+
+diag "ShowAsset";
+{
+ is $asset->Name, undef, "Can't see Name without ShowAsset";
+ ok !$asset->Contacts->id, "Can't see Contacts role group";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'ShowAsset',
+ Object => $catalog_one,
+ }), "Granted ShowAsset");
+
+ is $asset->Name, "Thinkpad T420s", "Got Name";
+ is $asset->Contacts->UserMembersObj->First->EmailAddress, 'trs at example.com', "Got Contact";
+}
+
+diag "ModifyAsset";
+{
+ my ($txnid, $txnmsg) = $asset->SetName("Lenovo Thinkpad T420s");
+ ok !$txnid, "Update failed: $txnmsg";
+ is $asset->Name, "Thinkpad T420s", "Name didn't change";
+
+ my ($ok, $msg) = $asset->AddLink( Type => 'RefersTo', Target => 't:1' );
+ ok !$ok, "No rights to AddLink: $msg";
+
+ ($ok, $msg) = $asset->DeleteLink( Type => 'RefersTo', Target => 't:1' );
+ ok !$ok, "No rights to DeleteLink: $msg";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'ModifyAsset',
+ Object => $catalog_one,
+ }), "Granted ModifyAsset");
+
+ ($txnid, $txnmsg) = $asset->SetName("Lenovo Thinkpad T420s");
+ ok $txnid, "Updated Name: $txnmsg";
+ is $asset->Name, "Lenovo Thinkpad T420s", "Name changed";
+}
+
+diag "Catalogs";
+{
+ my ($txnid, $txnmsg) = $asset->SetCatalog($catalog_two->id);
+ ok !$txnid, "Failed to update Catalog: $txnmsg";
+ is $asset->CatalogObj->Name, $catalog_one->Name, "Catalog unchanged";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'CreateAsset',
+ Object => $catalog_two,
+ }), "Granted CreateAsset in second catalog");
+
+ ($txnid, $txnmsg) = $asset->SetCatalog($catalog_two->id);
+ ok $txnid, "Updated Catalog: $txnmsg";
+ unlike $txnmsg, qr/Permission Denied/i, "Transaction message isn't Permission Denied";
+ ok !$asset->CurrentUserCanSee, "Can no longer see the asset";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'ShowAsset',
+ Object => $catalog_two,
+ }), "Granted ShowAsset");
+
+ ok $asset->CurrentUserCanSee, "Can see the asset now";
+ is $asset->CatalogObj->Name, undef, "Can't see the catalog name still";
+
+ ok(RT::Test->add_rights({
+ Principal => 'Privileged',
+ Right => 'ShowCatalog',
+ Object => $catalog_two,
+ }), "Granted ShowCatalog");
+
+ is $asset->CatalogObj->Name, $catalog_two->Name, "Now we can see the catalog name";
+}
+
+done_testing;
diff --git a/t/assets/roles.t b/t/assets/roles.t
new file mode 100644
index 0000000..ffaa5d2
--- /dev/null
+++ b/t/assets/roles.t
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+
+my $catalog = create_catalog( Name => "A catalog" );
+my $asset = create_asset( Name => "Test asset", Catalog => $catalog->id );
+ok $asset && $asset->id, "Created asset";
+
+for my $object ($asset, $catalog, RT->System) {
+ for my $role (RT::Asset->Roles) {
+ my $group = $object->RoleGroup($role);
+ ok $group->id, "Loaded role group $role for " . ref($object);
+
+ my $principal = $group->PrincipalObj;
+ ok $principal && $principal->id, "Found PrincipalObj for role group"
+ or next;
+
+ if ($object->DOES("RT::Record::Role::Rights")) {
+ my ($ok, $msg) = $principal->GrantRight(
+ Object => $object,
+ Right => "ShowAsset",
+ );
+ ok $ok, "Granted right" or diag "Error: $msg";
+ }
+ }
+}
+
+done_testing;
diff --git a/t/assets/web.t b/t/assets/web.t
new file mode 100644
index 0000000..5579702
--- /dev/null
+++ b/t/assets/web.t
@@ -0,0 +1,114 @@
+use strict;
+use warnings;
+
+use lib 'xt/lib';
+use RT::Extension::Assets::Test tests => undef;
+
+RT->Config->Set("CustomFieldGroupings",
+ "RT::Asset" => {
+ Dates => [qw(Purchased)],
+ },
+);
+
+my $catalog = create_catalog( Name => "Office" );
+ok $catalog->id, "Created Catalog";
+
+my $purchased = create_cf( Name => 'Purchased', Pattern => '(?#Year)^(?:19|20)\d{2}$' );
+ok $purchased->id, "Created CF";
+
+my $height = create_cf( Name => 'Height', Pattern => '(?#Inches)^\d+"?$' );
+ok $height->id, "Created CF";
+
+my $material = create_cf( Name => 'Material' );
+ok $material->id, "Created CF";
+
+my %CF = (
+ Height => ".CF-" . $height->id . "-Edit",
+ Material => ".CF-" . $material->id . "-Edit",
+ Purchased => ".CF-" . $purchased->id . "-Edit",
+);
+
+my ($base, $m) = RT::Extension::Assets::Test->started_ok;
+ok $m->login, "Logged in agent";
+
+diag "Create basic asset (no CFs)";
+{
+ $m->follow_link_ok({ id => "assets-create" }, "Asset create link");
+ $m->submit_form_ok({ with_fields => { Catalog => $catalog->id } }, "Picked a catalog");
+ $m->submit_form_ok({
+ with_fields => {
+ id => 'new',
+ Name => 'Thinkpad T420s',
+ Description => 'A laptop',
+ },
+ }, "submited create form");
+ $m->content_like(qr/Asset .* created/, "Found created message");
+ my ($id) = $m->uri =~ /id=(\d+)/;
+
+ my $asset = RT::Asset->new( RT->SystemUser );
+ $asset->Load($id);
+ is $asset->id, $id, "id matches";
+ is $asset->Name, "Thinkpad T420s", "Name matches";
+ is $asset->Description, "A laptop", "Description matches";
+}
+
+diag "Create with CFs";
+{
+ ok apply_cfs($height, $material), "Applied CFs";
+
+ $m->follow_link_ok({ id => "assets-create" }, "Asset create link");
+ $m->submit_form_ok({ with_fields => { Catalog => $catalog->id } }, "Picked a catalog");
+
+ ok $m->form_with_fields(qw(id Name Description)), "Found form";
+ $m->submit_form_ok({
+ fields => {
+ id => 'new',
+ Name => 'Standing desk',
+ $CF{Height} => 'forty-six inches',
+ $CF{Material} => 'pine',
+ },
+ }, "submited create form");
+ $m->content_unlike(qr/Asset .* created/, "Lacks created message");
+ $m->content_like(qr/must match .*?Inches/, "Found validation error");
+
+ # Intentionally fix only the invalid CF to test the other fields are
+ # preserved across errors
+ ok $m->form_with_fields(qw(id Name Description)), "Found form again";
+ $m->set_fields( $CF{Height} => '46"' );
+ $m->submit_form_ok({}, "resubmitted form");
+
+ $m->content_like(qr/Asset .* created/, "Found created message");
+ my ($id) = $m->uri =~ /id=(\d+)/;
+
+ my $asset = RT::Asset->new( RT->SystemUser );
+ $asset->Load($id);
+ is $asset->id, $id, "id matches";
+ is $asset->FirstCustomFieldValue('Height'), '46"', "Found height";
+ is $asset->FirstCustomFieldValue('Material'), 'pine', "Found material";
+}
+
+diag "Create with CFs in other groups";
+{
+ ok apply_cfs($purchased), "Applied CF";
+
+ $m->follow_link_ok({ id => "assets-create" }, "Asset create link");
+ $m->submit_form_ok({ with_fields => { Catalog => $catalog->id } }, "Picked a catalog");
+
+ ok $m->form_with_fields(qw(id Name Description)), "Found form";
+
+ $m->submit_form_ok({
+ fields => {
+ id => 'new',
+ Name => 'Chair',
+ $CF{Height} => '23',
+ },
+ }, "submited create form");
+
+ $m->content_like(qr/Asset .* created/, "Found created message");
+ $m->content_unlike(qr/Purchased.*?must match .*?Year/, "Lacks validation error for Purchased");
+}
+
+# XXX TODO: test other modify pages
+
+undef $m;
+done_testing;
commit 6eb052012c1f4b54a8ee32413ef174b11eb0f102
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 13:53:36 2015 -0400
remove .in file and use .pm file as test lib
diff --git a/t/assets/lib/RT/Extension/Assets/Test.pm.in b/t/assets/lib/RT/Extension/Assets/Test.pm.in
deleted file mode 100644
index 0f49438..0000000
--- a/t/assets/lib/RT/Extension/Assets/Test.pm.in
+++ /dev/null
@@ -1,96 +0,0 @@
-use strict;
-use warnings;
-
-### after: use lib qw(@RT_LIB_PATH@);
-use lib qw(/opt/rt4/local/lib /opt/rt4/lib);
-
-package RT::Extension::Assets::Test;
-use base 'RT::Test';
-
-our @EXPORT = qw(create_catalog create_asset create_assets create_cf apply_cfs);
-
-sub import {
- my $class = shift;
- my %args = @_;
-
- $args{'requires'} ||= [];
- if ( $args{'testing'} ) {
- unshift @{ $args{'requires'} }, 'RT::Extension::Assets';
- } else {
- $args{'testing'} = 'RT::Extension::Assets';
- }
-
- $class->SUPER::import( %args );
-
- require RT::Extension::Assets;
- require RT::Asset;
- __PACKAGE__->export_to_level(1);
-}
-
-sub diag {
- Test::More::diag(@_) if $ENV{TEST_VERBOSE};
-}
-
-sub create_catalog {
- my %info = @_;
- my $catalog = RT::Catalog->new( RT->SystemUser );
- my ($id, $msg) = $catalog->Create( %info );
- if ($id) {
- diag("Created catalog #$id: " . $catalog->Name);
- return $catalog;
- } else {
- my $spec = join "/", map { "$_=$info{$_}" } keys %info;
- RT->Logger->error("Failed to create catalog ($spec): $msg");
- return;
- }
-}
-
-sub create_asset {
- my %info = @_;
- my $asset = RT::Asset->new( RT->SystemUser );
- my ($id, $msg) = $asset->Create( %info );
- if ($id) {
- diag("Created asset #$id: " . $asset->Name);
- return $asset;
- } else {
- my $spec = join "/", map { "$_=$info{$_}" } keys %info;
- RT->Logger->error("Failed to create asset ($spec): $msg");
- return;
- }
-}
-
-sub create_assets {
- my $error = 0;
- for my $info (@_) {
- create_asset(%$info)
- or $error++;
- }
- return not $error;
-}
-
-sub create_cf {
- my %args = (
- Name => "Test Asset CF ".($$ + rand(1024)),
- Type => "FreeformSingle",
- LookupType => RT::Asset->CustomFieldLookupType,
- @_,
- );
- my $cf = RT::CustomField->new( RT->SystemUser );
- my ($ok, $msg) = $cf->Create(%args);
- RT->Logger->error("Can't create CF: $msg") unless $ok;
- return $cf;
-}
-
-sub apply_cfs {
- my $success = 1;
- for my $cf (@_) {
- my ($ok, $msg) = $cf->AddToObject( RT::Catalog->new(RT->SystemUser) );
- if (not $ok) {
- RT->Logger->error("Couldn't apply CF: $msg");
- $success = 0;
- }
- }
- return $success;
-}
-
-1;
commit 422e0893f84b333fb8144e0fa2d0e6ce70c12bf8
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 14:59:22 2015 -0400
move extension test lib in to RT
diff --git a/t/assets/lib/RT/Extension/Assets/Test.pm b/lib/RT/Test/Assets.pm
similarity index 100%
rename from t/assets/lib/RT/Extension/Assets/Test.pm
rename to lib/RT/Test/Assets.pm
commit 322fbe2044f2bf15aa3a90d2da19d061e6556b2f
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 17:28:10 2015 -0400
clean up RT::Test::Asset lib so it can be used as a base for the tests
diff --git a/lib/RT/Test/Assets.pm b/lib/RT/Test/Assets.pm
index 8dbf044..f107a12 100644
--- a/lib/RT/Test/Assets.pm
+++ b/lib/RT/Test/Assets.pm
@@ -1,10 +1,7 @@
use strict;
use warnings;
-### after: use lib qw(@RT_LIB_PATH@);
-use lib qw(/Users/trwww/Documents/waveright/bestpractical/git/rt/local/lib ../rt/lib);
-
-package RT::Extension::Assets::Test;
+package RT::Test::Assets;
use base 'RT::Test';
our @EXPORT = qw(create_catalog create_asset create_assets create_cf apply_cfs);
@@ -13,13 +10,6 @@ sub import {
my $class = shift;
my %args = @_;
- $args{'requires'} ||= [];
- if ( $args{'testing'} ) {
- unshift @{ $args{'requires'} }, 'RT::Extension::Assets';
- } else {
- $args{'testing'} = 'RT::Extension::Assets';
- }
-
$class->SUPER::import( %args );
require RT::Extension::Assets;
commit 3b71f69acb2b18ccbb56c1ab8fa7fe7908aae0de
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 17:29:51 2015 -0400
move assets database scaffolding to RT
This is mostly a raw copy in to the RT schema files.
TODO:
- integrate in to existing data instead of adding to end of file
- upgrading without Assets extension installed
- upgrading with Assets extension installed
diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index fd9e971..bb7c095 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1644,7 +1644,138 @@ Set($HideArticleSearchOnReplyCreate, 0);
=back
+=head1 Assets
+=over 4
+
+=item C<@AssetQueues>
+
+This should be a list of names of queues whose tickets should always
+display the "Assets" box. This is useful for queues which deal
+primarily with assets, as it provides a ready box to link an asset to
+the ticket, even when the ticket has no related assets yet.
+
+=cut
+
+# Set(@AssetQueues, ());
+
+=item C<$DefaultCatalog>
+
+This provides the default catalog after a user initially logs in.
+However, the default catalog is "sticky," and so will remember the
+last-selected catalog thereafter.
+
+=cut
+
+# Set($DefaultCatalog, 'General assets');
+
+=item C<$AssetSearchFields>
+
+Specifies which fields of L<RT::Asset> to match against and how to match
+each field when performing a quick search on assets. Valid match
+methods are LIKE, STARTSWITH, ENDSWITH, =, and !=. Valid search fields
+are id, Name, Description, or custom fields, which are specified as
+"CF.1234" or "CF.Name"
+
+=cut
+
+Set($AssetSearchFields, {
+ id => '=',
+ Name => 'LIKE',
+ Description => 'LIKE',
+}) unless $AssetSearchFields;
+
+=item C<$AssetSearchFormat>
+
+The format that results of the asset search are displayed with. This is
+either a string, which will be used for all catalogs, or a hash
+reference, keyed by catalog's name/id. If a hashref and neither name or
+id is found therein, falls back to the key ''.
+
+If you wish to use the multiple catalog format, your configuration would look
+something like:
+
+ Set($AssetSearchFormat, {
+ 'General assets' => q[Format String for the General Assets Catalog],
+ 8 => q[Format String for Catalog 8],
+ '' => q[Format String for any catalogs not listed explicitly],
+ });
+
+=cut
+
+# loc('Related tickets')
+Set($AssetSearchFormat, q[
+ '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ Description,
+ '__Status__ (__Catalog__)/TITLE:Status',
+ Owner,
+ HeldBy,
+ Contacts,
+ '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
+]) unless $AssetSearchFormat;
+
+=item C<$AssetSummaryFormat>
+
+The information that is displayed on ticket display pages about assets
+related to the ticket. This is displayed in a table beneath the asset
+name.
+
+=cut
+
+Set($AssetSummaryFormat, q[
+ '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ Description,
+ '__Status__ (__Catalog__)/TITLE:Status',
+ Owner,
+ HeldBy,
+ Contacts,
+ '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
+]) unless $AssetSummaryFormat;
+
+=item C<$AssetSummaryRelatedTicketsFormat>
+
+The information that is displayed on ticket display pages about tickets
+related to assets related to the ticket. This is displayed as a list of
+tickets underneath the asset properties.
+
+=cut
+
+Set($AssetSummaryRelatedTicketsFormat, q[
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
+ '(__OwnerName__)',
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
+ QueueName,
+ Status,
+]) unless $AssetSummaryRelatedTicketsFormat;
+
+=item C<%AdminSearchResultFormat>
+
+The C<Catalogs> key of this standard RT configuration option (see
+L<RT_Config/%AdminSearchResultFormat>) controls how catalogs are
+displayed in their list in the admin pages.
+
+=cut
+
+Set(%AdminSearchResultFormat,
+ Catalogs =>
+ q{'<a href="__WebPath__/Admin/Assets/Catalogs/Modify.html?id=__id__">__id__</a>/TITLE:#'}
+ .q{,'<a href="__WebPath__/Admin/Assets/Catalogs/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
+ .q{,__Description__,__Lifecycle__,__Disabled__},
+) unless $AdminSearchResultFormat{Catalogs};
+
+=item C<$AssetBasicCustomFieldsOnCreate>
+
+Specify a list of Asset custom fields to show in "Basics" widget on create.
+
+e.g.
+
+Set( $AssetBasicCustomFieldsOnCreate, [ 'foo', 'bar' ] );
+
+=cut
+
+# Set($AssetBasicCustomFieldsOnCreate, undef );
+
+=back
=head2 Message box properties
@@ -2359,8 +2490,6 @@ Set($TimeInICal, 0);
=back
-
-
=head1 Cryptography
A complete description of RT's cryptography capabilities can be found in
@@ -2875,6 +3004,52 @@ Set(%Lifecycles,
'deleted -> open' => { label => 'Undelete', }, # loc{label}
],
},
+ assets => {
+ type => "asset",
+ initial => [
+ 'new' # loc
+ ],
+ active => [
+ 'allocated', # loc
+ 'in-use' # loc
+ ],
+ inactive => [
+ 'recycled', # loc
+ 'stolen', # loc
+ 'deleted' # loc
+ ],
+
+ defaults => {
+ on_create => 'new',
+ },
+
+ transitions => {
+ '' => [qw(new allocated in-use)],
+ new => [qw(allocated in-use stolen deleted)],
+ allocated => [qw(in-use recycled stolen deleted)],
+ "in-use" => [qw(allocated recycled stolen deleted)],
+ recycled => [qw(allocated)],
+ stolen => [qw(allocated)],
+ deleted => [qw(allocated)],
+ },
+ rights => {
+ '* -> *' => 'ModifyAsset',
+ },
+ actions => {
+ '* -> allocated' => {
+ label => "Allocate" # loc
+ },
+ '* -> in-use' => {
+ label => "Now in-use" # loc
+ },
+ '* -> recycled' => {
+ label => "Recycle" # loc
+ },
+ '* -> stolen' => {
+ label => "Report stolen" # loc
+ },
+ },
+ },
);
diff --git a/etc/acl.Pg b/etc/acl.Pg
index a659d8e..0e1de2c 100644
--- a/etc/acl.Pg
+++ b/etc/acl.Pg
@@ -80,6 +80,35 @@ sub acl {
}
}
return (@acls);
+
+{ # START assets ACL
+ my @tables = qw (
+ rtxassets_id_seq
+ RTxAssets
+ rtxcatalogs_id_seq
+ RTxCatalogs
+ );
+
+ my $db_user = RT->Config->Get('DatabaseUser');
+
+ my $sequence_right
+ = ( $dbh->{pg_server_version} >= 80200 )
+ ? "USAGE, SELECT, UPDATE"
+ : "SELECT, UPDATE";
+
+ foreach my $table (@tables) {
+ # Tables are upper-case, sequences are lowercase in @tables
+ if ( $table =~ /^[a-z]/ ) {
+ push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";"
+ }
+ else {
+ push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";"
+ }
+ }
+
+} # END Assets ACL
+
+ return (@acls);
}
1;
diff --git a/etc/initialdata b/etc/initialdata
index dd1daf5..f876940 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -886,3 +886,33 @@ Hour: { $SubscriptionObj->SubValue('Hour') }
},
},
);
+
+require RT::Asset;
+# Create global role groups
+push @Final, sub {
+ foreach my $type (RT::Asset->Roles) {
+ next if $type eq "Owner"; # There's a core global role group for Owner
+
+ my $group = RT::Group->new( RT->SystemUser );
+ my ($ok, $msg) = $group->CreateRoleGroup(
+ Object => RT->System,
+ Name => $type,
+ InsideTransaction => 0,
+ );
+ RT->Logger->error("Couldn't create global asset role group '$type': $msg")
+ unless $ok;
+ }
+};
+
+# Create default catalog
+push @Final, sub {
+ my $catalog = RT::Catalog->new( RT->SystemUser );
+ my ($ok, $msg) = $catalog->Create(
+ Name => "General assets",
+ Description => "The default catalog",
+ );
+ RT->Logger->error("Couldn't create default catalog 'General assets': $msg")
+ unless $ok;
+};
+
+1;
diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index effefc5..4934920 100644
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -487,3 +487,35 @@ Created DATE,
LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
LastUpdated DATE
);
+CREATE SEQUENCE RTxAssets_seq;
+CREATE TABLE RTxAssets (
+ id NUMBER(11,0) CONSTRAINT RTxAssets_key PRIMARY KEY,
+ Name varchar2(255) DEFAULT '',
+ Catalog NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Status varchar2(64) DEFAULT '',
+ Description varchar2(255) DEFAULT '',
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
+
+CREATE INDEX RTxAssetsName ON RTxAssets (LOWER(Name));
+CREATE INDEX RTxAssetsStatus ON RTxAssets (Status);
+CREATE INDEX RTxAssetsCatalog ON RTxAssets (Catalog);
+
+CREATE SEQUENCE RTxCatalogs_seq;
+CREATE TABLE RTxCatalogs (
+ id NUMBER(11,0) CONSTRAINT RTxCatalogs_key PRIMARY KEY,
+ Name varchar2(255) DEFAULT '',
+ Lifecycle varchar2(32) DEFAULT 'assets',
+ Description varchar2(255) DEFAULT '',
+ Disabled NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Creator NUMBER(11,0) DEFAULT 0 NOT NULL,
+ Created DATE,
+ LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL,
+ LastUpdated DATE
+);
+
+CREATE INDEX RTxCatalogsName ON RTxCatalogs (LOWER(Name));
+CREATE INDEX RTxCatalogsDisabled ON RTxCatalogs (Disabled);
diff --git a/etc/schema.Pg b/etc/schema.Pg
index e5e2a04..6459483 100644
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -719,3 +719,37 @@ LastUpdated TIMESTAMP NULL,
PRIMARY KEY (id)
);
+CREATE SEQUENCE rtxassets_id_seq;
+CREATE TABLE RTxAssets (
+ id integer DEFAULT nextval('rtxassets_id_seq'),
+ Name varchar(255) NOT NULL DEFAULT '',
+ Catalog integer NOT NULL DEFAULT 0,
+ Status varchar(64) NOT NULL DEFAULT '',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Creator integer NOT NULL DEFAULT 0,
+ Created timestamp DEFAULT NULL,
+ LastUpdatedBy integer NOT NULL DEFAULT 0,
+ LastUpdated timestamp DEFAULT NULL,
+ PRIMARY KEY (id)
+);
+
+CREATE INDEX RTxAssetsName ON RTxAssets (LOWER(Name));
+CREATE INDEX RTxAssetsStatus ON RTxAssets (Status);
+CREATE INDEX RTxAssetsCatalog ON RTxAssets (Catalog);
+
+CREATE SEQUENCE rtxcatalogs_id_seq;
+CREATE TABLE RTxCatalogs (
+ id integer DEFAULT nextval('rtxcatalogs_id_seq'),
+ Name varchar(255) NOT NULL DEFAULT '',
+ Lifecycle varchar(32) NOT NULL DEFAULT 'assets',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Disabled integer NOT NULL DEFAULT 0,
+ Creator integer NOT NULL DEFAULT 0,
+ Created timestamp DEFAULT NULL,
+ LastUpdatedBy integer NOT NULL DEFAULT 0,
+ LastUpdated timestamp DEFAULT NULL,
+ PRIMARY KEY (id)
+);
+
+CREATE INDEX RTxCatalogsName ON RTxCatalogs (LOWER(Name));
+CREATE INDEX RTxCatalogsDisabled ON RTxCatalogs (Disabled);
diff --git a/etc/schema.SQLite b/etc/schema.SQLite
index c50e5b1..cdd4d4b 100644
--- a/etc/schema.SQLite
+++ b/etc/schema.SQLite
@@ -519,3 +519,33 @@ Created TIMESTAMP NULL,
LastUpdatedBy integer NOT NULL DEFAULT 0,
LastUpdated TIMESTAMP NULL
);
+CREATE TABLE RTxAssets (
+ id INTEGER PRIMARY KEY,
+ Name varchar(255) NOT NULL DEFAULT '',
+ Catalog int(11) NOT NULL DEFAULT 0,
+ Status varchar(64) NOT NULL DEFAULT '',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Creator int(11) NOT NULL DEFAULT 0,
+ Created timestamp DEFAULT NULL,
+ LastUpdatedBy int(11) NOT NULL DEFAULT 0,
+ LastUpdated timestamp DEFAULT NULL
+);
+
+CREATE INDEX RTxAssetsName on RTxAssets (Name);
+CREATE INDEX RTxAssetsStatus ON RTxAssets (Status);
+CREATE INDEX RTxAssetsCatalog ON RTxAssets (Catalog);
+
+CREATE TABLE RTxCatalogs (
+ id INTEGER PRIMARY KEY,
+ Name varchar(255) NOT NULL DEFAULT '',
+ Lifecycle varchar(32) NOT NULL DEFAULT 'assets',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Disabled int2 NOT NULL DEFAULT 0,
+ Creator int(11) NOT NULL DEFAULT 0,
+ Created timestamp DEFAULT NULL,
+ LastUpdatedBy int(11) NOT NULL DEFAULT 0,
+ LastUpdated timestamp DEFAULT NULL
+);
+
+CREATE INDEX RTxCatalogsName on RTxCatalogs (Name);
+CREATE INDEX RTxCatalogsDisabled ON RTxCatalogs (Disabled);
diff --git a/etc/schema.mysql b/etc/schema.mysql
index da14e72..9949fb2 100644
--- a/etc/schema.mysql
+++ b/etc/schema.mysql
@@ -508,3 +508,35 @@ CREATE TABLE ObjectClasses (
LastUpdated datetime default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE RTxAssets (
+ id int(11) NOT NULL AUTO_INCREMENT,
+ Name varchar(255) NOT NULL DEFAULT '',
+ Catalog int(11) NOT NULL DEFAULT 0,
+ Status varchar(64) NOT NULL DEFAULT '',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Creator int(11) NOT NULL DEFAULT 0,
+ Created datetime DEFAULT NULL,
+ LastUpdatedBy int(11) NOT NULL DEFAULT 0,
+ LastUpdated datetime DEFAULT NULL,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE INDEX RTxAssetsName ON RTxAssets (Name);
+CREATE INDEX RTxAssetsStatus ON RTxAssets (Status);
+CREATE INDEX RTxAssetsCatalog ON RTxAssets (Catalog);
+
+CREATE TABLE RTxCatalogs (
+ id int(11) NOT NULL AUTO_INCREMENT,
+ Name varchar(255) NOT NULL DEFAULT '',
+ Lifecycle varchar(32) NOT NULL DEFAULT 'assets',
+ Description varchar(255) NOT NULL DEFAULT '',
+ Disabled int2 NOT NULL DEFAULT 0,
+ Creator int(11) NOT NULL DEFAULT 0,
+ Created datetime DEFAULT NULL,
+ LastUpdatedBy int(11) NOT NULL DEFAULT 0,
+ LastUpdated datetime DEFAULT NULL,
+ PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE INDEX RTxCatalogsName ON RTxCatalogs (Name);
+CREATE INDEX RTxCatalogsDisabled ON RTxCatalogs (Disabled);
commit 0f24385d6628e0a6df6533ab2bd9269bf9975c52
Author: Todd Wade <todd at bestpractical.com>
Date: Thu Jul 23 17:32:26 2015 -0400
assets tests from rt-extension-assets
all tests except the web tests are currenly passing
diff --git a/t/assets/api.t b/t/assets/api.t
index a36d8a8..df64eab 100644
--- a/t/assets/api.t
+++ b/t/assets/api.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
use Test::Warn;
my $catalog;
diff --git a/t/assets/collection.t b/t/assets/collection.t
index 7bf5911..f2c3019 100644
--- a/t/assets/collection.t
+++ b/t/assets/collection.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
my $user = RT::Test->load_or_create_user( Name => 'testuser' );
ok $user->id, "Created user";
diff --git a/t/assets/compile.t b/t/assets/compile.t
index 4ab1d21..ea27bc5 100644
--- a/t/assets/compile.t
+++ b/t/assets/compile.t
@@ -2,9 +2,8 @@ use strict;
use warnings;
use Test::More;
-use lib 'xt/lib';
-use_ok('RT::Extension::Assets::Test');
+use_ok('RT::Test::Assets');
use_ok('RT::Asset');
use_ok('RT::Assets');
use_ok('RT::Catalog');
diff --git a/t/assets/links.t b/t/assets/links.t
index d81fdcc..a9101fe 100644
--- a/t/assets/links.t
+++ b/t/assets/links.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
use Test::Warn;
my $catalog = create_catalog( Name => "BPS" );
diff --git a/t/assets/rights.t b/t/assets/rights.t
index 30394b3..b28b16b 100644
--- a/t/assets/rights.t
+++ b/t/assets/rights.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
my $user = RT::Test->load_or_create_user( Name => 'testuser' );
ok $user->id, "Created user";
diff --git a/t/assets/roles.t b/t/assets/roles.t
index ffaa5d2..1d8a647 100644
--- a/t/assets/roles.t
+++ b/t/assets/roles.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
my $catalog = create_catalog( Name => "A catalog" );
my $asset = create_asset( Name => "Test asset", Catalog => $catalog->id );
diff --git a/t/assets/web.t b/t/assets/web.t
index 5579702..3595e26 100644
--- a/t/assets/web.t
+++ b/t/assets/web.t
@@ -1,8 +1,7 @@
use strict;
use warnings;
-use lib 'xt/lib';
-use RT::Extension::Assets::Test tests => undef;
+use RT::Test::Assets tests => undef;
RT->Config->Set("CustomFieldGroupings",
"RT::Asset" => {
@@ -28,7 +27,7 @@ my %CF = (
Purchased => ".CF-" . $purchased->id . "-Edit",
);
-my ($base, $m) = RT::Extension::Assets::Test->started_ok;
+my ($base, $m) = RT::Test::Assets->started_ok;
ok $m->login, "Logged in agent";
diag "Create basic asset (no CFs)";
-----------------------------------------------------------------------
More information about the rt-commit
mailing list