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

(-)a/Koha/REST/V1/Patrons.pm (-1 lines)
Lines 121-127 sub add { Link Here
121
                            module      => 'members',
121
                            module      => 'members',
122
                            letter_code => 'WELCOME',
122
                            letter_code => 'WELCOME',
123
                            branchcode  => $patron->branchcode,
123
                            branchcode  => $patron->branchcode,
124
                            ,
125
                            lang   => $patron->lang || 'default',
124
                            lang   => $patron->lang || 'default',
126
                            tables => {
125
                            tables => {
127
                                'branches'  => $patron->branchcode,
126
                                'branches'  => $patron->branchcode,
(-)a/t/db_dependent/api/v1/patrons.t (-20 / +141 lines)
Lines 54-67 $mocked_letters->mock( Link Here
54
        return 1;
54
        return 1;
55
    }
55
    }
56
);
56
);
57
my $message_has_content = 1;
57
my $letter_enqueued;
58
my $letter_enqueued;
58
$mocked_letters->mock(
59
$mocked_letters->mock(
59
    'EnqueueLetter',
60
    'EnqueueLetter',
60
    sub {
61
    sub {
61
        $letter_enqueued = 1;
62
        $letter_enqueued = $message_has_content ? 1 : 0;
62
63
63
        # return a 'message_id'
64
        # return a 'message_id'
64
        return 42;
65
        return $message_has_content ? 42 : undef;
65
    }
66
    }
66
);
67
);
67
$mocked_letters->mock(
68
$mocked_letters->mock(
Lines 427-433 subtest 'add() tests' => sub { Link Here
427
    $schema->storage->txn_rollback;
428
    $schema->storage->txn_rollback;
428
429
429
    subtest 'librarian access tests' => sub {
430
    subtest 'librarian access tests' => sub {
430
        plan tests => 25;
431
        plan tests => 37;
431
432
432
        $schema->storage->txn_begin;
433
        $schema->storage->txn_begin;
433
434
Lines 471-481 subtest 'add() tests' => sub { Link Here
471
472
472
        $newpatron->{library_id} = $deleted_library_id;
473
        $newpatron->{library_id} = $deleted_library_id;
473
474
475
        # Test duplicate userid constraint
474
        $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(400)
476
        $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(400)
475
            ->json_is( '/error' => "Problem with " . $newpatron->{userid} );
477
            ->json_is( '/error' => "Problem with " . $newpatron->{userid} );
476
478
477
        $newpatron->{library_id} = $patron->branchcode;
479
        $newpatron->{library_id} = $patron->branchcode;
478
480
481
        # Test duplicate cardnumber constraint
482
        $newpatron->{userid} = undef;    # force regeneration
483
        warning_like {
484
            $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(409)
485
                ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' )
486
                ->json_like( '/conflict' => qr/(borrowers\.)?cardnumber/ );
487
        }
488
        qr/DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key '(borrowers\.)?cardnumber'/;
489
479
        # Create a library just to make sure its ID doesn't exist on the DB
490
        # Create a library just to make sure its ID doesn't exist on the DB
480
        my $category_to_delete  = $builder->build_object( { class => 'Koha::Patron::Categories' } );
491
        my $category_to_delete  = $builder->build_object( { class => 'Koha::Patron::Categories' } );
481
        my $deleted_category_id = $category_to_delete->id;
492
        my $deleted_category_id = $category_to_delete->id;
Lines 511-516 subtest 'add() tests' => sub { Link Here
511
        # Set a date-time field
522
        # Set a date-time field
512
        $newpatron->{last_seen} = output_pref( { dt => dt_from_string->add( days => -1 ), dateformat => 'rfc3339' } );
523
        $newpatron->{last_seen} = output_pref( { dt => dt_from_string->add( days => -1 ), dateformat => 'rfc3339' } );
513
524
525
        # Test welcome email sending with AutoEmailNewUser = 0 but welcome_yes override
514
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 0 );
526
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 0 );
515
        $letter_enqueued = 0;
527
        $letter_enqueued = 0;
516
        $t->post_ok(
528
        $t->post_ok(
Lines 524-542 subtest 'add() tests' => sub { Link Here
524
            ->json_is( '/last_seen'     => $newpatron->{last_seen},     'Date-time field set (Bug 28585)' );
536
            ->json_is( '/last_seen'     => $newpatron->{last_seen},     'Date-time field set (Bug 28585)' );
525
537
526
        my $p = Koha::Patrons->find( { cardnumber => $newpatron->{cardnumber} } );
538
        my $p = Koha::Patrons->find( { cardnumber => $newpatron->{cardnumber} } );
527
        is( $letter_enqueued, 1, "Patron got welcome notice" );
539
        is( $letter_enqueued, 1, "Patron got welcome notice due to welcome_yes override" );
528
540
529
        $newpatron->{userid} = undef;    # force regeneration
541
        # Test when AutoEmailNewUser = 1 but welcome_no override
530
        warning_like {
542
        $newpatron->{cardnumber} = "NewCard12345";
531
            $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(409)
543
        $newpatron->{userid}     = "newuserid";
532
                ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' )
544
        $letter_enqueued         = 0;
533
                ->json_like( '/conflict' => qr/(borrowers\.)?cardnumber/ );
545
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 1 );
534
        }
546
        $t->post_ok(
535
        qr/DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key '(borrowers\.)?cardnumber'/;
547
            "//$userid:$password@/api/v1/patrons" => { 'x-koha-override' => 'welcome_no' } => json => $newpatron )
548
            ->status_is( 201, 'Patron created successfully with welcome_no override' );
549
        is( $letter_enqueued, 0, "No welcome notice sent due to welcome_no override" );
550
551
        # Test when AutoEmailNewUser = 1 with no overrides
552
        $newpatron->{cardnumber} = "NewCard54321";
553
        $newpatron->{userid}     = "newuserid2";
554
        $letter_enqueued         = 0;
555
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 1 );
556
        $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )
557
            ->status_is( 201, 'Patron created successfully with AutoEmailNewUser = 1' );
558
        is( $letter_enqueued, 1, "Welcome notice sent due to AutoEmailNewUser = 1" );
559
560
        # Test case when patron has no valid email address
561
        $mocked_patron->mock( 'notice_email_address', sub { return undef; } );
562
        $newpatron->{cardnumber} = "NewCard99999";
563
        $newpatron->{userid}     = "newuserid3";
564
        $letter_enqueued         = 0;
565
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 1 );
566
        $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )
567
            ->status_is( 201, 'Patron created successfully but email will not be sent' );
568
        is( $letter_enqueued, 0, "No welcome notice sent due to missing email address" );
569
        $mocked_patron->unmock('notice_email_address');
570
571
        # Test case when notice template returns an empty string
572
        $newpatron->{cardnumber} = "NewCardPidgeon";
573
        $newpatron->{userid}     = "newuserid4";
574
        $letter_enqueued         = 0;
575
        $message_has_content     = 0;
576
        t::lib::Mocks::mock_preference( 'AutoEmailNewUser', 1 );
577
        $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )
578
            ->status_is( 201, 'Patron created successfully with AutoEmailNewUser = 1 and empty WELCOME notice' );
579
        is( $letter_enqueued, 0, "Welcome not sent as it would be empty" );
580
        $message_has_content = 1;
536
581
537
        subtest 'extended_attributes handling tests' => sub {
582
        subtest 'extended_attributes handling tests' => sub {
538
583
539
            plan tests => 19;
584
            plan tests => 25;
540
585
541
            $mocked_patron->mock(
586
            $mocked_patron->mock(
542
                'extended_attributes',
587
                'extended_attributes',
Lines 645-650 subtest 'add() tests' => sub { Link Here
645
                    }
690
                    }
646
                }
691
                }
647
            );
692
            );
693
            my $non_repeatable = $builder->build_object(
694
                {
695
                    class => 'Koha::Patron::Attribute::Types',
696
                    value => {
697
                        mandatory     => 0,
698
                        repeatable    => 0,
699
                        unique_id     => 0,
700
                        category_code => 'ST'
701
                    }
702
                }
703
            );
704
            my $unique_id = $builder->build_object(
705
                {
706
                    class => 'Koha::Patron::Attribute::Types',
707
                    value => {
708
                        mandatory     => 0,
709
                        repeatable    => 1,
710
                        unique_id     => 1,
711
                        category_code => 'ST'
712
                    }
713
                }
714
            );
648
715
649
            my $patron_id = $t->post_ok(
716
            my $patron_id = $t->post_ok(
650
                "//$userid:$password@/api/v1/patrons" => json => {
717
                "//$userid:$password@/api/v1/patrons" => json => {
Lines 655-676 subtest 'add() tests' => sub { Link Here
655
                    "city"                => "Konstanz",
722
                    "city"                => "Konstanz",
656
                    "library_id"          => "MPL",
723
                    "library_id"          => "MPL",
657
                    "extended_attributes" => [
724
                    "extended_attributes" => [
658
                        { type => $repeatable_1->code, value => 'a' },
725
                        { type => $repeatable_1->code,   value => 'a' },
659
                        { type => $repeatable_1->code, value => 'b' },
726
                        { type => $repeatable_1->code,   value => 'b' },
660
                        { type => $repeatable_1->code, value => 'c' },
727
                        { type => $repeatable_1->code,   value => 'c' },
661
                        { type => $repeatable_2->code, value => 'd' },
728
                        { type => $repeatable_2->code,   value => 'd' },
662
                        { type => $repeatable_2->code, value => 'e' }
729
                        { type => $repeatable_2->code,   value => 'e' },
730
                        { type => $non_repeatable->code, value => 'single' },
731
                        { type => $unique_id->code,      value => 'unique1' }
663
                    ]
732
                    ]
664
                }
733
                }
665
            )->status_is( 201, 'Patron added' )->tx->res->json->{patron_id};
734
            )->status_is( 201, 'Patron added' )->tx->res->json->{patron_id};
666
            my $extended_attributes =
735
            my $extended_attributes =
667
                join( ' ', sort map { $_->attribute } Koha::Patrons->find($patron_id)->extended_attributes->as_list );
736
                join( ' ', sort map { $_->attribute } Koha::Patrons->find($patron_id)->extended_attributes->as_list );
668
            is( $extended_attributes, 'a b c d e', 'Extended attributes are stored correctly' );
737
            is( $extended_attributes, 'a b c d e single unique1', 'Extended attributes are stored correctly' );
738
739
            # Test non-repeatable constraint in real scenario
740
            $t->post_ok(
741
                "//$userid:$password@/api/v1/patrons" => json => {
742
                    "firstname"           => "Another",
743
                    "surname"             => "User",
744
                    "address"             => "Somewhere",
745
                    "category_id"         => "ST",
746
                    "city"                => "Konstanz",
747
                    "library_id"          => "MPL",
748
                    "extended_attributes" => [
749
                        { type => $non_repeatable->code, value => 'first' },
750
                        { type => $non_repeatable->code, value => 'second' }
751
                    ]
752
                }
753
            )->status_is(400)->json_like( '/error' => qr/Tried to add more than one non-repeatable attributes/ );
754
755
            # Test unique ID constraint in real scenario
756
            $t->post_ok(
757
                "//$userid:$password@/api/v1/patrons" => json => {
758
                    "firstname"           => "Another",
759
                    "surname"             => "User",
760
                    "address"             => "Somewhere",
761
                    "category_id"         => "ST",
762
                    "city"                => "Konstanz",
763
                    "library_id"          => "MPL",
764
                    "extended_attributes" => [ { type => $unique_id->code, value => 'unique1' } ]
765
                }
766
            )->status_is(400)->json_like( '/error' => qr/Your action breaks a unique constraint on the attribute/ );
669
        };
767
        };
