View | Details | Raw Unified | Return to bug 17505
Collapse All | Expand All

(-)a/Koha/Patron/MessagePreference.pm (+51 lines)
Lines 311-316 sub store { Link Here
311
    return $self;
311
    return $self;
312
}
312
}
313
313
314
sub TO_JSON {
315
    my ($self, $params) = @_;
316
317
    my $json = {};
318
    my $pref;
319
    $params->{'options'} ||= Koha::Patron::MessagePreferences->get_options;
320
    my $transports = $self->message_transport_types;
321
322
    foreach my $option (@{$params->{'options'}}) {
323
        foreach my $param (keys %$option) {
324
            if ($param eq 'message_attribute_id' &&
325
                    $option->{$param} == $self->message_attribute_id) {
326
                $pref = $option;
327
                last;
328
            }
329
        }
330
    }
331
332
    foreach my $conf (keys %$pref) {
333
        if ($conf =~ /^transport_/) {
334
            my $mtt = $conf =~ s/^transport_//r;
335
            if ($mtt eq 'sms' && !C4::Context->preference('SMSSendDriver')) {
336
                next;
337
            }
338
            if ($mtt eq 'phone' &&
339
                !C4::Context->preference('TalkingTechItivaPhoneNotification')) {
340
                next;
341
            }
342
            $json->{'transport_types'}->{$mtt} = $transports->{$mtt} ?
343
                                Mojo::JSON->true : Mojo::JSON->false;
344
        }
345
    }
346
347
    $json->{'days_in_advance'} = {
348
        configurable => $pref->{'takes_days'} ?
349
                                Mojo::JSON->true : Mojo::JSON->false,
350
        value => defined $self->days_in_advance ?
351
                                0+$self->days_in_advance : undef
352
    };
353
    $json->{'digest'} = {
354
        configurable => $self->wants_digest
355
                            ? $pref->{'has_digest_off'} # can digest be unchecked?
356
                                    ? Mojo::JSON->true : Mojo::JSON->false
357
                            : $pref->{'has_digest'}     # can digest be checked?
358
                                    ? Mojo::JSON->true : Mojo::JSON->false,
359
        value => $self->wants_digest ? Mojo::JSON->true : Mojo::JSON->false
360
    };
361
362
    return $json;
363
}
364
314
=head3 validate
365
=head3 validate
315
366
316
Makes a basic validation for object.
367
Makes a basic validation for object.
(-)a/Koha/Patron/MessagePreferences.pm (+29 lines)
Lines 125-130 sub search_with_message_name { Link Here
125
    return $self->SUPER::search($params, $attributes);
125
    return $self->SUPER::search($params, $attributes);
126
}
126
}
127
127
128
sub TO_JSON {
129
    my ($self) = @_;
130
131
    my $preferences = {};
132
    my $options = $self->get_options;
133
    foreach my $preference ($self->as_list) {
134
        $preferences->{$preference->message_name} = $preference->TO_JSON({
135
            options => $options
136
        });
137
    }
138
139
    # If some preferences are not stored even though they are valid options,
140
    # then add those options to the returned HASHref as well
141
    foreach my $option (@$options) {
142
        unless ($preferences->{$option->{'message_name'}}) {
143
            my $message_attribute_id = Koha::Patron::MessagePreference::Attributes->find({
144
                message_name => $option->{'message_name'}
145
            })->message_attribute_id;
146
            $preferences->{$option->{'message_name'}} =
147
                Koha::Patron::MessagePreference->new({
148
                    borrowernumber => -1,
149
                    message_attribute_id => $message_attribute_id,
150
                })->TO_JSON({ options => $options });
151
        }
152
    }
153
154
    return $preferences;
155
}
156
128
=head3 _type
157
=head3 _type
129
158
130
=cut
159
=cut
(-)a/Koha/REST/V1/Patron/Message/Preference.pm (+169 lines)
Line 0 Link Here
1
package Koha::REST::V1::Patron::Message::Preference;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
22
use Koha::Patron::MessagePreference::Attributes;
23
use Koha::Patron::MessagePreference::Transport::Types;
24
use Koha::Patron::MessagePreference::Transports;
25
use Koha::Patron::MessagePreferences;
26
27
use Try::Tiny;
28
29
sub list {
30
    my $c = shift->openapi->valid_input or return;
31
32
    my $enabled = _check_system_preferences($c);
33
    return $enabled if $enabled;
34
35
    my $borrowernumber = $c->validation->param('borrowernumber');
36
    my $categorycode   = $c->validation->param('categorycode');
37
38
    my $found = $borrowernumber
39
        ? Koha::Patrons->find($borrowernumber)
40
        : Koha::Patron::Categories->find($categorycode);
41
42
    return try {
43
        die unless $found;
44
        my $preferences = Koha::Patron::MessagePreferences->search({
45
            borrowernumber => $borrowernumber,
46
            categorycode   => $categorycode,
47
        });
48
49
        return $c->render(status => 200, openapi => $preferences);
50
    }
51
    catch {
52
        unless ($found) {
53
            return $c->render( status  => 400, openapi => {
54
                error => "Patron or category not found" } );
55
        }
56
57
        $_->rethrow();
58
    };
59
}
60
61
sub edit {
62
    my $c = shift->openapi->valid_input or return;
63
64
    my $enabled = _check_system_preferences($c);
65
    return $enabled if $enabled;
66
67
    my $borrowernumber = $c->validation->param('borrowernumber');
68
    my $categorycode   = $c->validation->param('categorycode');
69
    my $body           = $c->validation->param('body');
70
71
    my $found = $borrowernumber
72
        ? Koha::Patrons->find($borrowernumber)
73
        : Koha::Patron::Categories->find($categorycode);
74
75
    return try {
76
        die unless $found;
77
        foreach my $in (keys %{$body}) {
78
            my $preference =
79
                Koha::Patron::MessagePreferences->find_with_message_name({
80
                    borrowernumber => $borrowernumber,
81
                    categorycode => $categorycode,
82
                    message_name => $in
83
                });
84
85
            # Format wants_digest and days_in_advance values
86
            my $wants_digest = $body->{$in}->{'digest'} ?
87
                $body->{$in}->{'digest'}->{'value'} ? 1 : 0 : 0;
88
            my $days_in_advance = $body->{$in}->{'days_in_advance'} ?
89
                defined $body->{$in}->{'days_in_advance'}->{'value'} ?
90
                    $body->{$in}->{'days_in_advance'}->{'value'} : undef : undef;
91
92
            # HASHref for updated preference
93
            my @transport_types;
94
            foreach my $mtt (keys %{$body->{$in}->{'transport_types'}}) {
95
                if ($body->{$in}->{'transport_types'}->{$mtt}) {
96
                    push @transport_types, $mtt;
97
                }
98
            }
99
            my $edited_preference = {
100
                wants_digest => $wants_digest,
101
                days_in_advance => $days_in_advance,
102
                message_transport_types => \@transport_types
103
            };
104
105
            # Unless a preference for this message name exists, create it
106
            unless ($preference) {
107
                my $attr = Koha::Patron::MessagePreference::Attributes->find({
108
                    message_name => $in
109
                });
110
                unless ($attr) {
111
                    Koha::Exceptions::BadParameter->throw(
112
                        error => "Message type $in not found."
113
                    );
114
                }
115
                $edited_preference->{'message_attribute_id'} =
116
                        $attr->message_attribute_id;
117
                if ($borrowernumber) {
118
                    $edited_preference->{'borrowernumber'}=$found->borrowernumber;
119
                } else {
120
                    $edited_preference->{'categorycode'}=$found->categorycode;
121
                }
122
                Koha::Patron::MessagePreference->new($edited_preference)->store;
123
            }
124
            # Otherwise, modify the already-existing one
125
            else {
126
                $preference->set($edited_preference)->store;
127
            }
128
        }
129
130
        # Finally, return the preferences
131
        my $preferences = Koha::Patron::MessagePreferences->search({
132
            borrowernumber => $borrowernumber,
133
            categorycode   => $categorycode,
134
        });
135
136
        return $c->render( status => 200, openapi => $preferences);
137
    }
138
    catch {
139
        unless ($found) {
140
            return $c->render( status  => 400, openapi => {
141
                error => "Patron or category not found" } );
142
        }
143
        if ($_->isa('Koha::Exceptions::BadParameter')) {
144
            return $c->render( status => 400, openapi => { error => $_->error });
145
        }
146
        if ($_->isa('Koha::Exceptions::Patron::MessagePreference')) {
147
            return $c->render( status => 400, openapi => { error => $_->error });
148
        }
149
150
        $_->rethrow();
151
    };
152
}
153
154
sub _check_system_preferences {
155
    my $c = shift;
156
    if ( ! C4::Context->preference('EnhancedMessagingPreferences') ) {
157
        return $c->render( status => 403, openapi => {
158
            error => "Enhanced messaging preferences are not enabled"});
159
    }
160
    if (($c->stash('is_owner_access') || $c->stash('is_guarantor_access'))
161
        && ! C4::Context->preference('EnhancedMessagingPreferencesOPAC')) {
162
        return $c->render( status => 403, openapi => {
163
            error => "Patrons does not have access to enhanced messaging"
164
                    ." preferences" });
165
    }
166
    return;
167
}
168
169
1;
(-)a/api/v1/swagger/definitions/messagingpreference.yaml (+12 lines)
Line 0 Link Here
1
type: object
2
properties:
3
  Item_Due:
