From 2ef45ff9caf531d43a366186a7c80d7307d91252 Mon Sep 17 00:00:00 2001 From: juncai Date: Tue, 23 Aug 2016 18:33:57 -0700 Subject: [PATCH] Add unit test for UsbChooserController This CL adds some unit tests for code that deals with displaying USB devices that have the same name on the chooser. BUG=637402 Review-Url: https://codereview.chromium.org/2269993004 Cr-Commit-Position: refs/heads/master@{#413929} --- .../usb/usb_chooser_controller_unittest.cc | 136 ++++++++++++++++++ chrome/chrome_tests_unit.gypi | 1 + device/usb/mock_usb_device.h | 7 + 3 files changed, 144 insertions(+) create mode 100644 chrome/browser/usb/usb_chooser_controller_unittest.cc diff --git a/chrome/browser/usb/usb_chooser_controller_unittest.cc b/chrome/browser/usb/usb_chooser_controller_unittest.cc new file mode 100644 index 00000000000000..3a4134215f3f25 --- /dev/null +++ b/chrome/browser/usb/usb_chooser_controller_unittest.cc @@ -0,0 +1,136 @@ +// Copyright 2016 The Chromium 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 + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/usb/usb_chooser_controller.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "content/public/test/web_contents_tester.h" +#include "device/core/mock_device_client.h" +#include "device/usb/mock_usb_device.h" +#include "device/usb/mock_usb_service.h" +#include "device/usb/public/interfaces/device_manager.mojom.h" +#include "mojo/public/cpp/bindings/array.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +const char kDefaultTestUrl[] = "https://www.google.com/"; + +} // namespace + +class UsbChooserControllerTest : public ChromeRenderViewHostTestHarness { + public: + UsbChooserControllerTest() {} + ~UsbChooserControllerTest() override = default; + + void SetUp() override { + ChromeRenderViewHostTestHarness::SetUp(); + + mojo::Array device_filters; + device::usb::ChooserService::GetPermissionCallback callback; + content::WebContentsTester* web_contents_tester = + content::WebContentsTester::For(web_contents()); + web_contents_tester->NavigateAndCommit(GURL(kDefaultTestUrl)); + usb_chooser_controller_.reset(new UsbChooserController( + main_rfh(), std::move(device_filters), main_rfh(), callback)); + } + + protected: + scoped_refptr CreateMockUsbDevice( + const std::string& product_string, + const std::string& serial_number) { + scoped_refptr device(new device::MockUsbDevice( + 0, 1, "Google", product_string, serial_number)); + std::unique_ptr webusb_allowed_origins( + new device::WebUsbAllowedOrigins()); + webusb_allowed_origins->origins.push_back(GURL(kDefaultTestUrl)); + device->set_webusb_allowed_origins(std::move(webusb_allowed_origins)); + return device; + } + + device::MockDeviceClient device_client_; + std::unique_ptr usb_chooser_controller_; + + private: + DISALLOW_COPY_AND_ASSIGN(UsbChooserControllerTest); +}; + +TEST_F(UsbChooserControllerTest, AddDevice) { + scoped_refptr device_a = + CreateMockUsbDevice("a", "001"); + device_client_.usb_service()->AddDevice(device_a); + EXPECT_EQ(1u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("a"), usb_chooser_controller_->GetOption(0)); + + scoped_refptr device_b = + CreateMockUsbDevice("b", "002"); + device_client_.usb_service()->AddDevice(device_b); + EXPECT_EQ(2u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("b"), usb_chooser_controller_->GetOption(1)); + + scoped_refptr device_c = + CreateMockUsbDevice("c", "003"); + device_client_.usb_service()->AddDevice(device_c); + EXPECT_EQ(3u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("c"), usb_chooser_controller_->GetOption(2)); +} + +TEST_F(UsbChooserControllerTest, RemoveDevice) { + scoped_refptr device_a = + CreateMockUsbDevice("a", "001"); + device_client_.usb_service()->AddDevice(device_a); + scoped_refptr device_b = + CreateMockUsbDevice("b", "002"); + device_client_.usb_service()->AddDevice(device_b); + scoped_refptr device_c = + CreateMockUsbDevice("c", "003"); + device_client_.usb_service()->AddDevice(device_c); + + device_client_.usb_service()->RemoveDevice(device_b); + EXPECT_EQ(2u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("a"), usb_chooser_controller_->GetOption(0)); + EXPECT_EQ(base::ASCIIToUTF16("c"), usb_chooser_controller_->GetOption(1)); + + // Remove a non-existent device, the number of devices should not change. + scoped_refptr device_non_existent = + CreateMockUsbDevice("d", "001"); + device_client_.usb_service()->RemoveDevice(device_non_existent); + EXPECT_EQ(2u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("a"), usb_chooser_controller_->GetOption(0)); + EXPECT_EQ(base::ASCIIToUTF16("c"), usb_chooser_controller_->GetOption(1)); + + device_client_.usb_service()->RemoveDevice(device_a); + EXPECT_EQ(1u, usb_chooser_controller_->NumOptions()); + EXPECT_EQ(base::ASCIIToUTF16("c"), usb_chooser_controller_->GetOption(0)); + + device_client_.usb_service()->RemoveDevice(device_c); + EXPECT_EQ(0u, usb_chooser_controller_->NumOptions()); +} + +TEST_F(UsbChooserControllerTest, AddAndRemoveDeviceWithSameName) { + scoped_refptr device_a_1 = + CreateMockUsbDevice("a", "001"); + device_client_.usb_service()->AddDevice(device_a_1); + EXPECT_EQ(base::ASCIIToUTF16("a"), usb_chooser_controller_->GetOption(0)); + scoped_refptr device_b = + CreateMockUsbDevice("b", "002"); + device_client_.usb_service()->AddDevice(device_b); + scoped_refptr device_a_2 = + CreateMockUsbDevice("a", "002"); + device_client_.usb_service()->AddDevice(device_a_2); + EXPECT_EQ(base::ASCIIToUTF16("a (001)"), + usb_chooser_controller_->GetOption(0)); + EXPECT_EQ(base::ASCIIToUTF16("b"), usb_chooser_controller_->GetOption(1)); + EXPECT_EQ(base::ASCIIToUTF16("a (002)"), + usb_chooser_controller_->GetOption(2)); + + device_client_.usb_service()->RemoveDevice(device_a_1); + EXPECT_EQ(base::ASCIIToUTF16("b"), usb_chooser_controller_->GetOption(0)); + EXPECT_EQ(base::ASCIIToUTF16("a"), usb_chooser_controller_->GetOption(1)); +} diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 6adc5976721cd2..72c1d9d7e0f2fb 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1587,6 +1587,7 @@ 'browser/ui/window_sizer/window_sizer_unittest.cc', 'browser/ui/zoom/zoom_controller_unittest.cc', 'browser/usb/usb_chooser_context_unittest.cc', + 'browser/usb/usb_chooser_controller_unittest.cc', 'browser/usb/web_usb_detector_unittest.cc', # The importer code is not used on Android. 'common/importer/firefox_importer_utils_unittest.cc', diff --git a/device/usb/mock_usb_device.h b/device/usb/mock_usb_device.h index 6c6241a5ad0ca9..a9a6cd0ca6f32f 100644 --- a/device/usb/mock_usb_device.h +++ b/device/usb/mock_usb_device.h @@ -7,11 +7,13 @@ #include +#include #include #include #include "device/usb/usb_device.h" #include "device/usb/usb_device_handle.h" +#include "device/usb/webusb_descriptors.h" #include "testing/gmock/include/gmock/gmock.h" namespace device { @@ -44,6 +46,11 @@ class MockUsbDevice : public UsbDevice { void AddMockConfig(const UsbConfigDescriptor& config); + void set_webusb_allowed_origins( + std::unique_ptr webusb_allowed_origins) { + webusb_allowed_origins_ = std::move(webusb_allowed_origins); + } + // Public wrappers around protected functions. void ActiveConfigurationChanged(int configuration_value); void NotifyDeviceRemoved();