|
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 |
- |
|
|