4
    $ref: ./messagingpreference/transport.yaml
5
  Advance_Notice:
6
    $ref: ./messagingpreference/transport.yaml
7
  Hold_Filled:
8
    $ref: ./messagingpreference/transport.yaml
9
  Item_Check_in:
10
    $ref: ./messagingpreference/transport.yaml
11
  Item_Checkout:
12
    $ref: ./messagingpreference/transport.yaml
(-)a/api/v1/swagger/definitions/messagingpreference/transport.yaml (+37 lines)
Line 0 Link Here
1
type: object
2
properties:
3
  transport_types:
4
    type: object
5
    properties:
6
      email:
7
        type: boolean
8
      phone:
9
        type: boolean
10
      print:
11
        type: boolean
12
      sms:
13
        type: boolean
14
  days_in_advance:
15
    type: object
16
    properties:
17
      configurable:
18
        description: Can this message have a value for days in advance
19
        type: boolean
20
        readOnly: true
21
      value:
22
        type:
23
          - integer
24
          - 'null'
25
        minimum: 0
26
        maximum: 30
27
  digest:
28
    type: object
29
    properties:
30
      configurable:
31
        description: Can this message be requested as digest
32
        type: boolean
33
        readOnly: true
34
      value:
35
        description: Is digest enabled
36
        type: boolean
