| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "peridot/bin/cloud_provider_firestore/app/device_set_impl.h" |
| |
| #include <fuchsia/ledger/cloud/cpp/fidl.h> |
| #include <lib/callback/capture.h> |
| #include <lib/callback/set_when_called.h> |
| #include <lib/fidl/cpp/binding.h> |
| #include <lib/fxl/macros.h> |
| #include <lib/gtest/test_loop_fixture.h> |
| |
| #include "peridot/bin/cloud_provider_firestore/app/testing/test_credentials_provider.h" |
| #include "peridot/bin/cloud_provider_firestore/firestore/testing/test_firestore_service.h" |
| #include "peridot/lib/convert/convert.h" |
| |
| namespace cloud_provider_firestore { |
| namespace { |
| |
| class DeviceSetImplTest : public gtest::TestLoopFixture, |
| public cloud_provider::DeviceSetWatcher { |
| public: |
| DeviceSetImplTest() |
| : test_credentials_provider_(dispatcher()), |
| device_set_impl_("user_path", &test_credentials_provider_, |
| &firestore_service_, device_set_.NewRequest()), |
| watcher_binding_(this) {} |
| |
| // cloud_provider::DeviceSetWatcher: |
| void OnCloudErased() override { on_cloud_erased_calls_++; } |
| |
| void OnNetworkError() override { on_network_error_calls_++; } |
| |
| protected: |
| cloud_provider::DeviceSetPtr device_set_; |
| TestCredentialsProvider test_credentials_provider_; |
| TestFirestoreService firestore_service_; |
| DeviceSetImpl device_set_impl_; |
| |
| fidl::Binding<cloud_provider::DeviceSetWatcher> watcher_binding_; |
| int on_cloud_erased_calls_ = 0; |
| int on_network_error_calls_ = 0; |
| |
| private: |
| FXL_DISALLOW_COPY_AND_ASSIGN(DeviceSetImplTest); |
| }; |
| |
| TEST_F(DeviceSetImplTest, EmptyWhenDisconnected) { |
| bool on_empty_called = false; |
| device_set_impl_.set_on_empty(callback::SetWhenCalled(&on_empty_called)); |
| device_set_.Unbind(); |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(on_empty_called); |
| } |
| |
| TEST_F(DeviceSetImplTest, CheckFingerprintOk) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| device_set_->CheckFingerprint( |
| convert::ToArray("abc"), |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(1u, firestore_service_.get_document_records.size()); |
| |
| firestore_service_.get_document_records.front().callback( |
| grpc::Status(), google::firestore::v1beta1::Document()); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::OK, status); |
| } |
| |
| TEST_F(DeviceSetImplTest, CheckFingerprintNotFound) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| device_set_->CheckFingerprint( |
| convert::ToArray("abc"), |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(1u, firestore_service_.get_document_records.size()); |
| |
| firestore_service_.get_document_records.front().callback( |
| grpc::Status(grpc::NOT_FOUND, ""), |
| google::firestore::v1beta1::Document()); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::NOT_FOUND, status); |
| } |
| |
| TEST_F(DeviceSetImplTest, SetFingerprint) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| device_set_->SetFingerprint( |
| convert::ToArray("abc"), |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(1u, firestore_service_.create_document_records.size()); |
| |
| firestore_service_.create_document_records.front().callback( |
| grpc::Status(), google::firestore::v1beta1::Document()); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::OK, status); |
| } |
| |
| TEST_F(DeviceSetImplTest, SetWatcherResultOk) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| cloud_provider::DeviceSetWatcherPtr watcher; |
| watcher_binding_.Bind(watcher.NewRequest()); |
| device_set_->SetWatcher( |
| convert::ToArray("abc"), std::move(watcher), |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_EQ(1u, firestore_service_.listen_clients.size()); |
| EXPECT_FALSE(callback_called); |
| |
| auto response = google::firestore::v1beta1::ListenResponse(); |
| response.mutable_target_change()->set_target_change_type( |
| google::firestore::v1beta1::TargetChange_TargetChangeType_CURRENT); |
| firestore_service_.listen_clients[0]->OnResponse(std::move(response)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::OK, status); |
| EXPECT_EQ(0, on_cloud_erased_calls_); |
| } |
| |
| TEST_F(DeviceSetImplTest, SetWatcherResultCloudErased) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| cloud_provider::DeviceSetWatcherPtr watcher; |
| watcher_binding_.Bind(watcher.NewRequest()); |
| device_set_->SetWatcher( |
| convert::ToArray("abc"), std::move(watcher), |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_EQ(1u, firestore_service_.listen_clients.size()); |
| EXPECT_FALSE(callback_called); |
| |
| auto response = google::firestore::v1beta1::ListenResponse(); |
| response.mutable_document_delete(); |
| firestore_service_.listen_clients[0]->OnResponse(std::move(response)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::NOT_FOUND, status); |
| EXPECT_EQ(1, on_cloud_erased_calls_); |
| } |
| |
| TEST_F(DeviceSetImplTest, Erase) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::INTERNAL_ERROR; |
| device_set_->Erase( |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(1u, firestore_service_.list_documents_records.size()); |
| |
| auto response = google::firestore::v1beta1::ListDocumentsResponse(); |
| response.add_documents()->set_name("some/document/name"); |
| response.add_documents()->set_name("some/other/name"); |
| firestore_service_.list_documents_records[0].callback(grpc::Status::OK, |
| std::move(response)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(2u, firestore_service_.delete_document_records.size()); |
| EXPECT_EQ("some/document/name", |
| firestore_service_.delete_document_records[0].request.name()); |
| EXPECT_EQ("some/other/name", |
| firestore_service_.delete_document_records[1].request.name()); |
| |
| firestore_service_.delete_document_records[0].callback(grpc::Status::OK); |
| firestore_service_.delete_document_records[1].callback(grpc::Status::OK); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::OK, status); |
| } |
| |
| // Paginated response from the device map list is not currently handled - we |
| // give up and return INTERNAL_ERROR. When we add support for pagination, this |
| // test should be edited to verify the correct behavior. |
| TEST_F(DeviceSetImplTest, EraseWithPaginatedDeviceListResponse) { |
| bool callback_called = false; |
| auto status = cloud_provider::Status::OK; |
| device_set_->Erase( |
| callback::Capture(callback::SetWhenCalled(&callback_called), &status)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_FALSE(callback_called); |
| EXPECT_EQ(1u, firestore_service_.list_documents_records.size()); |
| |
| auto response = google::firestore::v1beta1::ListDocumentsResponse(); |
| response.add_documents()->set_name("some/document/name"); |
| response.add_documents()->set_name("some/other/name"); |
| response.set_next_page_token("token"); |
| firestore_service_.list_documents_records[0].callback(grpc::Status::OK, |
| std::move(response)); |
| |
| RunLoopUntilIdle(); |
| EXPECT_TRUE(callback_called); |
| EXPECT_EQ(cloud_provider::Status::INTERNAL_ERROR, status); |
| } |
| |
| } // namespace |
| } // namespace cloud_provider_firestore |