[Rt-commit] rt branch, 4.4/column-map-validation, created. rt-4.4.1-88-gae43278

Shawn Moore shawn at bestpractical.com
Tue Jul 26 16:29:56 EDT 2016


The branch, 4.4/column-map-validation has been created
        at  ae43278103d06e394cc031858b999ad99a22c267 (commit)

- Log -----------------------------------------------------------------
commit 16d1d22db43a2d6af20f1dae227b72b1dcfe6299
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jul 26 20:25:19 2016 +0000

    Verify each database field has a corresponding ColumnMap entry
    
    New database columns will either need to be blacklisted or get a
    ColumnMap entry before this test will pass.
    
    Fixes: I#22386

diff --git a/t/api/column-map.t b/t/api/column-map.t
new file mode 100644
index 0000000..e5e9ebc
--- /dev/null
+++ b/t/api/column-map.t
@@ -0,0 +1,139 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef;
+
+# This test uses some gymnastics to retrieve the column map out of the
+# ColumnMap components under /Elements/RT__*/. the column map hashref is locked
+# away in a lexical variable and the only way to get access to it is by
+# overriding the GetColumnMapEntry function, which all existant ColumnMap
+# components call. We use RT::Dashboard::Mailer for convenience; it's the
+# easiest way to invoke Mason components outside of a web request. The
+# dashboard mailer expects components to return strings, so we stash the column
+# map hash in %COLUMN_MAP. we have to coalesce multiple calls to
+# GetColumnMapEntry to handle the generic column map and the class-specific one
+# since /Elements/ColumnMap tries both
+
+use RT::Dashboard::Mailer;
+no warnings 'redefine';
+my %COLUMN_MAP;
+*HTML::Mason::Commands::GetColumnMapEntry = sub {
+    my %args = @_;
+    %COLUMN_MAP = (%COLUMN_MAP, %{ $args{Map} });
+    return undef;
+};
+
+my %BLACKLIST = (
+    common   => [
+        'Creator',
+        'Created',
+        'LastUpdatedBy',
+        'LastUpdated',
+        'SortOrder',
+    ],
+
+    'RT::Article' => [
+        'Parent',  # to be removed
+    ],
+
+    'RT::Class' => [
+    ],
+
+    'RT::CustomField' => [
+    ],
+
+    'RT::Group' => [
+        'Domain',    # internal
+        'Instance',  # internal
+    ],
+
+    'RT::Scrip' => [
+        'ScripAction',             # called "Action"
+        'ScripCondition',          # called "Condition"
+        'CustomCommitCode',        # large content
+        'CustomPrepareCode',       # large content
+        'CustomIsApplicableCode',  # large content
+    ],
+
+    'RT::Template' => [
+        'Content',  # large content
+    ],
+
+    'RT::Ticket' => [
+        'IsMerged',  # internal
+    ],
+
+    'RT::Transaction' => [
+        'Data',           # handled by "Description"
+        'NewReference',   # handled by "Description"
+        'OldReference',   # handled by "Description"
+        'ReferenceType',  # handled by "Description"
+    ],
+
+    'RT::User' => [
+        'Password',          # secret
+        'AuthToken',         # secret
+        'SMIMECertificate',  # large content
+        'Comments',          # large content
+        'Signature',         # large content
+    ],
+);
+
+my %COMMON = map { $_ => 1 } @{ $BLACKLIST{common} };
+
+foreach my $endpoint (glob('share/html/Elements/RT__*/ColumnMap')) {
+    # convert the filename to a class name
+    (my $mapname = $endpoint) =~ s|.+/(RT__.+?)/.+|$1|;
+    (my $class = $mapname) =~ s|__|::|;
+
+    # skip RT::Dashboard and RT::SavedSearch
+    next unless $class->isa('RT::Record');
+
+    # ensure class is fully initialized
+    $class->new(RT->SystemUser);
+
+    # get the columns for this class from searchbuilder
+    my @columns = keys %{ $class->_ClassAccessible };
+
+    # get the keys for this class's columnmap
+    %COLUMN_MAP = ();
+    RT::Dashboard::Mailer::RunComponent('/Elements/ColumnMap', Class => $mapname, Name => 'nonexistent');
+    my @keys = keys %COLUMN_MAP;
+    my %has_map = map { $_ => 1 } @keys;
+    my %blacklist = map { $_ => 1 } @{ $BLACKLIST{common} }, @{ $BLACKLIST{$class} || [] };
+
+    for my $column (sort @columns) {
+        if ($has_map{$column} && $blacklist{$column}) {
+            unless ($COMMON{$column}) {
+                ok(0, "blacklisted column '$column' for $class in ColumnMap; either remove from blacklist or ColumnMap");
+            }
+        }
+        elsif ($has_map{$column} && !$blacklist{$column}) {
+            ok(1, "nonblacklisted column '$column' for $class in ColumnMap");
+        }
+        elsif (!$has_map{$column} && $blacklist{$column}) {
+            ok(1, "blacklisted column '$column' for $class in ColumnMap");
+        }
+        elsif (!$has_map{$column} && !$blacklist{$column}) {
+            ok(0, "column '$column' for $class not present in ColumnMap; either add it to $mapname or blacklist it");
+        }
+
+        delete $blacklist{$column};
+    }
+
+    for my $leftover_column (sort keys %blacklist) {
+        next if $COMMON{$leftover_column};
+        ok(0, "saw $leftover_column in blacklist but it's nonexistent in $class; remove from blacklist?");
+    }
+
+    delete $BLACKLIST{$class};
+}
+
+delete $BLACKLIST{common};
+
+for my $leftover_class (sort keys %BLACKLIST) {
+    ok(0, "blacklisted class '$leftover_class' had no column map; remove from blacklist?");
+}
+
+done_testing;
+