37
additionalProperties: false
(-)a/api/v1/swagger/paths/messagingpreferences.yaml (+117 lines)
Line 0 Link Here
1
/messaging_preferences:
2
  get:
3
    x-mojo-to: Patron::Message::Preference#list
4
    operationId: listMessagingPreferences
5
    x-koha-authorization:
6
      permissions:
7
        borrowers: '*'
8
      allow-owner: true
9
      allow-guarantor: true
10
    tags:
11
      - notices
12
    parameters:
13
      - name: borrowernumber
14
        in: query
15
        description: Patron's borrowernumber
16
        required: false
17
        type: integer
18
      - name: categorycode
19
        in: query
20
        description: Categorycode to find default messaging preferences for a category
21
        required: false
22
        type: string
23
    produces:
24
      - application/json
25
    responses:
26
      '200':
27
        description: A messaging preference object
28
        schema:
29
          $ref: ../definitions/messagingpreference.yaml
30
      '400':
31
        description: Bad parameter given
32
        schema:
33
          $ref: ../definitions/error.yaml
34
      '401':
35
        description: Authentication required
36
        schema:
37
          $ref: ../definitions/error.yaml
38
      '403':
39
        description: Access forbidden
40
        schema:
41
          $ref: ../definitions/error.yaml
42
      '404':
43
        description: Preferences not found
44
        schema:
45
          $ref: ../definitions/error.yaml
46
      '500':
47
        description: Internal error
48
        schema:
49
          $ref: ../definitions/error.yaml
50
      '503':
51
        description: Under maintenance
52
        schema:
53
          $ref: ../definitions/error.yaml
54
  put:
55
    x-mojo-to: Patron::Message::Preference#edit
56
    operationId: editMessagingPreferences
57
    description: >-
58
      Modifies patron's messaging preferences. Please note that not all
59
      parameters defined in body object's documentation can actually be used for
60
      each message option due to dynamic configuration. Make a GET request first
61
      to see whether an option is configurable or if message transport type is
62
      available.
63
    x-koha-authorization:
64
      permissions:
65
        borrowers: '*'
66
      allow-owner: true
67
      allow-guarantor: true
