summaryrefslogtreecommitdiff
path: root/rt/t/customfields/transaction_searching.t
blob: 0958b5ea66a4d60173988028db3255fd663bf67e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use strict;
use warnings;

use RT::Test tests => 'no_declare';

my $initialdata = RT::Test::get_relocatable_file("transaction-cfs" => "..", "data", "initialdata");
my ($rv, $msg) = RT->DatabaseHandle->InsertData( $initialdata, undef, disconnect_after => 0 );
ok($rv, "Inserted test data from $initialdata")
    or diag "Error: $msg";

create_tickets(
    Spam        => {  },
    Coffee      => { Billable   => "No", },
    Phone       => { Billable   => "Yes", Who => ["Telecom", "Information Technology"], When => "2013-06-25", Location => "Geology" },
    Stacks      => { Billable   => "Yes", Who => "Library", When => "2013-06-01" },
    Benches     => { Billable   => "Yes", Location => "Outdoors" },
);

# Sanity check
results_are("CF.Location IS NOT NULL", [qw( Phone Benches )]);
results_are("CF.Location IS NULL",     [qw( Spam Coffee Stacks )]);

# TODO: Ideal behaviour of TxnCF IS NULL not yet determined
#results_are("TxnCF.Billable IS NULL", [qw( Spam )]);

results_are("TxnCF.Billable IS NOT NULL", [qw( Coffee Phone Stacks Benches )]);
results_are("TxnCF.Billable = 'No'", [qw( Coffee )]);
results_are("TxnCF.Billable = 'Yes'", [qw( Phone Stacks Benches )]);
results_are("TxnCF.Billable = 'Yes' AND CF.Location IS NOT NULL", [qw( Phone Benches )]);
results_are("TxnCF.Billable = 'Yes' AND CF.Location = 'Outdoors'", [qw( Benches )]);
results_are("TxnCF.Billable = 'Yes' AND CF.Location LIKE 'o'", [qw( Phone Benches )]);

results_are("TxnCF.Who = 'Telecom' OR TxnCF.Who = 'Library'", [qw( Phone Stacks )]);

# TODO: Negative searching finds tickets with at least one txn doesn't have the value
#results_are("TxnCF.Who != 'Library'", [qw( Spam Coffee Phone Benches )]);

results_are("TxnCF.When > '2013-06-24'", [qw( Phone )]);
results_are("TxnCF.When < '2013-06-24'", [qw( Stacks )]);
results_are("TxnCF.When >= '2013-06-01' and TxnCF.When <= '2013-06-30'", [qw( Phone Stacks )]);

results_are("TxnCF.Who LIKE 'e'", [qw( Phone )]);

# TODO: Negative searching finds tickets with at least one txn doesn't have the value
#results_are("TxnCF.Who NOT LIKE 'e'", [qw( Spam Coffee Stacks Benches )]);

results_are("TxnCF.Who NOT LIKE 'e' and TxnCF.Who IS NOT NULL", [qw( Stacks )]);


# Multiple CFs with same name applied to different queues
clear_tickets();
create_tickets(
    BlueNone    => { Queue => "Blues" },
    PurpleNone  => { Queue => "Purples" },

    Blue        => { Queue => "Blues",   Color => "Blue" },
    Purple      => { Queue => "Purples", Color => "Purple" },
);

# Queue-specific txn CFs
results_are("TxnCF.Blues.{Color} = 'Blue'", [qw( Blue )]);
results_are("TxnCF.Blues.{Color} = 'Purple'", []);

# Multiple transaction CFs by name
results_are("TxnCF.{Color} IS NOT NULL", [qw( Blue Purple )]);
results_are("TxnCF.{Color} = 'Blue'", [qw( Blue )]);
results_are("TxnCF.{Color} = 'Purple'", [qw( Purple )]);
results_are("TxnCF.{Color} LIKE 'e'", [qw( Blue Purple )]);

done_testing;

sub results_are {
    local $Test::Builder::Level = $Test::Builder::Level + 1;

    my $query    = shift;
    my $expected = shift;
    my %expected = map { $_ => 1 } @$expected;
    my @unexpected;

    my $tickets = RT::Tickets->new(RT->SystemUser);
    my ($ok, $msg) = $tickets->FromSQL($query);
    ok($ok, "Searched: $query")
        or return diag $msg;
    for my $t (@{$tickets->ItemsArrayRef || []}) {
        if (delete $expected{$t->Subject}) {
            ok(1, "Found expected ticket ".$t->Subject);
        } else {
            push @unexpected, $t->Subject;
        }
    }
    ok(0, "Didn't find expected ticket $_")
        for grep $expected{$_}, @$expected;
    ok(0, "Found unexpected tickets: ".join ", ", @unexpected)
        if @unexpected;
}

sub create_tickets {
    my %ticket = @_;
    for my $subject (sort keys %ticket) {
        my %data = %{$ticket{$subject}};
        my $location = delete $data{Location};
        my $queue    = delete $data{Queue} || "General";

        my $ticket = RT::Ticket->new( RT->SystemUser );
        my ($ok, $msg) = $ticket->Create(
            Queue   => $queue,
            Subject => $subject,
        );
        ok($ticket->id, "Created ticket: $msg") or next;

        if ($location) {
            ($ok, $msg) = $ticket->AddCustomFieldValue( Field => "Location", Value => $location );
            ok($ok, "Added Location: $msg") or next;
        }

        my ($txnid, $txnmsg, $txn) = $ticket->Correspond( Content => "test transaction" );
        unless ($txnid) {
            RT->Logger->error("Unable to correspond on ticket $ok: $txnmsg");
            next;
        }
        for my $name (sort keys %data) {
            my $values = ref $data{$name} ? $data{$name} : [$data{$name}];
            for my $v (@$values) {
                ($ok, $msg) = $txn->_AddCustomFieldValue(
                    Field => $name,
                    Value => $v,
                    RecordTransaction => 0
                );
                ok($ok, "Added txn CF $name value '$v'")
                    or diag $msg;
            }
        }
    }
}

sub clear_tickets {
    my $tickets = RT::Tickets->new( RT->SystemUser );
    $tickets->FromSQL("id > 0");
    $_->SetStatus("deleted") for @{$tickets->ItemsArrayRef};
}