commit ae43278103d06e394cc031858b999ad99a22c267
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Tue Jul 26 20:26:06 2016 +0000

    Add missing ColumnMap entries
    
    Discovered by t/api/column-map.t
    
    Fixes: I#22386

diff --git a/share/html/Elements/RT__Article/ColumnMap b/share/html/Elements/RT__Article/ColumnMap
index 23476a9..f987132 100644
--- a/share/html/Elements/RT__Article/ColumnMap
+++ b/share/html/Elements/RT__Article/ColumnMap
@@ -71,6 +71,11 @@ $COLUMN_MAP = {
         title     => 'Class id',                   # loc
         value     => sub { $_[0]->Class },
     },
+    URI => {
+        attribute => 'URI',
+        title     => 'URI',                   # loc
+        value     => sub { $_[0]->URI },
+    },
     ClassName => {
         attribute => 'Class',
         title     => 'Class',                               # loc
@@ -88,7 +93,12 @@ $COLUMN_MAP = {
             }
             return \$topics;
         },
-    }
+    },
+    Disabled => {
+        title     => 'Status', # loc
+        attribute => 'Disabled',
+        value     => sub { return $_[0]->Disabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') },
+    },
 };
 
 </%ONCE>
diff --git a/share/html/Elements/RT__Class/ColumnMap b/share/html/Elements/RT__Class/ColumnMap
index ac0a09a..86af9a6 100644
--- a/share/html/Elements/RT__Class/ColumnMap
+++ b/share/html/Elements/RT__Class/ColumnMap
@@ -67,6 +67,11 @@ my $COLUMN_MAP = {
         attribute => 'Disabled',
         value     => sub { return $_[0]->Disabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') },
     },
+    HotList => {
+        title     => 'HotList', # loc
+        attribute => 'HotList',
+        value     => sub { return $_[0]->HotList ? $_[0]->loc('HotList') : '' },
+    },
 };
 
 