68
    tags:
69
      - notices
70
    parameters:
71
      - name: borrowernumber
72
        in: query
73
        description: Patron's borrowernumber
74
        required: false
75
        type: integer
76
      - name: categorycode
77
        in: query
78
        description: Categorycode to find default messaging preferences for a category
79
        required: false
80
        type: string
81
      - name: body
82
        in: body
83
        description: A JSON object containing information on messaging preferences
84
        required: true
85
        schema:
86
          $ref: ../definitions/messagingpreference.yaml
87
    produces:
88
      - application/json
89
    responses:
90
      '200':
91
        description: A messaging preferences object
92
        schema:
93
          $ref: ../definitions/messagingpreference.yaml
94
      '400':
95
        description: Missing or wrong parameters
96
        schema:
97
          $ref: ../definitions/error.yaml
98
      '401':
99
        description: Authentication required
100
        schema:
101
          $ref: ../definitions/error.yaml
102
      '403':
103
        description: Access forbidden
104
        schema:
105
          $ref: ../definitions/error.yaml
106
      '404':
107
        description: Patron or category not found
108
        schema:
109
          $ref: ../definitions/error.yaml
110
      '500':
111
        description: Internal error
112
        schema:
113
          $ref: ../definitions/error.yaml
114
      '503':
115
        description: Under maintenance
116
        schema:
117
          $ref: ../definitions/error.yaml
(-)a/api/v1/swagger/swagger.yaml (+4 lines)
Lines 76-81 definitions: Link Here
76
    $ref: ./definitions/job.yaml
76
    $ref: ./definitions/job.yaml
77
  library:
77
  library:
78
    $ref: ./definitions/library.yaml
78
    $ref: ./definitions/library.yaml
79
  messagingpreference:
80
    $ref: ./definitions/messagingpreference.yaml
79
  order:
81
  order:
80
    $ref: ./definitions/order.yaml
82
    $ref: ./definitions/order.yaml
81
  patron:
83
  patron:
Lines 281-286 paths: Link Here
281
    $ref: ./paths/libraries.yaml#/~1libraries
283
    $ref: ./paths/libraries.yaml#/~1libraries
282
  "/libraries/{library_id}":
284
  "/libraries/{library_id}":
283
    $ref: "./paths/libraries.yaml#/~1libraries~1{library_id}"
285
    $ref: "./paths/libraries.yaml#/~1libraries~1{library_id}"
286
  "/messaging_preferences":
287
    $ref: "./paths/messagingpreferences.yaml#/~1messaging_preferences"
284
  "/oauth/login/{provider_code}/{interface}":
288
  "/oauth/login/{provider_code}/{interface}":
285
    $ref: ./paths/oauth.yaml#/~1oauth~1login~1{provider_code}~1{interface}
289
    $ref: ./paths/oauth.yaml#/~1oauth~1login~1{provider_code}~1{interface}
286
  /oauth/token:
290
  /oauth/token:
(-)a/t/db_dependent/api/v1/messagingpreferences.t (-1 / +420 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# Copyright Koha-Suomi Oy 2017
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
23
use Test::More tests => 2;
24
use Test::Mojo;
25
use t::lib::Mocks;
26
use t::lib::TestBuilder;
27
28
use C4::Auth;
29
use C4::Context;
30
31
use Koha::Database;
32
use Koha::Notice::Templates;
33
use Koha::Patron::MessagePreferences;
34
use Koha::Patron::MessagePreference::Attributes;
35
use Koha::Patron::MessagePreference::Transport;
36
use Koha::Patron::MessagePreference::Transport::Types;
37
38
my $schema  = Koha::Database->new->schema;
39
my $builder = t::lib::TestBuilder->new;
40
41
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
42
# this affects the other REST api tests
43
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
44
45
my $remote_address = '127.0.0.1';
46
my $t              = Test::Mojo->new('Koha::REST::V1');
47
48
subtest 'list() tests' => sub {
49
    plan tests => 34;
50
51
    $schema->storage->txn_begin;
52
53
    my $path = '/api/v1/messaging_preferences';
54
55
    my ($patron, $session) = create_user_and_session();
56
    my $borrowernumber = $patron->borrowernumber;
57
    my $categorycode   = $patron->categorycode;
58
    my ($another_patron, undef) = create_user_and_session();
59
    my ($librarian, $librarian_session) = create_user_and_session({
60
        flags => 16
61
    });
62
    my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({
63
        patron => $patron
64
    });
65
    my ($preference2, $mtt1_2, $mtt2_2) = build_a_test_category_preference({
66
        patron => $patron
67
    });
68
69
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 1);
70
    my $tx = $t->ua->build_tx(GET => $path);
71
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
72
    $t->request_ok($tx)
73
      ->status_is(401);
74
75
    $tx = $t->ua->build_tx(GET => "$path?borrowernumber="
76
                           .$another_patron->borrowernumber);
77
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
78
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
79
    $t->request_ok($tx)
80
      ->status_is(403);
81
82
    $tx = $t->ua->build_tx(GET => "$path?categorycode=$categorycode");
83
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
84
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
85
    $t->request_ok($tx)
86
      ->status_is(403);
87
88
    $tx = $t->ua->build_tx(GET => $path);
89
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
90
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
91
    $t->request_ok($tx)
92
      ->status_is(400)
93
      ->json_is('/error', 'Patron or category not found');
94
95
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 0);
96
    $tx = $t->ua->build_tx(GET => "$path?borrowernumber=$borrowernumber");
