Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // TODO(robliao,vadimt): Determine the granularity of testing to perform. | 5 // TODO(robliao,vadimt): Determine the granularity of testing to perform. |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Test fixture for background.js. | 8 * Test fixture for background.js. |
| 9 * @constructor | 9 * @constructor |
| 10 * @extends {testing.Test} | 10 * @extends {testing.Test} |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 this.mockApis.expects(once()). | 468 this.mockApis.expects(once()). |
| 469 instrumented_tabs_create( | 469 instrumented_tabs_create( |
| 470 chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})), | 470 chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})), |
| 471 chromeTabsCreateSavedArgs.match(ANYTHING)). | 471 chromeTabsCreateSavedArgs.match(ANYTHING)). |
| 472 will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab)); | 472 will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab)); |
| 473 this.mockApis.expects(once()).chrome_windows_create( | 473 this.mockApis.expects(once()).chrome_windows_create( |
| 474 eqJSON({url: testActionUrl, focused: true})); | 474 eqJSON({url: testActionUrl, focused: true})); |
| 475 | 475 |
| 476 // Invoking the tested function. | 476 // Invoking the tested function. |
| 477 onNotificationClicked( | 477 onNotificationClicked( |
| 478 testNotificationId, this.mockLocalFunctions.functions().selector); | 478 testNotificationId, this.mockLocalFunctions.functions().selector); |
|
robliao
2013/12/30 01:59:49
To reduce test churn do this refactor first:
http
vadimt
2014/01/02 21:46:04
Yeah, I originally agreed that this would make tes
robliao
2014/01/03 09:09:34
The callback approach in the CR comment decouples
vadimt
2014/01/03 18:50:34
I wonder what other reviewers think. The proposal
rgustafson
2014/01/07 20:36:44
Let me look at this more in depth after lunch.
robliao
2014/01/10 21:50:42
This is a structure request. It should be done to
| |
| 479 }); | 479 }); |
| 480 | |
|
robliao
2013/12/30 01:59:49
Overall: Could use some more test cases.
* Fresh r
vadimt
2014/01/02 21:46:04
We should be pragmatic about the testing, and I ag
robliao
2014/01/03 09:09:34
The bug was found by manual testing, but broke the
vadimt
2014/01/03 18:50:34
This is a legitimate way of finding bugs :) You ar
rgustafson
2014/01/07 20:36:44
While I don't agree with the general sentiment of
| |
| 481 TEST_F( | |
|
robliao
2013/12/30 01:59:49
Comment targeted test behavior and expectations.
vadimt
2014/01/02 21:46:04
Done.
| |
| 482 'GoogleNowBackgroundUnitTest', | |
| 483 'ShowNotificationCards', | |
| 484 function() { | |
| 485 // Tests showNotificationCards function. | |
| 486 | |
| 487 // Setup and expectations. | |
| 488 var existingNotifications = { | |
| 489 'SHOULD BE DELETED': 'SOMETHING', | |
| 490 'SHOULD BE KEPT': 'SOMETHING' | |
| 491 }; | |
| 492 | |
| 493 var notificationGroups = { | |
| 494 TEST_FIELD: 'TEST VALUE' | |
| 495 }; | |
| 496 | |
| 497 var cards = { | |
| 498 'SHOULD BE KEPT': [1], | |
| 499 'NEW CARD': [2] | |
| 500 }; | |
| 501 | |
| 502 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION'; | |
|
robliao
2013/12/30 01:59:49
Is this necessary? This parameter used for the fun
vadimt
2014/01/02 21:46:04
I'm checking that the parameter (if passed) is not
| |
| 503 | |
| 504 var expectedUpdatedNotifications = { | |
| 505 'SHOULD BE KEPT': 'KEPT CARD NOTIFICATION DATA', | |
| 506 'NEW CARD': 'NEW CARD NOTIFICATION DATA' | |
| 507 }; | |
| 508 | |
| 509 this.makeAndRegisterMockApis([ | |
| 510 'cardSet.update', | |
| 511 'chrome.storage.local.set', | |
| 512 'instrumented.notifications.getAll' | |
| 513 ]); | |
| 514 this.makeMockLocalFunctions([ | |
| 515 'onSuccess' | |
| 516 ]); | |
| 517 | |
| 518 var notificationsGetAllSavedArgs = new SaveMockArguments(); | |
| 519 this.mockApis.expects(once()). | |
| 520 instrumented_notifications_getAll( | |
| 521 notificationsGetAllSavedArgs.match(ANYTHING)). | |
| 522 will(invokeCallback( | |
| 523 notificationsGetAllSavedArgs, 0, existingNotifications)); | |
| 524 | |
| 525 this.mockApis.expects(once()). | |
| 526 cardSet_update( | |
| 527 'SHOULD BE KEPT', | |
| 528 [1], | |
| 529 eqJSON(notificationGroups), | |
| 530 fakeOnCardShownFunction). | |
| 531 will(returnValue('KEPT CARD NOTIFICATION DATA')); | |
| 532 this.mockApis.expects(once()). | |
| 533 cardSet_update( | |
| 534 'NEW CARD', | |
| 535 [2], | |
| 536 eqJSON(notificationGroups), | |
| 537 fakeOnCardShownFunction). | |
| 538 will(returnValue('NEW CARD NOTIFICATION DATA')); | |
| 539 this.mockApis.expects(once()). | |
| 540 cardSet_update( | |
| 541 'SHOULD BE DELETED', | |
| 542 [], | |
| 543 eqJSON(notificationGroups), | |
| 544 fakeOnCardShownFunction). | |
| 545 will(returnValue(undefined)); | |
| 546 | |
| 547 this.mockApis.expects(once()). | |
| 548 chrome_storage_local_set( | |
| 549 eqJSON({notificationsData: expectedUpdatedNotifications})); | |
| 550 | |
| 551 this.mockLocalFunctions.expects(once()). | |
| 552 onSuccess(); | |
| 553 | |
| 554 // Invoking the tested function. | |
| 555 showNotificationCards( | |
| 556 notificationGroups, | |
| 557 cards, | |
| 558 this.mockLocalFunctions.functions().onSuccess, | |
| 559 fakeOnCardShownFunction); | |
| 560 }); | |
| 561 | |
| 562 TEST_F( | |
| 563 'GoogleNowBackgroundUnitTest', | |
| 564 'CombineGroup', | |
| 565 function() { | |
| 566 // Tests combineGroup function. | |
|
robliao
2013/12/30 01:59:49
Comment targeted test behavior and expectations.
vadimt
2014/01/02 21:46:04
Done.
| |
| 567 | |
| 568 // Setup and expectations. | |
| 569 var combinedCards = { | |
| 570 'EXISTING CARD': [1] | |
| 571 }; | |
| 572 | |
| 573 var receivedNotificationNoShowTime = { | |
| 574 chromeNotificationId: 'EXISTING CARD', | |
| 575 trigger: {hideTimeSec: 1} | |
| 576 }; | |
| 577 var receivedNotificationWithShowTime = { | |
| 578 chromeNotificationId: 'NEW CARD', | |
| 579 trigger: {showTimeSec: 2, hideTimeSec: 3} | |
| 580 } | |
| 581 | |
| 582 var storedGroup = { | |
| 583 cardsTimestamp: 10000, | |
| 584 cards: [ | |
| 585 receivedNotificationNoShowTime, | |
| 586 receivedNotificationWithShowTime | |
| 587 ] | |
| 588 }; | |
| 589 | |
| 590 // Invoking the tested function. | |
| 591 combineGroup(combinedCards, storedGroup); | |
| 592 | |
| 593 // Check the output value. | |
| 594 var expectedCombinedCards = { | |
| 595 'EXISTING CARD': [ | |
| 596 1, | |
| 597 { | |
| 598 receivedNotification: receivedNotificationNoShowTime, | |
| 599 hideTime: 11000 | |
| 600 } | |
| 601 ], | |
| 602 'NEW CARD': [ | |
| 603 { | |
| 604 receivedNotification: receivedNotificationWithShowTime, | |
| 605 showTime: 12000, | |
| 606 hideTime: 13000 | |
| 607 } | |
| 608 ] | |
| 609 }; | |
| 610 | |
| 611 assertEquals( | |
| 612 JSON.stringify(expectedCombinedCards), | |
| 613 JSON.stringify(combinedCards)); | |
| 614 }); | |
| 615 | |
| 616 TEST_F( | |
| 617 'GoogleNowBackgroundUnitTest', | |
| 618 'CombineAndShowNotificationCards', | |
| 619 function() { | |
| 620 // Tests combineAndShowNotificationCards function. | |
| 621 // The test passes 2 groups to combineAndShowNotificationCards, checks | |
| 622 // that it calls combineGroup() for each of these groups and calls | |
| 623 // showNotificationCards() with the results of these combineGroup() calls. | |
| 624 | |
| 625 // Setup and expectations. | |
| 626 var testGroups = { | |
| 627 'TEST GROUP 1': {testField: 'TEST VALUE 1'}, | |
| 628 'TEST GROUP 2': {testField: 'TEST VALUE 2'} | |
| 629 }; | |
| 630 | |
| 631 var fakeOnSuccessFunction = 'FAKE ON SUCCESS FUNCTION'; | |
|
robliao
2013/12/30 01:59:49
Should use a fake function to simulate the correct
vadimt
2014/01/02 21:46:04
Here we test that the value is simple passed to ot
| |
| 632 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION'; | |
|
robliao
2013/12/30 01:59:49
See optional argument above.
vadimt
2014/01/02 21:46:04
Se above.
| |
| 633 | |
| 634 this.makeAndRegisterMockGlobals( | |
| 635 ['combineGroup', 'showNotificationCards']); | |
| 636 | |
| 637 var combineGroupSavedArgs = new SaveMockArguments(); | |
| 638 this.mockGlobals.expects(once()). | |
| 639 combineGroup( | |
| 640 combineGroupSavedArgs.match(eqJSON({})), | |
| 641 combineGroupSavedArgs.match(eqJSON({testField: 'TEST VALUE 1'}))). | |
| 642 will(callFunction(function() { | |
| 643 combineGroupSavedArgs.arguments[0].card1 = { | |
| 644 testValue: 'TEST CARD VALUE 1' | |
| 645 }; | |
| 646 })); | |
| 647 this.mockGlobals.expects(once()). | |
| 648 combineGroup( | |
| 649 combineGroupSavedArgs.match( | |
| 650 eqJSON({card1: {testValue: 'TEST CARD VALUE 1'}})), | |
| 651 combineGroupSavedArgs.match( | |
| 652 eqJSON({testField: 'TEST VALUE 2'}))). | |
| 653 will(callFunction(function() { | |
| 654 combineGroupSavedArgs.arguments[0].card2 = { | |
| 655 testValue: 'TEST CARD VALUE 2' | |
| 656 }; | |
| 657 })); | |
| 658 this.mockGlobals.expects(once()). | |
| 659 showNotificationCards( | |
| 660 eqJSON(testGroups), | |
| 661 eqJSON({ | |
| 662 card1: {testValue: 'TEST CARD VALUE 1'}, | |
| 663 card2: {testValue: 'TEST CARD VALUE 2'} | |
| 664 }), | |
| 665 fakeOnSuccessFunction, | |
| 666 fakeOnCardShownFunction); | |
| 667 | |
| 668 // Invoking the tested function. | |
| 669 combineAndShowNotificationCards( | |
| 670 testGroups, fakeOnSuccessFunction, fakeOnCardShownFunction); | |
| 671 }); | |
| 672 | |
| 673 TEST_F( | |
| 674 'GoogleNowBackgroundUnitTest', | |
| 675 'ProcessServerResponse', | |
| 676 function() { | |
| 677 // Tests processServerResponse function. | |
| 678 | |
| 679 // Setup and expectations. | |
| 680 Date.now = function() { return 3000000; }; | |
| 681 | |
| 682 // GROUP1 was requested and contains cards c4 and c5. For c5, there is a | |
| 683 // non-expired dismissal, so it will be ignored. | |
| 684 // GROUP2 was not requested, but is contained in server response to | |
| 685 // indicate that the group still exists. Stored group GROUP2 won't change. | |
| 686 // GROUP3 is stored, but is not present in server's response, which means | |
| 687 // it doesn't exist anymore. This group will be deleted. | |
| 688 // GROUP4 doesn't contain cards, but it was requested. This is treated as | |
| 689 // if it had an empty array of cards. Cards in the stored group will be | |
| 690 // replaced with an empty array. | |
| 691 // GROUP5 doesn't have next poll time, and it will be stored without next | |
| 692 // poll time. | |
| 693 var serverResponse = { | |
| 694 groups: { | |
| 695 GROUP1: {requested: true, nextPollSeconds: 46}, | |
| 696 GROUP2: {requested: false}, | |
| 697 GROUP4: {requested: true, nextPollSeconds: 45}, | |
| 698 GROUP5: {requested: true} | |
| 699 }, | |
| 700 notifications: [ | |
| 701 {notificationId: 'c4', groupName: 'GROUP1'}, | |
| 702 {notificationId: 'c5', groupName: 'GROUP1'} | |
| 703 ] | |
| 704 }; | |
| 705 | |
| 706 var recentDismissals = { | |
| 707 c4: 1800000, // expired dismissal | |
| 708 c5: 1800001 // non-expired dismissal | |
| 709 }; | |
| 710 | |
| 711 var storedGroups = { | |
| 712 GROUP2: { | |
| 713 cards: [{notificationId: 'c2'}], | |
| 714 cardsTimestamp: 239, | |
| 715 nextPollTime: 10000 | |
| 716 }, | |
| 717 GROUP3: { | |
| 718 cards: [{notificationId: 'c3'}], | |
| 719 cardsTimestamp: 240, | |
| 720 nextPollTime: 10001 | |
| 721 }, | |
| 722 GROUP4: { | |
| 723 cards: [{notificationId: 'c44'}], | |
|
robliao
2013/12/30 01:59:49
c4?
vadimt
2014/01/02 21:46:04
No, I wanted it to be different from c4.
robliao
2014/01/03 09:09:34
Document this so that future coders won't view thi
vadimt
2014/01/03 18:50:34
Renamed.
| |
| 724 cardsTimestamp: 241, | |
| 725 nextPollTime: 10002 | |
| 726 } | |
| 727 }; | |
| 728 | |
| 729 var expectedUpdatedGroups = { | |
| 730 GROUP1: { | |
| 731 cards: [{notificationId: 'c4', groupName: 'GROUP1'}], | |
| 732 cardsTimestamp: 3000000, | |
| 733 nextPollTime: 3046000 | |
| 734 }, | |
| 735 GROUP2: { | |
| 736 cards: [{notificationId: 'c2'}], | |
| 737 cardsTimestamp: 239, | |
| 738 nextPollTime: 10000 | |
| 739 }, | |
| 740 GROUP4: { | |
| 741 cards: [], | |
| 742 cardsTimestamp: 3000000, | |
| 743 nextPollTime: 3045000 | |
| 744 }, | |
| 745 GROUP5: { | |
| 746 cards: [], | |
| 747 cardsTimestamp: 3000000 | |
| 748 } | |
| 749 }; | |
| 750 | |
| 751 var expectedUpdatedRecentDismissals = { | |
| 752 c5: 1800001 | |
| 753 }; | |
| 754 | |
| 755 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION'; | |
| 756 | |
| 757 this.makeAndRegisterMockGlobals([ | |
| 758 'scheduleNextPoll', | |
| 759 'combineAndShowNotificationCards', | |
| 760 'recordEvent' | |
| 761 ]); | |
| 762 | |
| 763 this.makeAndRegisterMockApis([ | |
| 764 'chrome.storage.local.set', | |
| 765 'instrumented.storage.local.get' | |
| 766 ]); | |
| 767 | |
| 768 var storageGetSavedArgs = new SaveMockArguments(); | |
| 769 this.mockApis.expects(once()). | |
| 770 instrumented_storage_local_get( | |
| 771 storageGetSavedArgs.match( | |
| 772 eq(['notificationGroups', 'recentDismissals'])), | |
| 773 storageGetSavedArgs.match(ANYTHING)). | |
| 774 will(invokeCallback( | |
| 775 storageGetSavedArgs, | |
| 776 1, | |
| 777 { | |
| 778 notificationGroups: storedGroups, | |
| 779 recentDismissals: recentDismissals | |
| 780 })); | |
| 781 | |
| 782 this.mockGlobals.expects(once()). | |
| 783 scheduleNextPoll(eqJSON(expectedUpdatedGroups), true); | |
| 784 | |
| 785 var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments(); | |
| 786 this.mockGlobals.expects(once()). | |
| 787 combineAndShowNotificationCards( | |
| 788 combineAndShowNotificationCardsSavedArgs.match( | |
| 789 eqJSON(expectedUpdatedGroups)), | |
| 790 combineAndShowNotificationCardsSavedArgs.match( | |
| 791 ANYTHING), | |
| 792 combineAndShowNotificationCardsSavedArgs.match( | |
| 793 eq(fakeOnCardShownFunction))). | |
| 794 will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1)); | |
| 795 | |
| 796 this.mockApis.expects(once()). | |
| 797 chrome_storage_local_set( | |
| 798 eqJSON({ | |
| 799 notificationGroups: expectedUpdatedGroups, | |
| 800 recentDismissals: expectedUpdatedRecentDismissals})); | |
| 801 | |
| 802 this.mockGlobals.expects(once()). | |
| 803 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | |
| 804 | |
| 805 // Invoking the tested function. | |
| 806 processServerResponse(serverResponse, fakeOnCardShownFunction); | |
| 807 }); | |
| 808 | |
| 809 TEST_F( | |
| 810 'GoogleNowBackgroundUnitTest', | |
|
robliao
2013/12/30 01:59:49
Possible to generalize with the above?
vadimt
2014/01/02 21:46:04
You probably mean factoring out the common part.
I
| |
| 811 'ProcessServerResponseGoogleNowDisabled', | |
| 812 function() { | |
| 813 // Tests processServerResponse function for the case when the response | |
| 814 // indicates that Google Now is disabled. | |
| 815 | |
| 816 // Setup and expectations. | |
| 817 var serverResponse = { | |
| 818 googleNowDisabled: true, | |
| 819 groups: { | |
| 820 GROUP1: {nextPollTimeSeconds: 200} | |
| 821 } | |
| 822 }; | |
| 823 | |
| 824 var storedGroups = { | |
| 825 GROUP2: { | |
| 826 cards: [{notificationId: 'c2'}], | |
| 827 cardsTimestamp: 239, | |
| 828 nextPollTime: 10000 | |
| 829 }, | |
| 830 GROUP3: { | |
| 831 cards: [{notificationId: 'c3'}], | |
| 832 cardsTimestamp: 240, | |
| 833 nextPollTime: 10001 | |
| 834 } | |
| 835 }; | |
| 836 | |
| 837 var expectedUpdatedGroups = { | |
| 838 }; | |
| 839 | |
| 840 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION'; | |
| 841 | |
| 842 this.makeAndRegisterMockGlobals([ | |
| 843 'scheduleNextPoll', | |
| 844 'combineAndShowNotificationCards', | |
| 845 'recordEvent', | |
| 846 'onStateChange' | |
| 847 ]); | |
| 848 | |
| 849 this.makeAndRegisterMockApis([ | |
| 850 'chrome.storage.local.set', | |
| 851 'instrumented.storage.local.get' | |
| 852 ]); | |
| 853 | |
| 854 this.mockApis.expects(once()). | |
| 855 chrome_storage_local_set( | |
| 856 eqJSON({googleNowEnabled: false})); | |
| 857 | |
| 858 this.mockGlobals.expects(once()).onStateChange(); | |
| 859 | |
| 860 var storageGetSavedArgs = new SaveMockArguments(); | |
| 861 this.mockApis.expects(once()). | |
| 862 instrumented_storage_local_get( | |
| 863 storageGetSavedArgs.match( | |
| 864 eq(['notificationGroups', 'recentDismissals'])), | |
| 865 storageGetSavedArgs.match(ANYTHING)). | |
| 866 will(invokeCallback( | |
| 867 storageGetSavedArgs, 1, {notificationGroups: storedGroups})); | |
| 868 | |
| 869 this.mockGlobals.expects(once()). | |
| 870 scheduleNextPoll(eqJSON(expectedUpdatedGroups), false); | |
| 871 | |
| 872 var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments(); | |
| 873 this.mockGlobals.expects(once()). | |
| 874 combineAndShowNotificationCards( | |
| 875 combineAndShowNotificationCardsSavedArgs.match( | |
| 876 eqJSON(expectedUpdatedGroups)), | |
| 877 combineAndShowNotificationCardsSavedArgs.match( | |
| 878 ANYTHING), | |
| 879 combineAndShowNotificationCardsSavedArgs.match( | |
| 880 eq(fakeOnCardShownFunction))). | |
| 881 will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1)); | |
| 882 | |
| 883 this.mockApis.expects(once()). | |
| 884 chrome_storage_local_set( | |
| 885 eqJSON({ | |
| 886 notificationGroups: expectedUpdatedGroups, | |
| 887 recentDismissals: {}})); | |
| 888 | |
| 889 this.mockGlobals.expects(once()). | |
| 890 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS); | |
| 891 | |
| 892 // Invoking the tested function. | |
| 893 processServerResponse(serverResponse, fakeOnCardShownFunction); | |
| 894 }); | |
| OLD | NEW |