670
768
671
        subtest 'default patron messaging preferences handling' => sub {
769
        subtest 'default patron messaging preferences handling' => sub {
672
770
673
            plan tests => 3;
771
            plan tests => 6;
674
772
675
            t::lib::Mocks::mock_preference( 'EnhancedMessagingPreferences', 1 );
773
            t::lib::Mocks::mock_preference( 'EnhancedMessagingPreferences', 1 );
676
774
Lines 706-711 subtest 'add() tests' => sub { Link Here
706
                },
804
                },
707
                'Default messaging preferences set correctly'
805
                'Default messaging preferences set correctly'
708
            );
806
            );
807
808
            # Test with EnhancedMessagingPreferences disabled
809
            t::lib::Mocks::mock_preference( 'EnhancedMessagingPreferences', 0 );
810
811
            my $patron_id2 = $t->post_ok(
812
                "//$userid:$password@/api/v1/patrons" => json => {
813
                    "firstname"   => "David",
814
                    "surname"     => "Nolan",
815
                    "address"     => "Elsewhere",
816
                    "category_id" => "ST",
817
                    "city"        => "Bigtown",
818
                    "library_id"  => "MPL",
819
                }
820
            )->status_is( 201, 'Patron added with EnhancedMessagingPreferences disabled' )
821
                ->tx->res->json->{patron_id};
822
823
            # No messaging preferences should be set
824
            my $no_messaging_preferences = C4::Members::Messaging::GetMessagingPreferences(
825
                { borrowernumber => $patron_id2, message_name => 'Item_Due' } );
826
827
            ok(
828
                !$no_messaging_preferences->{transports}->{email},
829
                'No email messaging preferences set when EnhancedMessagingPreferences disabled'
830
            );
709
        };
831
        };
710
832
711
        $schema->storage->txn_rollback;
833
        $schema->storage->txn_rollback;
712
- 

Return to bug 39408