97
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
98
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
99
    $t->request_ok($tx)
100
      ->status_is(403)
101
      ->json_is('/error' => 'Enhanced messaging preferences are not enabled');
102
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 1);
103
104
    $tx = $t->ua->build_tx(GET => "$path?borrowernumber=$borrowernumber");
105
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
106
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
107
    $t->request_ok($tx)
108
      ->status_is(200)
109
      ->json_has('/'.$preference->message_name);
110
111
    $tx = $t->ua->build_tx(GET => "$path?borrowernumber=$borrowernumber");
112
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
113
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
114
    $t->request_ok($tx)
115
      ->status_is(200)
116
      ->json_has('/'.$preference->message_name)
117
      ->json_has('/'.$preference2->message_name)
118
      ->json_is('/'.$preference->message_name.'/transport_types/'
119
                .$mtt1->message_transport_type => Mojo::JSON->true)
120
      ->json_is('/'.$preference->message_name.'/transport_types/'
121
                .$mtt2->message_transport_type => Mojo::JSON->true)
122
      ->json_is('/'.$preference->message_name.'/days_in_advance/configurable'
123
                => Mojo::JSON->false)
124
      ->json_is('/'.$preference->message_name.'/days_in_advance/value'
125
                => undef)
126
      ->json_is('/'.$preference->message_name.'/digest/configurable'
127
                => Mojo::JSON->false)
128
      ->json_is('/'.$preference->message_name.'/digest/value'
129
                => Mojo::JSON->false);
130
131
    $tx = $t->ua->build_tx(GET => "$path?categorycode=$categorycode");
132
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
133
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
134
    $t->request_ok($tx)
135
      ->status_is(200)
136
      ->json_has('/'.$preference->message_name)
137
      ->json_has('/'.$preference2->message_name)
138
      ->json_is('/'.$preference2->message_name.'/transport_types/'
139
                .$mtt1_2->message_transport_type => Mojo::JSON->true)
140
      ->json_is('/'.$preference2->message_name.'/transport_types/'
141
                .$mtt2_2->message_transport_type => Mojo::JSON->true)
142
      ->json_is('/'.$preference2->message_name.'/days_in_advance/configurable'
143
                => Mojo::JSON->false)
144
      ->json_is('/'.$preference2->message_name.'/days_in_advance/value'
145
                => undef)
146
      ->json_is('/'.$preference2->message_name.'/digest/value'
147
                => Mojo::JSON->false);
148
149
    $schema->storage->txn_rollback;
150
};
151
152
subtest 'edit() tests' => sub {
153
    plan tests => 28;
154
155
    $schema->storage->txn_begin;
156
157
    my $path = '/api/v1/messaging_preferences';
158
159
    my ($patron, $session) = create_user_and_session();
160
    my ($librarian, $librarian_session) = create_user_and_session({
161
        flags => 16
162
    });
163
    my ($another_patron, undef) = create_user_and_session();
164
    my $borrowernumber = $patron->borrowernumber;
165
    my $categorycode   = $patron->categorycode;
166
    my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({
167
        patron => $patron
168
    });
169
    my ($preference2, $mtt1_2, $mtt2_2) = build_a_test_category_preference({
170
        patron => $patron
171
    });
172
173
    my $edited_preference = {
174
        $preference->message_name => {
175
            digest => {
176
                value => Mojo::JSON->true
177
            },
178
            days_in_advance => {
179
                value => 15
180
            },
181
            transport_types => {
182
                $mtt1->message_transport_type => Mojo::JSON->true,
183
                $mtt2->message_transport_type => Mojo::JSON->false
184
            }
185
        }
186
    };
187
188
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 1);
189
    my $tx = $t->ua->build_tx(PUT => $path => json => $edited_preference);
