Commit f4f799ec authored by Michael Hansen's avatar Michael Hansen Committed by Commit Bot

[Nearby] Validate device name.

This adds support for validating the device name that a user enters.
Validation happens as the user types and also when they try to save the
name. If an invalid name is detected, an error message will appear and
the "Done" button will be disabled.

Screenshots:
  https://screenshot.googleplex.com/3gnC6aQVyj4YmkX.png
  https://screenshot.googleplex.com/5arMAbok2MgfioU.png
  https://screenshot.googleplex.com/BEbCJ9LteRAYFpv.png

Bug: b:161297140
Change-Id: I3290eb92222cd796a1dede3ce603da5cc44940bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2424675
Commit-Queue: Michael Hansen <hansenmichael@google.com>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarAlex Gough <ajgo@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#811482}
parent 003f6f3f
......@@ -53,6 +53,17 @@
Your device visibility controls who can share with you while your screen is unlocked
</message>
<!-- Device name validation -->
<message name="IDS_NEARBY_DEVICE_NAME_EMPTY_ERROR" desc="Error message when the user has left the device name empty to indicate that they are required to provide a name.">
Add a device name to continue
</message>
<message name="IDS_NEARBY_DEVICE_NAME_TOO_LONG_ERROR" desc="Error message when the user has entered a device name that is too long and must enter a shorter one.">
Device name too long
</message>
<message name="IDS_NEARBY_DEVICE_NAME_INVALID_CHARACTERS_ERROR" desc="Error message when the user has entered a device name that contains invalid characters.">
Device name contains invalid characters
</message>
<!-- Discovery page -->
<message name="IDS_NEARBY_DISCOVERY_PAGE_INFO" desc="Help text on how to use the Nearby Share feature. Explains how to enable it on a nearby Chromebook to share with it.">
Make sure both devices are unlocked, close together, and have Bluetooth turned on. If you’re sharing with a Chromebook, make sure it has Nearby Sharing turned on (open the status area by selecting the time, then select Nearby Share).
......
ff767fad53b3e885935a6414a000338ec704c2b2
\ No newline at end of file
7a6874c1390be0538bf041fe4cf71d4bf406cbc8
\ No newline at end of file
59f33a02cc8311d5d4ea79f7a4c7c3a675481fae
\ No newline at end of file
......@@ -16,6 +16,8 @@ source_set("local_device_data") {
"nearby_share_local_device_data_manager_impl.h",
]
public_deps = [ "//chrome/browser/ui/webui/nearby_share/public/mojom" ]
deps = [
"//base",
"//chrome/browser/nearby_sharing/client",
......
......@@ -77,16 +77,27 @@ base::Optional<std::string> FakeNearbyShareLocalDeviceDataManager::GetIconUrl()
return icon_url_;
}
void FakeNearbyShareLocalDeviceDataManager::SetDeviceName(
nearby_share::mojom::DeviceNameValidationResult
FakeNearbyShareLocalDeviceDataManager::ValidateDeviceName(
const std::string& name) {
if (device_name_ == name)
return;
return next_validation_result_;
}
device_name_ = name;
NotifyLocalDeviceDataChanged(
/*did_device_name_change=*/true,
/*did_full_name_change=*/false,
/*did_icon_url_change=*/false);
nearby_share::mojom::DeviceNameValidationResult
FakeNearbyShareLocalDeviceDataManager::SetDeviceName(const std::string& name) {
if (next_validation_result_ !=
nearby_share::mojom::DeviceNameValidationResult::kValid)
return next_validation_result_;
if (device_name_ != name) {
device_name_ = name;
NotifyLocalDeviceDataChanged(
/*did_device_name_change=*/true,
/*did_full_name_change=*/false,
/*did_icon_url_change=*/false);
}
return nearby_share::mojom::DeviceNameValidationResult::kValid;
}
void FakeNearbyShareLocalDeviceDataManager::DownloadDeviceData() {
......
......@@ -13,6 +13,7 @@
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
class NearbyShareClientFactory;
class PrefService;
......@@ -84,7 +85,10 @@ class FakeNearbyShareLocalDeviceDataManager
std::string GetDeviceName() const override;
base::Optional<std::string> GetFullName() const override;
base::Optional<std::string> GetIconUrl() const override;
void SetDeviceName(const std::string& name) override;
nearby_share::mojom::DeviceNameValidationResult ValidateDeviceName(
const std::string& name) override;
nearby_share::mojom::DeviceNameValidationResult SetDeviceName(
const std::string& name) override;
void DownloadDeviceData() override;
void UploadContacts(std::vector<nearbyshare::proto::Contact> contacts,
UploadCompleteCallback callback) override;
......@@ -112,6 +116,11 @@ class FakeNearbyShareLocalDeviceDataManager
return upload_certificates_calls_;
}
void set_next_validation_result(
nearby_share::mojom::DeviceNameValidationResult result) {
next_validation_result_ = result;
}
private:
// NearbyShareLocalDeviceDataManager:
void OnStart() override;
......@@ -124,6 +133,8 @@ class FakeNearbyShareLocalDeviceDataManager
size_t num_download_device_data_calls_ = 0;
std::vector<UploadContactsCall> upload_contacts_calls_;
std::vector<UploadCertificatesCall> upload_certificates_calls_;
nearby_share::mojom::DeviceNameValidationResult next_validation_result_ =
nearby_share::mojom::DeviceNameValidationResult::kValid;
};
#endif // CHROME_BROWSER_NEARBY_SHARING_LOCAL_DEVICE_DATA_FAKE_NEARBY_SHARE_LOCAL_DEVICE_DATA_MANAGER_H_
......@@ -13,6 +13,7 @@
#include "base/observer_list_types.h"
#include "base/optional.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
// Manages local device data related to the UpdateDevice RPC such as the device
// ID, name, and icon url; provides the user's full name and icon URL returned
......@@ -58,11 +59,18 @@ class NearbyShareLocalDeviceDataManager {
// not yet been set from an UpdateDevice RPC response.
virtual base::Optional<std::string> GetIconUrl() const = 0;
// Sets and persists the device name in prefs. The device name is *not*
// uploaded to the Nearby Share server; the UpdateDevice proto device_name
// field in an artifact. Observers are notified via OnLocalDeviceDataChanged()
// if the device name changes.
virtual void SetDeviceName(const std::string& name) = 0;
// Validates the provided device name and returns an error if validation
// fails. This is just a check and the device name is not persisted.
virtual nearby_share::mojom::DeviceNameValidationResult ValidateDeviceName(
const std::string& name) = 0;
// Sets and persists the device name in prefs. The device name is first
// validated and if validation fails and error is returned and the device name
// is not persisted. The device name is *not* uploaded to the Nearby Share
// server; the UpdateDevice proto device_name field in an artifact. Observers
// are notified via OnLocalDeviceDataChanged() if the device name changes.
virtual nearby_share::mojom::DeviceNameValidationResult SetDeviceName(
const std::string& name) = 0;
// Makes an UpdateDevice RPC call to the Nearby Share server to retrieve all
// available device data, which includes the full name and icon URL for now.
......
......@@ -10,6 +10,7 @@
#include "base/memory/ptr_util.h"
#include "base/notreached.h"
#include "base/rand_util.h"
#include "base/strings/string_util.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater.h"
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl.h"
......@@ -37,6 +38,10 @@ constexpr base::TimeDelta kUpdateDeviceDataTimeout =
constexpr base::TimeDelta kDeviceDataDownloadPeriod =
base::TimeDelta::FromHours(1);
// The maximum length allowed for a device name, as encoded in UTF-8 in a
// std::string, which will not contain a null terminator.
size_t kDeviceNameMaxByteLength = 32;
} // namespace
// static
......@@ -131,17 +136,37 @@ base::Optional<std::string> NearbyShareLocalDeviceDataManagerImpl::GetIconUrl()
return url;
}
void NearbyShareLocalDeviceDataManagerImpl::SetDeviceName(
nearby_share::mojom::DeviceNameValidationResult
NearbyShareLocalDeviceDataManagerImpl::ValidateDeviceName(
const std::string& name) {
if (name.empty())
return nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty;
if (!base::IsStringUTF8(name))
return nearby_share::mojom::DeviceNameValidationResult::kErrorNotValidUtf8;
if (name.length() > kDeviceNameMaxByteLength)
return nearby_share::mojom::DeviceNameValidationResult::kErrorTooLong;
return nearby_share::mojom::DeviceNameValidationResult::kValid;
}
nearby_share::mojom::DeviceNameValidationResult
NearbyShareLocalDeviceDataManagerImpl::SetDeviceName(const std::string& name) {
if (name == GetDeviceName())
return;
return nearby_share::mojom::DeviceNameValidationResult::kValid;
auto error = ValidateDeviceName(name);
if (error != nearby_share::mojom::DeviceNameValidationResult::kValid)
return error;
// TODO(b/161297140): Perform input validation.
pref_service_->SetString(prefs::kNearbySharingDeviceNamePrefName, name);
NotifyLocalDeviceDataChanged(/*did_device_name_change=*/true,
/*did_full_name_change=*/false,
/*did_icon_url_change=*/false);
return nearby_share::mojom::DeviceNameValidationResult::kValid;
}
void NearbyShareLocalDeviceDataManagerImpl::DownloadDeviceData() {
......
......@@ -14,6 +14,7 @@
#include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "chrome/browser/nearby_sharing/proto/device_rpc.pb.h"
#include "chrome/browser/nearby_sharing/proto/rpc_resources.pb.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
class NearbyShareClientFactory;
class NearbyShareDeviceDataUpdater;
......@@ -60,7 +61,10 @@ class NearbyShareLocalDeviceDataManagerImpl
std::string GetDeviceName() const override;
base::Optional<std::string> GetFullName() const override;
base::Optional<std::string> GetIconUrl() const override;
void SetDeviceName(const std::string& name) override;
nearby_share::mojom::DeviceNameValidationResult ValidateDeviceName(
const std::string& name) override;
nearby_share::mojom::DeviceNameValidationResult SetDeviceName(
const std::string& name) override;
void DownloadDeviceData() override;
void UploadContacts(std::vector<nearbyshare::proto::Contact> contacts,
UploadCompleteCallback callback) override;
......
......@@ -25,6 +25,9 @@ namespace {
const char kFakeDefaultDeviceName[] = "Barack's Chromebook";
const char kFakeDeviceName[] = "My Cool Chromebook";
const char kFakeEmptyDeviceName[] = "";
const char kFakeTooLongDeviceName[] = "this string is 33 bytes in UTF-8!";
const char kFakeInvalidDeviceName[] = {0xC0};
const char kFakeFullName[] = "Barack Obama";
const char kFakeIconUrl[] = "https://www.google.com";
......@@ -256,6 +259,19 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, DeviceId) {
EXPECT_EQ(id, manager()->GetId());
}
TEST_F(NearbyShareLocalDeviceDataManagerImplTest, ValidateDeviceName) {
CreateManager();
EXPECT_EQ(manager()->ValidateDeviceName(kFakeDeviceName),
nearby_share::mojom::DeviceNameValidationResult::kValid);
EXPECT_EQ(manager()->ValidateDeviceName(kFakeEmptyDeviceName),
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
EXPECT_EQ(manager()->ValidateDeviceName(kFakeTooLongDeviceName),
nearby_share::mojom::DeviceNameValidationResult::kErrorTooLong);
EXPECT_EQ(
manager()->ValidateDeviceName(kFakeInvalidDeviceName),
nearby_share::mojom::DeviceNameValidationResult::kErrorNotValidUtf8);
}
TEST_F(NearbyShareLocalDeviceDataManagerImplTest, SetDeviceName) {
CreateManager();
......@@ -265,7 +281,27 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, SetDeviceName) {
EXPECT_EQ(kFakeDefaultDeviceName, manager()->GetDeviceName());
EXPECT_TRUE(notifications().empty());
manager()->SetDeviceName(kFakeDeviceName);
auto error = manager()->SetDeviceName(kFakeEmptyDeviceName);
EXPECT_EQ(error,
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
EXPECT_EQ(kFakeDefaultDeviceName, manager()->GetDeviceName());
EXPECT_TRUE(notifications().empty());
error = manager()->SetDeviceName(kFakeTooLongDeviceName);
EXPECT_EQ(error,
nearby_share::mojom::DeviceNameValidationResult::kErrorTooLong);
EXPECT_EQ(kFakeDefaultDeviceName, manager()->GetDeviceName());
EXPECT_TRUE(notifications().empty());
error = manager()->SetDeviceName(kFakeInvalidDeviceName);
EXPECT_EQ(
error,
nearby_share::mojom::DeviceNameValidationResult::kErrorNotValidUtf8);
EXPECT_EQ(kFakeDefaultDeviceName, manager()->GetDeviceName());
EXPECT_TRUE(notifications().empty());
error = manager()->SetDeviceName(kFakeDeviceName);
EXPECT_EQ(error, nearby_share::mojom::DeviceNameValidationResult::kValid);
EXPECT_EQ(kFakeDeviceName, manager()->GetDeviceName());
EXPECT_EQ(1u, notifications().size());
EXPECT_EQ(ObserverNotification(/*did_device_name_change=*/true,
......
......@@ -96,8 +96,20 @@ void NearbyShareSettings::GetDeviceName(
std::move(callback).Run(GetDeviceName());
}
void NearbyShareSettings::SetDeviceName(const std::string& device_name) {
local_device_data_manager_->SetDeviceName(device_name);
void NearbyShareSettings::ValidateDeviceName(
const std::string& device_name,
base::OnceCallback<void(nearby_share::mojom::DeviceNameValidationResult)>
callback) {
std::move(callback).Run(
local_device_data_manager_->ValidateDeviceName(device_name));
}
void NearbyShareSettings::SetDeviceName(
const std::string& device_name,
base::OnceCallback<void(nearby_share::mojom::DeviceNameValidationResult)>
callback) {
return std::move(callback).Run(
local_device_data_manager_->SetDeviceName(device_name));
}
void NearbyShareSettings::GetDataUsage(
......
......@@ -61,7 +61,14 @@ class NearbyShareSettings : public nearby_share::mojom::NearbyShareSettings,
void SetEnabled(bool enabled) override;
void GetDeviceName(
base::OnceCallback<void(const std::string&)> callback) override;
void SetDeviceName(const std::string& device_name) override;
void ValidateDeviceName(
const std::string& device_name,
base::OnceCallback<void(nearby_share::mojom::DeviceNameValidationResult)>
callback) override;
void SetDeviceName(
const std::string& device_name,
base::OnceCallback<void(nearby_share::mojom::DeviceNameValidationResult)>
callback) override;
void GetDataUsage(base::OnceCallback<void(nearby_share::mojom::DataUsage)>
callback) override;
void SetDataUsage(nearby_share::mojom::DataUsage data_usage) override;
......
......@@ -119,13 +119,43 @@ TEST_F(NearbyShareSettingsTest, GetAndSetEnabled) {
EXPECT_EQ(true, observer_.enabled);
}
TEST_F(NearbyShareSettingsTest, ValidateDeviceName) {
auto result = nearby_share::mojom::DeviceNameValidationResult::kValid;
local_device_data_manager_.set_next_validation_result(
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
nearby_share_settings_waiter_.ValidateDeviceName("", &result);
EXPECT_EQ(result,
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
local_device_data_manager_.set_next_validation_result(
nearby_share::mojom::DeviceNameValidationResult::kValid);
nearby_share_settings_waiter_.ValidateDeviceName(
"this string is 32 bytes in UTF-8", &result);
EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kValid);
}
TEST_F(NearbyShareSettingsTest, GetAndSetDeviceName) {
std::string name = "not_the_default";
nearby_share_settings_waiter_.GetDeviceName(&name);
EXPECT_EQ(kDefaultDeviceName, name);
// When we get a validation error, setting the name should not succeed.
EXPECT_EQ("uncalled", observer_.device_name);
auto result = nearby_share::mojom::DeviceNameValidationResult::kValid;
local_device_data_manager_.set_next_validation_result(
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
nearby_share_settings_waiter_.SetDeviceName("", &result);
EXPECT_EQ(result,
nearby_share::mojom::DeviceNameValidationResult::kErrorEmpty);
EXPECT_EQ(kDefaultDeviceName, nearby_share_settings_.GetDeviceName());
// When the name is valid, setting should succeed.
EXPECT_EQ("uncalled", observer_.device_name);
nearby_share_settings_.SetDeviceName("d");
result = nearby_share::mojom::DeviceNameValidationResult::kValid;
local_device_data_manager_.set_next_validation_result(
nearby_share::mojom::DeviceNameValidationResult::kValid);
nearby_share_settings_waiter_.SetDeviceName("d", &result);
EXPECT_EQ(result, nearby_share::mojom::DeviceNameValidationResult::kValid);
EXPECT_EQ("d", nearby_share_settings_.GetDeviceName());
EXPECT_EQ("uncalled", observer_.device_name);
......
......@@ -299,6 +299,7 @@ nearby_shared_auto_imports_closure_fix = [
# does not exist on disk there. The actual resources are in
# c/b/r/nearby_share/shared and are re-hosted in the chrome://os-settings
# webui at the chrome://os-settings/shared/* prefix.
"chrome/browser/resources/settings/shared/nearby_share_settings.html|getNearbyShareSettings",
"chrome/browser/resources/settings/shared/nearby_share_settings_behavior.html|NearbyShareSettingsBehavior,NearbySettings",
]
......
......@@ -5,6 +5,7 @@
<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../shared/nearby_share_settings.html">
<link rel="import" href="../../shared/nearby_share_settings_behavior.html">
<dom-module id="nearby-share-device-name-dialog">
......@@ -16,14 +17,17 @@
$i18n{nearbyShareDeviceNameDialogTitle}
</div>
<div slot="body">
<cr-input value="[[settings.deviceName]]" autofocus>
<cr-input value="[[settings.deviceName]]" on-input="onDeviceNameInput_"
error-message="[[errorMessage]]"
invalid="[[hasErrorMessage_(errorMessage)]]" autofocus>
</cr-input>
</div>
<div class="layout horizontal center" slot="button-container">
<cr-button class="cancel-button" on-click="onCancelTap_">
$i18n{cancel}
</cr-button>
<cr-button class="action-button" on-click="onDoneTap_">
<cr-button id="doneButton" class="action-button" on-click="onDoneTap_"
disabled="[[hasErrorMessage_(errorMessage)]]">
$i18n{done}
</cr-button>
</div>
......
......@@ -19,6 +19,12 @@ Polymer({
settings: {
type: Object,
},
/** @type {string} */
errorMessage: {
type: String,
value: '',
},
},
attached() {
......@@ -39,6 +45,15 @@ Polymer({
}
},
/** @private */
onDeviceNameInput_() {
nearby_share.getNearbyShareSettings()
.validateDeviceName(this.getEditInputValue_())
.then((result) => {
this.updateErrorMessage_(result.result);
});
},
/** @private */
onCancelTap_() {
this.close();
......@@ -46,7 +61,57 @@ Polymer({
/** @private */
onDoneTap_() {
this.set('settings.deviceName', this.$$('cr-input').value);
this.close();
nearby_share.getNearbyShareSettings()
.setDeviceName(this.getEditInputValue_())
.then((result) => {
this.updateErrorMessage_(result.result);
if (result.result ===
nearbyShare.mojom.DeviceNameValidationResult.kValid) {
this.close();
}
});
},
/**
* @private
*
* @param {!nearbyShare.mojom.DeviceNameValidationResult} validationResult The
* error status from validating the provided device name.
*/
updateErrorMessage_(validationResult) {
switch (validationResult) {
case nearbyShare.mojom.DeviceNameValidationResult.kErrorEmpty:
this.errorMessage = this.i18n('nearbyShareDeviceNameEmptyError');
break;
case nearbyShare.mojom.DeviceNameValidationResult.kErrorTooLong:
this.errorMessage = this.i18n('nearbyShareDeviceNameTooLongError');
break;
case nearbyShare.mojom.DeviceNameValidationResult.kErrorNotValidUtf8:
this.errorMessage =
this.i18n('nearbyShareDeviceNameInvalidCharactersError');
break;
default:
this.errorMessage = '';
break;
}
},
/**
* @private
*
* @return {!string}
*/
getEditInputValue_() {
return this.$$('cr-input').value;
},
/**
* @private
*
* @param {!string} errorMessage The error message.
* @return {boolean} Whether or not the error message exists.
*/
hasErrorMessage_(errorMessage) {
return errorMessage !== '';
}
});
......@@ -30,6 +30,18 @@ enum Visibility {
kSelectedContacts = 3
};
// Represents the error result when validating the device name.
enum DeviceNameValidationResult {
// The device name was valid.
kValid = 0,
// The device name must not be empty.
kErrorEmpty = 1,
// The device name is too long.
kErrorTooLong = 2,
// The device name is not valid UTF-8.
kErrorNotValidUtf8 = 3
};
// This observer interface allows clients to be notified whenever key Nearby
// Share settings are changed.
interface NearbyShareSettingsObserver {
......@@ -60,9 +72,14 @@ interface NearbyShareSettings {
// Get the device name shown to a sender when this device is available as
// a share target. |device_name| is the new device name.
GetDeviceName() => (string device_name);
// Validate the device name shown to a sender when this device is available
// as a share target. This is a separate function so that we can call it to
// validate input as a user types.
ValidateDeviceName(string device_name) => (DeviceNameValidationResult result);
// Set the device name shown to a sender when this device is available as
// a share target.
SetDeviceName(string device_name);
// a share target. Before saving the new name this will validate it and
// respond with an error if it is invalid.
SetDeviceName(string device_name) => (DeviceNameValidationResult result);
// Get which type of network connectivity Nearby Share can operate on.
GetDataUsage() => (DataUsage data_usage);
......
......@@ -114,6 +114,11 @@ void RegisterNearbySharedStrings(content::WebUIDataSource* data_source) {
IDS_NEARBY_CONTACT_VISIBILITY_ZERO_STATE_INFO},
{"nearbyShareContactVisibilityZeroStateText",
IDS_NEARBY_CONTACT_VISIBILITY_ZERO_STATE_TEXT},
{"nearbyShareDeviceNameEmptyError", IDS_NEARBY_DEVICE_NAME_EMPTY_ERROR},
{"nearbyShareDeviceNameTooLongError",
IDS_NEARBY_DEVICE_NAME_TOO_LONG_ERROR},
{"nearbyShareDeviceNameInvalidCharactersError",
IDS_NEARBY_DEVICE_NAME_INVALID_CHARACTERS_ERROR},
{"nearbyShareDiscoveryPageInfo", IDS_NEARBY_DISCOVERY_PAGE_INFO},
{"nearbyShareDiscoveryPageSubtitle", IDS_NEARBY_DISCOVERY_PAGE_SUBTITLE},
{"nearbyShareDiscoveryPageTitle", IDS_NEARBY_DISCOVERY_PAGE_TITLE},
......
......@@ -25,6 +25,9 @@ cr.define('nearby_share', function() {
this.allowedContacts_ = [];
/** @private {!nearbyShare.mojom.NearbyShareSettingsObserverInterface} */
this.observer_;
/** @private {!nearbyShare.mojom.DeviceNameValidationResult} */
this.nextDeviceNameResult_ =
nearbyShare.mojom.DeviceNameValidationResult.kValid;
/** @private {Object} */
this.$ = {
close() {},
......@@ -40,6 +43,15 @@ cr.define('nearby_share', function() {
this.observer_ = observer;
}
/**
* @param { !nearbyShare.mojom.DeviceNameValidationResult } result
*/
setNextDeviceNameResult(result) {
// Set the next result to be used when calling ValidateDeviceName() or
// SetDeviceName().
this.nextDeviceNameResult_ = result;
}
/**
* @return {!Promise<{enabled: !boolean}>}
*/
......@@ -66,12 +78,32 @@ cr.define('nearby_share', function() {
/**
* @param { !string } deviceName
* @return {!Promise<{
result: !nearbyShare.mojom.DeviceNameValidationResult,
* }>}
*/
async validateDeviceName(deviceName) {
return {result: this.nextDeviceNameResult_};
}
/**
* @param { !string } deviceName
* @return {!Promise<{
result: !nearbyShare.mojom.DeviceNameValidationResult,
* }>}
*/
setDeviceName(deviceName) {
async setDeviceName(deviceName) {
if (this.nextDeviceNameResult_ !==
nearbyShare.mojom.DeviceNameValidationResult.kValid) {
return {result: this.nextDeviceNameResult_};
}
this.deviceName_ = deviceName;
if (this.observer_) {
this.observer_.onDeviceNameChanged(deviceName);
}
return {result: this.nextDeviceNameResult_};
}
/**
......
......@@ -56,6 +56,8 @@ suite('NearbyShare', function() {
let accountManagerBrowserProxy = null;
/** @type {!nearby_share.FakeContactManager} */
const fakeContactManager = new nearby_share.FakeContactManager();
/** @type {!nearby_share.FakeNearbyShareSettings} */
let fakeSettings = null;
setup(function() {
accountManagerBrowserProxy = new TestAccountManagerBrowserProxy();
......@@ -68,8 +70,7 @@ suite('NearbyShare', function() {
nearby_share.setContactManagerForTesting(fakeContactManager);
fakeContactManager.setupContactRecords();
/** @type {!nearbyShare.mojom.NearbyShareSettingsInterface} */
const fakeSettings = new nearby_share.FakeNearbyShareSettings();
fakeSettings = new nearby_share.FakeNearbyShareSettings();
fakeSettings.setEnabled(true);
nearby_share.setNearbyShareSettingsForTesting(fakeSettings);
......@@ -162,6 +163,31 @@ suite('NearbyShare', function() {
subpage.set('settings.deviceName', oldName);
});
test('validate device name preference', async () => {
subpage.$$('#editDeviceNameButton').click();
Polymer.dom.flush();
const dialog = subpage.$$('nearby-share-device-name-dialog');
const input = dialog.$$('cr-input');
const doneButton = dialog.$$('#doneButton');
fakeSettings.setNextDeviceNameResult(
nearbyShare.mojom.DeviceNameValidationResult.kErrorEmpty);
input.fire('input');
// Allow the validation promise to resolve.
await test_util.waitAfterNextRender();
Polymer.dom.flush();
assertTrue(input.invalid);
assertTrue(doneButton.disabled);
fakeSettings.setNextDeviceNameResult(
nearbyShare.mojom.DeviceNameValidationResult.kValid);
input.fire('input');
await test_util.waitAfterNextRender();
Polymer.dom.flush();
assertFalse(input.invalid);
assertFalse(doneButton.disabled);
});
test('update data usage preference', function() {
assertEquals(3, subpage.prefs.nearby_sharing.data_usage.value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment