| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 #include "base/stl_util.h" | 6 #include "base/stl_util.h" |
| 7 #include "base/threading/thread.h" | 7 #include "base/threading/thread.h" |
| 8 #include "content/browser/download/byte_stream.h" | 8 #include "content/browser/download/byte_stream.h" |
| 9 #include "content/browser/download/download_create_info.h" | 9 #include "content/browser/download/download_create_info.h" |
| 10 #include "content/browser/download/download_file_factory.h" | 10 #include "content/browser/download/download_file_factory.h" |
| 11 #include "content/browser/download/download_item_impl.h" | 11 #include "content/browser/download/download_item_impl.h" |
| 12 #include "content/browser/download/download_item_impl_delegate.h" | 12 #include "content/browser/download/download_item_impl_delegate.h" |
| 13 #include "content/browser/download/download_request_handle.h" | 13 #include "content/browser/download/download_request_handle.h" |
| 14 #include "content/browser/download/mock_download_file.h" | 14 #include "content/browser/download/mock_download_file.h" |
| 15 #include "content/public/browser/download_id.h" | 15 #include "content/public/browser/download_id.h" |
| 16 #include "content/public/browser/download_destination_observer.h" | 16 #include "content/public/browser/download_destination_observer.h" |
| 17 #include "content/public/browser/download_interrupt_reasons.h" | 17 #include "content/public/browser/download_interrupt_reasons.h" |
| 18 #include "content/public/test/mock_download_item.h" | 18 #include "content/public/test/mock_download_item.h" |
| 19 #include "content/public/test/test_browser_thread.h" | 19 #include "content/public/test/test_browser_thread.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 22 |
| 23 using ::testing::_; | 23 using ::testing::_; |
| 24 using ::testing::AllOf; | |
| 25 using ::testing::Property; | 24 using ::testing::Property; |
| 26 using ::testing::Return; | 25 using ::testing::Return; |
| 27 using ::testing::SaveArg; | 26 using ::testing::SaveArg; |
| 28 using ::testing::StrictMock; | 27 using ::testing::StrictMock; |
| 29 | 28 |
| 30 namespace { | 29 namespace { |
| 31 | 30 |
| 32 const int kDownloadChunkSize = 1000; | 31 const int kDownloadChunkSize = 1000; |
| 33 const int kDownloadSpeed = 1000; | 32 const int kDownloadSpeed = 1000; |
| 34 const int kDummyDBHandle = 10; | 33 const int kDummyDBHandle = 10; |
| 35 const FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath"); | 34 const FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath"); |
| 36 | 35 |
| 37 } // namespace | 36 } // namespace |
| 38 | 37 |
| 39 namespace content { | 38 namespace content { |
| 40 | 39 |
| 41 namespace { | 40 namespace { |
| 42 | 41 |
| 43 DownloadId::Domain kValidDownloadItemIdDomain = "valid DownloadId::Domain"; | 42 DownloadId::Domain kValidDownloadItemIdDomain = "valid DownloadId::Domain"; |
| 44 | 43 |
| 45 class MockDelegate : public DownloadItemImplDelegate { | 44 class MockDelegate : public DownloadItemImplDelegate { |
| 46 public: | 45 public: |
| 47 MOCK_METHOD2(DetermineDownloadTarget, void( | 46 MOCK_METHOD2(DetermineDownloadTarget, void( |
| 48 DownloadItemImpl*, const DownloadTargetCallback&)); | 47 DownloadItemImpl*, const DownloadTargetCallback&)); |
| 48 MOCK_METHOD2(ShouldCompleteDownload, |
| 49 bool(DownloadItemImpl*, const base::Closure&)); |
| 49 MOCK_METHOD2(ShouldOpenDownload, | 50 MOCK_METHOD2(ShouldOpenDownload, |
| 50 bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&)); | 51 bool(DownloadItemImpl*, const ShouldOpenDownloadCallback&)); |
| 51 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const FilePath&)); | 52 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const FilePath&)); |
| 52 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); | 53 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); |
| 53 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); | 54 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); |
| 54 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); | 55 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); |
| 55 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); | 56 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); |
| 56 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); | 57 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); |
| 57 MOCK_METHOD1(ShowDownloadInBrowser, void(DownloadItemImpl*)); | 58 MOCK_METHOD1(ShowDownloadInBrowser, void(DownloadItemImpl*)); |
| 58 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); | 59 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 EXPECT_CALL(*mock_delegate(), ShowDownloadInBrowser(item)) | 479 EXPECT_CALL(*mock_delegate(), ShowDownloadInBrowser(item)) |
| 479 .Times(1); | 480 .Times(1); |
| 480 | 481 |
| 481 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 482 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 482 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 483 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 483 RunAllPendingInMessageLoops(); | 484 RunAllPendingInMessageLoops(); |
| 484 // All the callbacks should have happened by now. | 485 // All the callbacks should have happened by now. |
| 485 ::testing::Mock::VerifyAndClearExpectations(download_file); | 486 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 486 ::testing::Mock::VerifyAndClearExpectations(mock_delegate()); | 487 ::testing::Mock::VerifyAndClearExpectations(mock_delegate()); |
| 487 | 488 |
| 489 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 490 .WillOnce(Return(true)); |
| 488 EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _)) | 491 EXPECT_CALL(*download_file, RenameAndAnnotate(final_path, _)) |
| 489 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 492 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 490 final_path)); | 493 final_path)); |
| 491 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 494 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 492 .WillOnce(Return(true)); | 495 .WillOnce(Return(true)); |
| 493 EXPECT_CALL(*download_file, Detach()); | 496 EXPECT_CALL(*download_file, Detach()); |
| 494 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); | 497 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 495 RunAllPendingInMessageLoops(); | 498 RunAllPendingInMessageLoops(); |
| 496 ::testing::Mock::VerifyAndClearExpectations(download_file); | 499 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 497 ::testing::Mock::VerifyAndClearExpectations(mock_delegate()); | 500 ::testing::Mock::VerifyAndClearExpectations(mock_delegate()); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 // InProgress | 650 // InProgress |
| 648 ASSERT_TRUE(item->IsInProgress()); | 651 ASSERT_TRUE(item->IsInProgress()); |
| 649 ASSERT_FALSE(item->GetTargetFilePath().empty()); | 652 ASSERT_FALSE(item->GetTargetFilePath().empty()); |
| 650 EXPECT_TRUE(item->CanShowInFolder()); | 653 EXPECT_TRUE(item->CanShowInFolder()); |
| 651 EXPECT_TRUE(item->CanOpenDownload()); | 654 EXPECT_TRUE(item->CanOpenDownload()); |
| 652 | 655 |
| 653 // Complete | 656 // Complete |
| 654 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) | 657 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) |
| 655 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 658 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 656 FilePath(kDummyPath))); | 659 FilePath(kDummyPath))); |
| 660 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 661 .WillOnce(Return(true)); |
| 657 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 662 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 658 .WillOnce(Return(true)); | 663 .WillOnce(Return(true)); |
| 659 EXPECT_CALL(*download_file, Detach()); | 664 EXPECT_CALL(*download_file, Detach()); |
| 660 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); | 665 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 661 RunAllPendingInMessageLoops(); | 666 RunAllPendingInMessageLoops(); |
| 662 | 667 |
| 663 ASSERT_TRUE(item->IsComplete()); | 668 ASSERT_TRUE(item->IsComplete()); |
| 664 EXPECT_TRUE(item->CanShowInFolder()); | 669 EXPECT_TRUE(item->CanShowInFolder()); |
| 665 EXPECT_TRUE(item->CanOpenDownload()); | 670 EXPECT_TRUE(item->CanOpenDownload()); |
| 666 } | 671 } |
| 667 | 672 |
| 668 TEST_F(DownloadItemTest, EnabledActionsForTemporaryDownload) { | 673 TEST_F(DownloadItemTest, EnabledActionsForTemporaryDownload) { |
| 669 DownloadItemImpl* item = CreateDownloadItem(); | 674 DownloadItemImpl* item = CreateDownloadItem(); |
| 670 MockDownloadFile* download_file = DoIntermediateRename(item); | 675 MockDownloadFile* download_file = DoIntermediateRename(item); |
| 671 item->SetIsTemporary(true); | 676 item->SetIsTemporary(true); |
| 672 | 677 |
| 673 // InProgress Temporary | 678 // InProgress Temporary |
| 674 ASSERT_TRUE(item->IsInProgress()); | 679 ASSERT_TRUE(item->IsInProgress()); |
| 675 ASSERT_FALSE(item->GetTargetFilePath().empty()); | 680 ASSERT_FALSE(item->GetTargetFilePath().empty()); |
| 676 ASSERT_TRUE(item->IsTemporary()); | 681 ASSERT_TRUE(item->IsTemporary()); |
| 677 EXPECT_FALSE(item->CanShowInFolder()); | 682 EXPECT_FALSE(item->CanShowInFolder()); |
| 678 EXPECT_FALSE(item->CanOpenDownload()); | 683 EXPECT_FALSE(item->CanOpenDownload()); |
| 679 | 684 |
| 680 // Complete Temporary | 685 // Complete Temporary |
| 686 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 687 .WillOnce(Return(true)); |
| 681 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) | 688 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) |
| 682 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 689 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 683 FilePath(kDummyPath))); | 690 FilePath(kDummyPath))); |
| 684 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 691 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 685 .WillOnce(Return(true)); | 692 .WillOnce(Return(true)); |
| 686 EXPECT_CALL(*download_file, Detach()); | 693 EXPECT_CALL(*download_file, Detach()); |
| 687 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); | 694 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 688 RunAllPendingInMessageLoops(); | 695 RunAllPendingInMessageLoops(); |
| 689 | 696 |
| 690 ASSERT_TRUE(item->IsComplete()); | 697 ASSERT_TRUE(item->IsComplete()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 713 | 720 |
| 714 EXPECT_CALL(*download_file, Cancel()); | 721 EXPECT_CALL(*download_file, Cancel()); |
| 715 item->Cancel(true); | 722 item->Cancel(true); |
| 716 RunAllPendingInMessageLoops(); | 723 RunAllPendingInMessageLoops(); |
| 717 | 724 |
| 718 ASSERT_TRUE(item->IsCancelled()); | 725 ASSERT_TRUE(item->IsCancelled()); |
| 719 EXPECT_FALSE(item->CanShowInFolder()); | 726 EXPECT_FALSE(item->CanShowInFolder()); |
| 720 EXPECT_FALSE(item->CanOpenDownload()); | 727 EXPECT_FALSE(item->CanOpenDownload()); |
| 721 } | 728 } |
| 722 | 729 |
| 730 // Test various aspects of the delegate completion blocker. |
| 731 |
| 732 // Just allowing completion. |
| 733 TEST_F(DownloadItemTest, CompleteDelegate_ReturnTrue) { |
| 734 // Test to confirm that if we have a callback that returns true, |
| 735 // we complete immediately. |
| 736 DownloadItemImpl* item = CreateDownloadItem(); |
| 737 MockDownloadFile* download_file = DoIntermediateRename(item); |
| 738 |
| 739 // Drive the delegate interaction. |
| 740 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 741 .WillOnce(Return(true)); |
| 742 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 743 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 744 EXPECT_FALSE(item->IsDangerous()); |
| 745 |
| 746 // Make sure the download can complete. |
| 747 EXPECT_CALL(*download_file, RenameAndAnnotate(FilePath(kDummyPath), _)) |
| 748 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 749 FilePath(kDummyPath))); |
| 750 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 751 .WillOnce(Return(true)); |
| 752 EXPECT_CALL(*download_file, Detach()); |
| 753 RunAllPendingInMessageLoops(); |
| 754 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 755 } |
| 756 |
| 757 // Just delaying completion. |
| 758 TEST_F(DownloadItemTest, CompleteDelegate_BlockOnce) { |
| 759 // Test to confirm that if we have a callback that returns true, |
| 760 // we complete immediately. |
| 761 DownloadItemImpl* item = CreateDownloadItem(); |
| 762 MockDownloadFile* download_file = DoIntermediateRename(item); |
| 763 |
| 764 // Drive the delegate interaction. |
| 765 base::Closure delegate_callback; |
| 766 base::Closure copy_delegate_callback; |
| 767 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 768 .WillOnce(DoAll(SaveArg<1>(&delegate_callback), |
| 769 Return(false))) |
| 770 .WillOnce(Return(true)); |
| 771 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 772 ASSERT_FALSE(delegate_callback.is_null()); |
| 773 copy_delegate_callback = delegate_callback; |
| 774 delegate_callback.Reset(); |
| 775 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 776 copy_delegate_callback.Run(); |
| 777 ASSERT_TRUE(delegate_callback.is_null()); |
| 778 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 779 EXPECT_FALSE(item->IsDangerous()); |
| 780 |
| 781 // Make sure the download can complete. |
| 782 EXPECT_CALL(*download_file, RenameAndAnnotate(FilePath(kDummyPath), _)) |
| 783 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 784 FilePath(kDummyPath))); |
| 785 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 786 .WillOnce(Return(true)); |
| 787 EXPECT_CALL(*download_file, Detach()); |
| 788 RunAllPendingInMessageLoops(); |
| 789 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 790 } |
| 791 |
| 792 // Delay and set danger. |
| 793 TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) { |
| 794 // Test to confirm that if we have a callback that returns true, |
| 795 // we complete immediately. |
| 796 DownloadItemImpl* item = CreateDownloadItem(); |
| 797 MockDownloadFile* download_file = DoIntermediateRename(item); |
| 798 |
| 799 // Drive the delegate interaction. |
| 800 base::Closure delegate_callback; |
| 801 base::Closure copy_delegate_callback; |
| 802 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 803 .WillOnce(DoAll(SaveArg<1>(&delegate_callback), |
| 804 Return(false))) |
| 805 .WillOnce(Return(true)); |
| 806 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 807 ASSERT_FALSE(delegate_callback.is_null()); |
| 808 copy_delegate_callback = delegate_callback; |
| 809 delegate_callback.Reset(); |
| 810 EXPECT_FALSE(item->IsDangerous()); |
| 811 item->OnContentCheckCompleted( |
| 812 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT); |
| 813 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 814 copy_delegate_callback.Run(); |
| 815 ASSERT_TRUE(delegate_callback.is_null()); |
| 816 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 817 EXPECT_TRUE(item->IsDangerous()); |
| 818 |
| 819 // Make sure the download doesn't complete until we've validated it. |
| 820 EXPECT_CALL(*download_file, RenameAndAnnotate(FilePath(kDummyPath), _)) |
| 821 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 822 FilePath(kDummyPath))); |
| 823 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 824 .WillOnce(Return(true)); |
| 825 EXPECT_CALL(*download_file, Detach()); |
| 826 RunAllPendingInMessageLoops(); |
| 827 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 828 EXPECT_TRUE(item->IsDangerous()); |
| 829 |
| 830 item->DangerousDownloadValidated(); |
| 831 EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED, item->GetSafetyState()); |
| 832 RunAllPendingInMessageLoops(); |
| 833 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 834 } |
| 835 |
| 836 // Just delaying completion twice. |
| 837 TEST_F(DownloadItemTest, CompleteDelegate_BlockTwice) { |
| 838 // Test to confirm that if we have a callback that returns true, |
| 839 // we complete immediately. |
| 840 DownloadItemImpl* item = CreateDownloadItem(); |
| 841 MockDownloadFile* download_file = DoIntermediateRename(item); |
| 842 |
| 843 // Drive the delegate interaction. |
| 844 base::Closure delegate_callback; |
| 845 base::Closure copy_delegate_callback; |
| 846 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 847 .WillOnce(DoAll(SaveArg<1>(&delegate_callback), |
| 848 Return(false))) |
| 849 .WillOnce(DoAll(SaveArg<1>(&delegate_callback), |
| 850 Return(false))) |
| 851 .WillOnce(Return(true)); |
| 852 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 853 ASSERT_FALSE(delegate_callback.is_null()); |
| 854 copy_delegate_callback = delegate_callback; |
| 855 delegate_callback.Reset(); |
| 856 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 857 copy_delegate_callback.Run(); |
| 858 ASSERT_FALSE(delegate_callback.is_null()); |
| 859 copy_delegate_callback = delegate_callback; |
| 860 delegate_callback.Reset(); |
| 861 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 862 copy_delegate_callback.Run(); |
| 863 ASSERT_TRUE(delegate_callback.is_null()); |
| 864 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 865 EXPECT_FALSE(item->IsDangerous()); |
| 866 |
| 867 // Make sure the download can complete. |
| 868 EXPECT_CALL(*download_file, RenameAndAnnotate(FilePath(kDummyPath), _)) |
| 869 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 870 FilePath(kDummyPath))); |
| 871 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 872 .WillOnce(Return(true)); |
| 873 EXPECT_CALL(*download_file, Detach()); |
| 874 RunAllPendingInMessageLoops(); |
| 875 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 876 } |
| 877 |
| 723 TEST(MockDownloadItem, Compiles) { | 878 TEST(MockDownloadItem, Compiles) { |
| 724 MockDownloadItem mock_item; | 879 MockDownloadItem mock_item; |
| 725 } | 880 } |
| 726 | 881 |
| 727 } // namespace content | 882 } // namespace content |
| OLD | NEW |