190
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
191
    $t->request_ok($tx)
192
      ->status_is(401);
193
194
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber="
195
                           .$another_patron->borrowernumber
196
                           => json => $edited_preference);
197
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
198
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
199
    $t->request_ok($tx)
200
      ->status_is(403);
201
202
    $tx = $t->ua->build_tx(PUT => "$path?categorycode=$categorycode"
203
                           => json => $edited_preference);
204
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
205
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
206
    $t->request_ok($tx)
207
      ->status_is(403);
208
209
    $tx = $t->ua->build_tx(PUT => $path => json => $edited_preference);
210
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
211
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
212
    $t->request_ok($tx)
213
      ->status_is(400)
214
      ->json_is('/error', 'Patron or category not found');
215
216
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 0);
217
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
218
                           json => $edited_preference);
219
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
220
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
221
    $t->request_ok($tx)
222
      ->status_is(403)
223
      ->json_is('/error' => 'Enhanced messaging preferences are not enabled');
224
    t::lib::Mocks::mock_preference('EnhancedMessagingPreferences', 1);
225
226
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
227
                           json => $edited_preference);
228
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
229
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
230
    $t->request_ok($tx)
231
      ->status_is(400)
232
      ->json_like('/error' => qr/^days_in_advance cannot/);
233
234
    $edited_preference->{$preference->message_name}->
235
                                        {days_in_advance}->{value} = undef;
236
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
237
                           json => $edited_preference);
238
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
239
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
240
    $t->request_ok($tx)
241
      ->status_is(400)
242
      ->json_like('/error' => qr/igest cannot be selected/);
243
244
    $edited_preference->{$preference->message_name}->{digest}->{value}
245
                        = Mojo::JSON->false;
246
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
247
                           json => $edited_preference);
248
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
249
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
250
    $t->request_ok($tx)
251
      ->status_is(200)
252
      ->json_is('/'.$preference->message_name.'/transport_types/'.
253
                $mtt2->message_transport_type => Mojo::JSON->false)
254
      ->json_is('/'.$preference->message_name.'/transport_types/'.
255
                $mtt1->message_transport_type => Mojo::JSON->true);
256
257
    Koha::Patron::MessagePreference::Transports->search({
258
        message_attribute_id => $preference->message_attribute_id,
259
    })->update({ is_digest => 1 });
260
    $edited_preference->{$preference->message_name}->{digest}->{value}
261
                        = Mojo::JSON->true;
262
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
263
                           json => $edited_preference);
264
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
265
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
266
    $t->request_ok($tx)
267
      ->status_is(200)
268
      ->json_is('/'.$preference->message_name.'/digest/value' => Mojo::JSON->true);
269
270
    # Test librarian access
271
    $tx = $t->ua->build_tx(PUT => "$path?borrowernumber=$borrowernumber" =>
272
                           json => $edited_preference);
273
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
274
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
275
    $t->request_ok($tx)
276
      ->status_is(200)
277
      ->json_is('/'.$preference->message_name.'/digest/value' => Mojo::JSON->true);
278
279
    $schema->storage->txn_rollback;
