| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/nearby_sharing/nearby_receive_manager.h" |
| |
| #include "base/test/bind.h" |
| #include "base/test/mock_callback.h" |
| #include "chrome/browser/nearby_sharing/mock_nearby_sharing_service.h" |
| #include "chrome/browser/nearby_sharing/share_target.h" |
| #include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom-test-utils.h" |
| #include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| |
| namespace { |
| |
| class FakeReceiveObserver : public nearby_share::mojom::ReceiveObserver { |
| public: |
| void OnHighVisibilityChanged(bool in_high_visibility) override { |
| in_high_visibility_ = in_high_visibility; |
| } |
| |
| void OnTransferUpdate( |
| const ShareTarget& share_target, |
| nearby_share::mojom::TransferMetadataPtr metadata) override { |
| last_share_target_ = share_target; |
| last_metadata_ = *metadata; |
| } |
| |
| void OnNearbyProcessStopped() override { |
| on_nearby_process_stopped_called_ = true; |
| } |
| |
| void OnStartAdvertisingFailure() override { |
| on_start_advertising_failure_called_ = true; |
| } |
| |
| absl::optional<nearby_share::mojom::TransferMetadata> last_metadata_; |
| absl::optional<bool> in_high_visibility_; |
| ShareTarget last_share_target_; |
| bool on_nearby_process_stopped_called_ = false; |
| bool on_start_advertising_failure_called_ = false; |
| mojo::Receiver<nearby_share::mojom::ReceiveObserver> receiver_{this}; |
| }; |
| |
| class NearbyReceiveManagerTest : public testing::Test { |
| public: |
| using ReceiveSurfaceState = NearbySharingService::ReceiveSurfaceState; |
| using StatusCodes = NearbySharingService::StatusCodes; |
| using RegisterReceiveSurfaceResult = |
| nearby_share::mojom::RegisterReceiveSurfaceResult; |
| |
| NearbyReceiveManagerTest() |
| : transfer_metadata_(TransferMetadata::Status::kAwaitingLocalConfirmation, |
| /*progress=*/0.f, |
| /*token=*/"1234", |
| /*is_original=*/true, |
| /*is_final_status=*/false) { |
| share_target_.id = base::UnguessableToken::Create(); |
| receive_manager_.AddReceiveObserver( |
| observer_.receiver_.BindNewPipeAndPassRemote()); |
| } |
| |
| ~NearbyReceiveManagerTest() override = default; |
| |
| protected: |
| void FlushMojoMessages() { observer_.receiver_.FlushForTesting(); } |
| |
| void ExpectRegister(StatusCodes code = StatusCodes::kOk) { |
| EXPECT_CALL(sharing_service_, |
| RegisterReceiveSurface(testing::_, testing::_)) |
| .WillOnce([=](TransferUpdateCallback* transfer_callback, |
| ReceiveSurfaceState state) { |
| EXPECT_EQ(ReceiveSurfaceState::kForeground, state); |
| return code; |
| }); |
| } |
| |
| void ExpectUnregister(StatusCodes code = StatusCodes::kOk) { |
| EXPECT_CALL(sharing_service_, UnregisterReceiveSurface(testing::_)) |
| .WillOnce( |
| [=](TransferUpdateCallback* transfer_callback) { return code; }); |
| } |
| |
| void ExpectIsInHighVisibility(bool in_high_visibility) { |
| EXPECT_CALL(sharing_service_, IsInHighVisibility()) |
| .WillOnce(testing::Return(in_high_visibility)); |
| } |
| |
| void ExpectAccept(StatusCodes code = StatusCodes::kOk) { |
| EXPECT_CALL(sharing_service_, Accept(testing::_, testing::_)) |
| .WillOnce([=](const ShareTarget& share_target, |
| NearbySharingService::StatusCodesCallback |
| status_codes_callback) { |
| std::move(status_codes_callback).Run(code); |
| }); |
| } |
| |
| void ExpectReject(StatusCodes code = StatusCodes::kOk) { |
| EXPECT_CALL(sharing_service_, Reject(testing::_, testing::_)) |
| .WillOnce([=](const ShareTarget& share_target, |
| NearbySharingService::StatusCodesCallback |
| status_codes_callback) { |
| std::move(status_codes_callback).Run(code); |
| }); |
| } |
| |
| content::BrowserTaskEnvironment task_environment_; |
| ShareTarget share_target_; |
| TransferMetadata transfer_metadata_; |
| MockNearbySharingService sharing_service_; |
| FakeReceiveObserver observer_; |
| NearbyReceiveManager receive_manager_{&sharing_service_}; |
| nearby_share::mojom::ReceiveManagerAsyncWaiter receive_manager_waiter_{ |
| &receive_manager_}; |
| }; |
| |
| } // namespace |
| |
| TEST_F(NearbyReceiveManagerTest, Enter_Exit_Success) { |
| ExpectRegister(); |
| RegisterReceiveSurfaceResult result = RegisterReceiveSurfaceResult::kFailure; |
| receive_manager_waiter_.RegisterForegroundReceiveSurface(&result); |
| EXPECT_EQ(RegisterReceiveSurfaceResult::kSuccess, result); |
| |
| ExpectUnregister(); |
| bool exited = false; |
| receive_manager_waiter_.UnregisterForegroundReceiveSurface(&exited); |
| EXPECT_TRUE(exited); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, Enter_Failed) { |
| RegisterReceiveSurfaceResult result = RegisterReceiveSurfaceResult::kSuccess; |
| ExpectRegister(StatusCodes::kError); |
| receive_manager_waiter_.RegisterForegroundReceiveSurface(&result); |
| EXPECT_EQ(RegisterReceiveSurfaceResult::kFailure, result); |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, Multiple_Enter_Successful) { |
| RegisterReceiveSurfaceResult result = RegisterReceiveSurfaceResult::kFailure; |
| ExpectRegister(StatusCodes::kOk); |
| receive_manager_waiter_.RegisterForegroundReceiveSurface(&result); |
| FlushMojoMessages(); |
| EXPECT_EQ(RegisterReceiveSurfaceResult::kSuccess, result); |
| |
| result = RegisterReceiveSurfaceResult::kFailure; |
| ExpectRegister(StatusCodes::kOk); |
| receive_manager_waiter_.RegisterForegroundReceiveSurface(&result); |
| FlushMojoMessages(); |
| EXPECT_EQ(RegisterReceiveSurfaceResult::kSuccess, result); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, Exit_Failed) { |
| RegisterReceiveSurfaceResult result = RegisterReceiveSurfaceResult::kFailure; |
| ExpectRegister(); |
| receive_manager_waiter_.RegisterForegroundReceiveSurface(&result); |
| EXPECT_EQ(RegisterReceiveSurfaceResult::kSuccess, result); |
| |
| ExpectUnregister(StatusCodes::kError); |
| bool exited = false; |
| receive_manager_waiter_.UnregisterForegroundReceiveSurface(&exited); |
| EXPECT_FALSE(exited); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, ShareTargetNotifies_Accept) { |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); |
| FlushMojoMessages(); |
| EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); |
| ASSERT_TRUE(observer_.last_metadata_.has_value()); |
| EXPECT_EQ("1234", observer_.last_metadata_->token); |
| |
| ExpectAccept(); |
| bool success = false; |
| receive_manager_waiter_.Accept(share_target_.id, &success); |
| EXPECT_TRUE(success); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, ShareTargetNotifies_Reject) { |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); |
| FlushMojoMessages(); |
| EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); |
| ASSERT_TRUE(observer_.last_metadata_.has_value()); |
| EXPECT_EQ("1234", observer_.last_metadata_->token); |
| |
| ExpectReject(); |
| bool success = false; |
| receive_manager_waiter_.Reject(share_target_.id, &success); |
| EXPECT_TRUE(success); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, |
| ShareTargetNotifies_SenderCancelsBeforeAccept) { |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); |
| FlushMojoMessages(); |
| EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); |
| ASSERT_TRUE(observer_.last_metadata_.has_value()); |
| EXPECT_EQ("1234", observer_.last_metadata_->token); |
| |
| // Simulate the sender canceling before we accept the share target and causing |
| // the accept to fail before hitting the service. |
| TransferMetadata transfer_metadata_final(TransferMetadata::Status::kCancelled, |
| 1.f, absl::nullopt, true, true); |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_final); |
| FlushMojoMessages(); |
| |
| bool success = true; |
| receive_manager_waiter_.Accept(share_target_.id, &success); |
| EXPECT_FALSE(success); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, |
| ShareTargetNotifies_SenderCancelsBeforeReject) { |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_); |
| FlushMojoMessages(); |
| EXPECT_EQ(share_target_.id, observer_.last_share_target_.id); |
| ASSERT_TRUE(observer_.last_metadata_.has_value()); |
| EXPECT_EQ("1234", observer_.last_metadata_->token); |
| |
| // Simulate the sender canceling before we reject the share target and causing |
| // the reject to fail before hitting the service. |
| TransferMetadata transfer_metadata_final(TransferMetadata::Status::kCancelled, |
| 1.f, absl::nullopt, true, true); |
| receive_manager_.OnTransferUpdate(share_target_, transfer_metadata_final); |
| FlushMojoMessages(); |
| |
| bool success = true; |
| receive_manager_waiter_.Reject(share_target_.id, &success); |
| EXPECT_FALSE(success); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, IsInHighVisibility) { |
| ExpectIsInHighVisibility(true); |
| bool on = false; |
| receive_manager_waiter_.IsInHighVisibility(&on); |
| FlushMojoMessages(); |
| EXPECT_TRUE(on); |
| |
| ExpectIsInHighVisibility(false); |
| on = true; |
| receive_manager_waiter_.IsInHighVisibility(&on); |
| FlushMojoMessages(); |
| EXPECT_FALSE(on); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, OnHighVisibilityChangedObserver) { |
| receive_manager_.OnHighVisibilityChanged(false); |
| FlushMojoMessages(); |
| ASSERT_TRUE(observer_.in_high_visibility_.has_value()); |
| EXPECT_FALSE(*observer_.in_high_visibility_); |
| |
| observer_.in_high_visibility_ = absl::nullopt; |
| |
| receive_manager_.OnHighVisibilityChanged(true); |
| FlushMojoMessages(); |
| ASSERT_TRUE(observer_.in_high_visibility_.has_value()); |
| EXPECT_TRUE(*observer_.in_high_visibility_); |
| |
| ExpectUnregister(); |
| } |
| |
| TEST_F(NearbyReceiveManagerTest, OnStartAdvertisingFailureObserver) { |
| EXPECT_FALSE(observer_.on_start_advertising_failure_called_); |
| receive_manager_.OnStartAdvertisingFailure(); |
| FlushMojoMessages(); |
| EXPECT_TRUE(observer_.on_start_advertising_failure_called_); |
| |
| ExpectUnregister(); |
| } |