diff --git a/share/html/Elements/RT__CustomField/ColumnMap b/share/html/Elements/RT__CustomField/ColumnMap
index bdc8559..617aaef 100644
--- a/share/html/Elements/RT__CustomField/ColumnMap
+++ b/share/html/Elements/RT__CustomField/ColumnMap
@@ -63,7 +63,7 @@ my $COLUMN_MAP = {
             title     => $c, attribute => $c,
             value     => sub { return $_[0]->$c() },
         } }
-        qw(Name Description Type LookupType Pattern EntryHint)
+        qw(Name Description Type LookupType Pattern EntryHint RenderType ValuesClass CanonicalizeClass)
     ),
     map(
         { my $c = $_; my $short = $c; $short =~ s/^Friendly//;
@@ -73,6 +73,11 @@ my $COLUMN_MAP = {
         } }
         qw(FriendlyLookupType FriendlyType FriendlyPattern)
     ),
+    BasedOn => {
+        title     => 'Based On',
+        attribute => 'BasedOn',
+        value     => sub { return $_[0]->BasedOnObj->Name },
+    },
     MaxValues => {
         title     => 'MaxValues', # loc
         attribute => 'MaxValues',
@@ -81,6 +86,11 @@ my $COLUMN_MAP = {
             return !$v ? $_[0]->loc('unlimited') : $v == 0 ? $_[0]->loc('one') : $v;
         },
     },
+    UniqueValues => {
+        title     => 'UniqueValues', # loc
+        attribute => 'UniqueValues',
+        value     => sub { return $_[0]->UniqueValues ? $_[0]->loc('Unique values') : '' },
+    },
     AddedTo => {
         title     => 'Added', # loc
         value     => sub {
diff --git a/share/html/Elements/RT__Queue/ColumnMap b/share/html/Elements/RT__Queue/ColumnMap
index 2ab8937..8e878e6 100644
--- a/share/html/Elements/RT__Queue/ColumnMap
+++ b/share/html/Elements/RT__Queue/ColumnMap
@@ -57,6 +57,11 @@ my $COLUMN_MAP = {
         attribute => 'Disabled',
         value     => sub { return $_[0]->Disabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') },
     },
+    SLADisabled => {
+        title     => 'SLA Status', # loc
+        attribute => 'SLADisabled',
+        value     => sub { return $_[0]->SLADisabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') },
+    },
     InitialPriority => {
         title     => 'InitialPriority', # loc
         value     => sub { $_[0]->DefaultValue('InitialPriority') || '' },
diff --git a/share/html/Elements/RT__Template/ColumnMap b/share/html/Elements/RT__Template/ColumnMap
index c4bffb7..7c9250a 100644
--- a/share/html/Elements/RT__Template/ColumnMap
+++ b/share/html/Elements/RT__Template/ColumnMap
@@ -73,6 +73,10 @@ my $COLUMN_MAP = {
         title     => 'Queue', # loc
         value     => sub { $_[0]->Queue },
     },
+    Type => {
+        title     => 'Type', # loc
+        value     => sub { $_[0]->Type },
+    },
     IsEmpty => {
         title     => 'Empty', # loc
         value     => sub { $_[0]->IsEmpty? $_[0]->loc('Yes') : $_[0]->loc('No') },
diff --git a/share/html/Elements/RT__User/ColumnMap b/share/html/Elements/RT__User/ColumnMap
index 94c8873..1c0b896 100644
--- a/share/html/Elements/RT__User/ColumnMap
+++ b/share/html/Elements/RT__User/ColumnMap
@@ -137,6 +137,11 @@ my $COLUMN_MAP = {
         attribute   => 'Lang',
         value       => sub { return $_[0]->Lang() },
     },
+    Timezone => {
+        title       => 'Timezone', #loc
+        attribute   => 'Timezone',
+        value       => sub { return $_[0]->Timezone() },
+    },
     FreeformContactInfo => {
         title       => 'Extra Info', #loc
         attribute   => 'FreeformContactInfo',

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


More information about the rt-commit mailing list