280
};
281
282
sub create_user_and_session {
283
    my ($params) = @_;
284
285
    my $categorycode = $builder->build({ source => 'Category' })->{categorycode};
286
    my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
287
288
    my $borrower = $builder->build({
289
        source => 'Borrower',
290
        value => {
291
            branchcode   => $branchcode,
292
            categorycode => $categorycode,
293
            flags        => $params->{'flags'} || 0,
294
        }
295
    });
296
297
    my $session = C4::Auth::get_session('');
298
    $session->param('number', $borrower->{ borrowernumber });
299
    $session->param('id', $borrower->{ userid });
300
    $session->param('ip', '127.0.0.1');
301
    $session->param('lasttime', time());
302
    $session->flush;
303
    my $patron = Koha::Patrons->find($borrower->{borrowernumber});
304
305
    return ($patron, $session);
306
}
307
308
309
sub build_a_test_attribute {
310
    my ($params) = @_;
311
312
    $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0
313
                            ? 1 : 0;
314
315
    my $attribute = $builder->build({
316
        source => 'MessageAttribute',
317
        value => $params,
318
    });
319
320
    return Koha::Patron::MessagePreference::Attributes->find(
321
        $attribute->{message_attribute_id}
322
    );
323
}
324
325
sub build_a_test_category {
326
    my $categorycode   = $builder->build({
327
        source => 'Category' })->{categorycode};
328
329
    return Koha::Patron::Categories->find($categorycode);
330
}
331
332
sub build_a_test_letter {
333
    my ($params) = @_;
334
335
    my $mtt = $params->{mtt} ? $params->{mtt} : 'email';
336
    my $branchcode     = $builder->build({
337
        source => 'Branch' })->{branchcode};
338
    my $letter = $builder->build({
339
        source => 'Letter',
340
        value => {
341
            branchcode => '',
342
            is_html => 0,
343
            message_transport_type => $mtt
344
        }
345
    });
346
347
    return Koha::Notice::Templates->find({
348
        module     => $letter->{module},
349
        code       => $letter->{code},
350
        branchcode => $letter->{branchcode},
351
    });
352
}
353
354
sub build_a_test_transport_type {
355
    my $mtt = $builder->build({
356
        source => 'MessageTransportType' });
357
358
    return Koha::Patron::MessagePreference::Transport::Types->find(
359
        $mtt->{message_transport_type}
360
    );
361
}
362
363
sub build_a_test_category_preference {
364
    my ($params) = @_;
365
366
    my $patron = $params->{patron};
367
    my $attr = $params->{attr}
368
                    ? $params->{attr}
369
                    : build_a_test_attribute($params->{days_in_advance});
370
371
    my $letter = $params->{letter} ? $params->{letter} : build_a_test_letter();
372
    my $mtt1 = $params->{mtt1} ? $params->{mtt1} : build_a_test_transport_type();
373
    my $mtt2 = $params->{mtt2} ? $params->{mtt2} : build_a_test_transport_type();
374
375
    Koha::Patron::MessagePreference::Transport->new({
376
        message_attribute_id   => $attr->message_attribute_id,
377
        message_transport_type => $mtt1->message_transport_type,
378
        is_digest              => $params->{digest} ? 1 : 0,
379
        letter_module          => $letter->module,
380
        letter_code            => $letter->code,
381
    })->store;
382
383
    Koha::Patron::MessagePreference::Transport->new({
384
        message_attribute_id   => $attr->message_attribute_id,
385
        message_transport_type => $mtt2->message_transport_type,
386
        is_digest              => $params->{digest} ? 1 : 0,
387
        letter_module          => $letter->module,
388
        letter_code            => $letter->code,
389
    })->store;
390
391
    my $default = Koha::Patron::MessagePreference->new({
392
        categorycode         => $patron->categorycode,
393
        message_attribute_id => $attr->message_attribute_id,
394
        wants_digest         => $params->{digest} ? 1 : 0,
395
        days_in_advance      => $params->{days_in_advance}
396
                                 ? $params->{days_in_advance} : undef,
397
    })->store;
398
399
    Koha::Patron::MessagePreference::Transport::Preference->new({
400
        borrower_message_preference_id => $default->borrower_message_preference_id,
401
        message_transport_type         => $mtt1->message_transport_type,
402
    })->store;
403
    Koha::Patron::MessagePreference::Transport::Preference->new({
404
        borrower_message_preference_id => $default->borrower_message_preference_id,
405
        message_transport_type         => $mtt2->message_transport_type,
406
    })->store;
407
408
    return ($default, $mtt1, $mtt2);
409
}
410
411
sub build_a_test_complete_preference {
412
    my ($params) = @_;
413
414
    my ($default, $mtt1, $mtt2) = build_a_test_category_preference($params);
415
    my $patron = $params->{patron};
416
    $patron->set_default_messaging_preferences;
417
    return (Koha::Patron::MessagePreferences->search({
418
        borrowernumber => $patron->borrowernumber
419
    })->next, $mtt1, $mtt2);
420
}

Return to bug 17505