CrOS Settings: Convert apn detail dialog browser test to TS
Bug: b/270728282 Test: browser_tests --gtest_filter="*ApnDetailDialog*" Change-Id: I1ae97454cfb1fe7212aae8fe26ffb17ecd92293e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4908401 Commit-Queue: Ruma Kesh <rkesh@google.com> Reviewed-by: Wes Okuhara <wesokuhara@google.com> Cr-Commit-Position: refs/heads/main@{#1207351}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
80516eb1c8
commit
adb7d16865
ash/webui/common/resources/network
chrome
browser
resources
ash
settings
test
data
@ -2,4 +2,26 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
export {};
|
||||
import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
|
||||
import {ApnProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
|
||||
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
|
||||
|
||||
import {ApnDetailDialogMode} from './cellular_utils.js';
|
||||
|
||||
export class ApnDetailDialog extends I18nMixin
|
||||
(PolymerElement) {
|
||||
guid:
|
||||
string;
|
||||
apnProperties:
|
||||
ApnProperties|undefined;
|
||||
mode:
|
||||
ApnDetailDialogMode;
|
||||
apnList:
|
||||
ApnProperties[];
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'apn-detail-dialog': ApnDetailDialog;
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ export {LifetimeBrowserProxy, LifetimeBrowserProxyImpl} from '/shared/settings/l
|
||||
export {ProfileInfo, ProfileInfoBrowserProxy, ProfileInfoBrowserProxyImpl} from '/shared/settings/people_page/profile_info_browser_proxy.js';
|
||||
export {PageStatus, StatusAction, StoredAccount, SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, SyncStatus} from '/shared/settings/people_page/sync_browser_proxy.js';
|
||||
export {PrivacyPageBrowserProxyImpl, SecureDnsMode, SecureDnsUiManagementMode} from '/shared/settings/privacy_page/privacy_page_browser_proxy.js';
|
||||
export {ApnDetailDialog} from 'chrome://resources/ash/common/network/apn_detail_dialog.js';
|
||||
export {AppManagementFileHandlingItemElement} from 'chrome://resources/cr_components/app_management/file_handling_item.js';
|
||||
export {AppManagementSupportedLinksItemElement} from 'chrome://resources/cr_components/app_management/supported_links_item.js';
|
||||
export {AppManagementToggleRowElement} from 'chrome://resources/cr_components/app_management/toggle_row.js';
|
||||
|
@ -22,7 +22,7 @@ build_webui_tests("build") {
|
||||
|
||||
files = [
|
||||
"apn_subpage_tests.js",
|
||||
"apn_detail_dialog_tests.js",
|
||||
"apn_detail_dialog_test.ts",
|
||||
"cellular_networks_list_test.js",
|
||||
"cellular_roaming_toggle_button_test.js",
|
||||
"crostini_extra_containers_subpage_test.js",
|
||||
|
@ -0,0 +1,520 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://os-settings/os_settings.js';
|
||||
|
||||
import {ApnDetailDialog, CrCheckboxElement, CrDialogElement, CrInputElement} from 'chrome://os-settings/os_settings.js';
|
||||
import {ApnDetailDialogMode} from 'chrome://resources/ash/common/network/cellular_utils.js';
|
||||
import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js';
|
||||
import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
|
||||
import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnState, ApnType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
|
||||
import {NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
|
||||
import {assertEquals, assertFalse, assertNull, assertStringContains, assertTrue} from 'chrome://webui-test/chai_assert.js';
|
||||
import {FakeNetworkConfig} from 'chrome://webui-test/chromeos/fake_network_config_mojom.js';
|
||||
import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
|
||||
import {disableAnimationsAndTransitions} from 'chrome://webui-test/test_api.js';
|
||||
import {eventToPromise} from 'chrome://webui-test/test_util.js';
|
||||
|
||||
const TEST_APN: ApnProperties = {
|
||||
accessPointName: 'apn',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
authentication: ApnAuthenticationType.kAutomatic,
|
||||
ipType: ApnIpType.kAutomatic,
|
||||
apnTypes: [ApnType.kDefault],
|
||||
state: ApnState.kEnabled,
|
||||
id: undefined,
|
||||
language: undefined,
|
||||
localizedName: undefined,
|
||||
name: undefined,
|
||||
attach: undefined,
|
||||
};
|
||||
|
||||
suite('<apn-detail-dialog>', () => {
|
||||
let apnDetailDialog: ApnDetailDialog;
|
||||
let mojoApi: FakeNetworkConfig;
|
||||
|
||||
function toggleAdvancedSettings(): void {
|
||||
const advancedSettingsBtn =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#advancedSettingsBtn');
|
||||
assertTrue(!!advancedSettingsBtn);
|
||||
advancedSettingsBtn.click();
|
||||
}
|
||||
|
||||
function assertElementEnabled(selector: string): void {
|
||||
const element = apnDetailDialog.shadowRoot!.querySelector<
|
||||
HTMLInputElement|HTMLSelectElement|HTMLButtonElement|CrCheckboxElement>(
|
||||
selector);
|
||||
assertTrue(!!element);
|
||||
assertFalse(element.disabled);
|
||||
}
|
||||
|
||||
function assertAllInputsEnabled(): void {
|
||||
assertElementEnabled('#apnInput');
|
||||
assertElementEnabled('#usernameInput');
|
||||
assertElementEnabled('#passwordInput');
|
||||
assertElementEnabled('#authTypeDropDown');
|
||||
assertElementEnabled('#apnDefaultTypeCheckbox');
|
||||
assertElementEnabled('#apnAttachTypeCheckbox');
|
||||
assertElementEnabled('#ipTypeDropDown');
|
||||
}
|
||||
|
||||
suiteSetup(() => {
|
||||
disableAnimationsAndTransitions();
|
||||
mojoApi = new FakeNetworkConfig();
|
||||
MojoInterfaceProviderImpl.getInstance().setMojoServiceRemoteForTest(
|
||||
mojoApi);
|
||||
});
|
||||
|
||||
teardown(() => {
|
||||
apnDetailDialog.remove();
|
||||
mojoApi.resetForTest();
|
||||
});
|
||||
|
||||
async function init(
|
||||
mode?: ApnDetailDialogMode,
|
||||
apnProperties?: ApnProperties): Promise<void> {
|
||||
apnDetailDialog = document.createElement('apn-detail-dialog');
|
||||
apnDetailDialog.guid = 'fake-guid';
|
||||
apnDetailDialog.apnList = [TEST_APN];
|
||||
apnDetailDialog.mode = mode || ApnDetailDialogMode.CREATE;
|
||||
apnDetailDialog.apnProperties = apnProperties;
|
||||
document.body.appendChild(apnDetailDialog);
|
||||
await waitAfterNextRender(apnDetailDialog);
|
||||
}
|
||||
|
||||
test('Element contains dialog', async () => {
|
||||
await init();
|
||||
const dialog = apnDetailDialog.shadowRoot!.querySelector('cr-dialog');
|
||||
assertTrue(!!dialog);
|
||||
assertTrue(dialog.open);
|
||||
// Confirm that the dialog has the add apn title.
|
||||
const apnDetailDialogTitle =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLElement>(
|
||||
'#apnDetailDialogTitle');
|
||||
assertTrue(!!apnDetailDialogTitle);
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailAddApnDialogTitle'),
|
||||
apnDetailDialogTitle.innerText);
|
||||
assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#apnInput'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#usernameInput'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#passwordInput'));
|
||||
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot!.querySelector('#authTypeDropDown'));
|
||||
const defaultTypeCheckbox =
|
||||
apnDetailDialog.shadowRoot!.querySelector<CrCheckboxElement>(
|
||||
'#apnDefaultTypeCheckbox');
|
||||
assertTrue(!!defaultTypeCheckbox);
|
||||
assertTrue(defaultTypeCheckbox.checked);
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot!.querySelector('#apnAttachTypeCheckbox'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#ipTypeDropDown'));
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot!.querySelector('#apnDetailCancelBtn'));
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot!.querySelector('#apnDetailActionBtn'));
|
||||
assertNull(apnDetailDialog.shadowRoot!.querySelector('#apnDoneBtn'));
|
||||
assertEquals(
|
||||
apnDetailDialog.shadowRoot!.querySelector('#apnInput'),
|
||||
apnDetailDialog.shadowRoot!.activeElement);
|
||||
});
|
||||
|
||||
test('Clicking the cancel button fires the close event', async () => {
|
||||
await init();
|
||||
const closeEventPromise = eventToPromise('close', window);
|
||||
const cancelBtn =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailCancelBtn');
|
||||
assertTrue(!!cancelBtn);
|
||||
|
||||
cancelBtn.click();
|
||||
await closeEventPromise;
|
||||
const crDialogElement =
|
||||
apnDetailDialog.shadowRoot!.querySelector<CrDialogElement>(
|
||||
'#apnDetailDialog');
|
||||
assertTrue(!!crDialogElement);
|
||||
assertFalse(crDialogElement.open);
|
||||
});
|
||||
|
||||
test(
|
||||
'Clicking on the advanced settings button expands/collapses section',
|
||||
async () => {
|
||||
await init();
|
||||
const isAdvancedSettingShowing = () => {
|
||||
const ironCollapseElement =
|
||||
apnDetailDialog.shadowRoot!.querySelector('iron-collapse');
|
||||
assertTrue(!!ironCollapseElement);
|
||||
return ironCollapseElement.opened;
|
||||
};
|
||||
assertFalse(isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
assertTrue(!!isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
assertFalse(isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
const assertOptions =
|
||||
(expectedTextArray: string[],
|
||||
optionNodes: NodeListOf<HTMLOptionElement>) => {
|
||||
for (const [idx, expectedText] of expectedTextArray.entries()) {
|
||||
assertTrue(!!optionNodes[idx]);
|
||||
assertTrue(!!optionNodes[idx]!.text);
|
||||
assertEquals(expectedText, optionNodes[idx]!.text);
|
||||
}
|
||||
};
|
||||
const authTypeDropDown =
|
||||
apnDetailDialog.shadowRoot!.querySelector('#authTypeDropDown');
|
||||
assertTrue(!!authTypeDropDown);
|
||||
const authTypeOptionNodes = authTypeDropDown.querySelectorAll('option');
|
||||
assertEquals(3, authTypeOptionNodes.length);
|
||||
// Note: We are also checking that the items appear in a certain order.
|
||||
assertOptions(
|
||||
[
|
||||
apnDetailDialog.i18n('apnDetailTypeAuto'),
|
||||
apnDetailDialog.i18n('apnDetailAuthTypePAP'),
|
||||
apnDetailDialog.i18n('apnDetailAuthTypeCHAP'),
|
||||
],
|
||||
authTypeOptionNodes);
|
||||
|
||||
const ipTypeDropDown =
|
||||
apnDetailDialog.shadowRoot!.querySelector('#ipTypeDropDown');
|
||||
assertTrue(!!ipTypeDropDown);
|
||||
const ipTypeOptionNodes =
|
||||
ipTypeDropDown.querySelectorAll<HTMLOptionElement>('option');
|
||||
assertEquals(4, ipTypeOptionNodes.length);
|
||||
|
||||
assertOptions(
|
||||
[
|
||||
apnDetailDialog.i18n('apnDetailTypeAuto'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv4'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv6'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv4_Ipv6'),
|
||||
],
|
||||
ipTypeOptionNodes);
|
||||
});
|
||||
|
||||
test('Clicking on the add button calls createCustomApn', async () => {
|
||||
await init();
|
||||
const apnInput =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLInputElement>(
|
||||
'#apnInput');
|
||||
assertTrue(!!apnInput);
|
||||
apnInput.value = TEST_APN.accessPointName;
|
||||
const usernameInput =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLInputElement>(
|
||||
'#usernameInput');
|
||||
assertTrue(!!usernameInput);
|
||||
usernameInput.value = TEST_APN.username!;
|
||||
const passwordInput =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLInputElement>(
|
||||
'#passwordInput');
|
||||
assertTrue(!!passwordInput);
|
||||
passwordInput.value = TEST_APN.password!;
|
||||
|
||||
assertAllInputsEnabled();
|
||||
assertElementEnabled('#apnDetailCancelBtn');
|
||||
let actionBtn =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!actionBtn);
|
||||
assertEquals(apnDetailDialog.i18n('add'), actionBtn.innerText);
|
||||
|
||||
// Add a network.
|
||||
const network = OncMojo.getDefaultManagedProperties(
|
||||
NetworkType.kCellular, apnDetailDialog.guid, apnDetailDialog.guid);
|
||||
mojoApi.setManagedPropertiesForTest(network);
|
||||
await flushTasks();
|
||||
|
||||
const properties = await mojoApi.getManagedProperties(apnDetailDialog.guid);
|
||||
assertTrue(!!properties);
|
||||
assertEquals(
|
||||
undefined, properties.result.typeProperties.cellular!.customApnList);
|
||||
|
||||
actionBtn = apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!actionBtn);
|
||||
actionBtn.click();
|
||||
await flushTasks();
|
||||
await mojoApi.whenCalled('createCustomApn');
|
||||
|
||||
assertEquals(
|
||||
1, properties.result.typeProperties.cellular!.customApnList!.length);
|
||||
|
||||
const apn = properties.result.typeProperties.cellular!.customApnList![0];
|
||||
assertTrue(!!apn);
|
||||
assertEquals(TEST_APN.accessPointName, apn.accessPointName);
|
||||
assertEquals(TEST_APN.username, apn.username);
|
||||
assertEquals(TEST_APN.password, apn.password);
|
||||
assertEquals(TEST_APN.authentication, apn.authentication);
|
||||
assertEquals(TEST_APN.ipType, apn.ipType);
|
||||
assertEquals(TEST_APN.apnTypes.length, apn.apnTypes.length);
|
||||
assertEquals(TEST_APN.apnTypes[0], apn.apnTypes[0]);
|
||||
});
|
||||
|
||||
test('Setting mode to view changes buttons and fields', async () => {
|
||||
const assertFieldDisabled = (selector: string) => {
|
||||
const element = apnDetailDialog.shadowRoot!.querySelector<
|
||||
HTMLInputElement|HTMLSelectElement|CrCheckboxElement>(selector);
|
||||
assertTrue(!!element);
|
||||
assertTrue(element.disabled);
|
||||
};
|
||||
|
||||
// Set the dialog mode before opening the dialog so that the default focus
|
||||
// can be tested.
|
||||
await init(
|
||||
/* mode= */ ApnDetailDialogMode.VIEW, /* apnProperties= */ TEST_APN);
|
||||
|
||||
const apnDetailDialogTitle =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLElement>(
|
||||
'#apnDetailDialogTitle');
|
||||
assertTrue(!!apnDetailDialogTitle);
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailViewApnDialogTitle'),
|
||||
apnDetailDialogTitle.innerText);
|
||||
assertNull(
|
||||
apnDetailDialog.shadowRoot!.querySelector('#apnDetailCancelBtn'));
|
||||
assertNull(
|
||||
apnDetailDialog.shadowRoot!.querySelector('#apnDetailActionBtn'));
|
||||
const doneBtn =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDoneBtn');
|
||||
assertTrue(!!doneBtn);
|
||||
assertFalse(doneBtn.disabled);
|
||||
assertFieldDisabled('#apnInput');
|
||||
assertFieldDisabled('#usernameInput');
|
||||
assertFieldDisabled('#passwordInput');
|
||||
assertFieldDisabled('#authTypeDropDown');
|
||||
assertFieldDisabled('#apnDefaultTypeCheckbox');
|
||||
assertFieldDisabled('#apnAttachTypeCheckbox');
|
||||
assertFieldDisabled('#ipTypeDropDown');
|
||||
assertEquals(doneBtn, apnDetailDialog.shadowRoot!.activeElement);
|
||||
});
|
||||
|
||||
test('Dialog input fields are validated', async () => {
|
||||
await init();
|
||||
const apnInputField =
|
||||
apnDetailDialog.shadowRoot!.querySelector<CrInputElement>('#apnInput');
|
||||
assertTrue(!!apnInputField);
|
||||
const actionButton =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!actionButton);
|
||||
// Case: After opening dialog before user input
|
||||
assertFalse(apnInputField.invalid);
|
||||
assertTrue(actionButton.disabled);
|
||||
|
||||
// Case : After valid user input
|
||||
apnInputField.value = 'test';
|
||||
assertFalse(apnInputField.invalid);
|
||||
assertFalse(actionButton.disabled);
|
||||
|
||||
// Case : After Removing all user input no error state but button disabled
|
||||
apnInputField.value = '';
|
||||
assertFalse(apnInputField.invalid);
|
||||
assertTrue(actionButton.disabled);
|
||||
|
||||
// Case : Non ascii user input
|
||||
apnInputField.value = 'testμ';
|
||||
assertTrue(apnInputField.invalid);
|
||||
assertTrue(actionButton.disabled);
|
||||
assertStringContains(apnInputField.value, 'μ');
|
||||
|
||||
// Case : longer than 63 characters then removing one character
|
||||
apnInputField.value = 'a'.repeat(64);
|
||||
assertTrue(apnInputField.invalid);
|
||||
assertTrue(actionButton.disabled);
|
||||
assertEquals(63, apnInputField.value.length);
|
||||
apnInputField.value = apnInputField.value.slice(0, -1);
|
||||
assertFalse(apnInputField.invalid);
|
||||
assertFalse(actionButton.disabled);
|
||||
|
||||
// Case : longer than 63 non-ASCII characters
|
||||
apnInputField.value = 'μ'.repeat(64);
|
||||
assertTrue(apnInputField.invalid);
|
||||
assertTrue(actionButton.disabled);
|
||||
});
|
||||
|
||||
test('Apn types are correctly validated in all modes', async () => {
|
||||
await init();
|
||||
const updateApnTypeCheckboxes =
|
||||
(defaultType: boolean, attachType: boolean) => {
|
||||
const apnDefaultTypeCheckbox =
|
||||
apnDetailDialog.shadowRoot!.querySelector<CrCheckboxElement>(
|
||||
'#apnDefaultTypeCheckbox');
|
||||
assertTrue(!!apnDefaultTypeCheckbox);
|
||||
apnDefaultTypeCheckbox.checked = defaultType;
|
||||
|
||||
const apnAttachTypeCheckbox =
|
||||
apnDetailDialog.shadowRoot!.querySelector<CrCheckboxElement>(
|
||||
'#apnAttachTypeCheckbox');
|
||||
assertTrue(!!apnAttachTypeCheckbox);
|
||||
apnAttachTypeCheckbox.checked = attachType;
|
||||
};
|
||||
|
||||
toggleAdvancedSettings();
|
||||
const getDefaultApnInfo = () =>
|
||||
apnDetailDialog.shadowRoot!.querySelector('#defaultApnRequiredInfo');
|
||||
|
||||
TEST_APN.id = '1';
|
||||
const currentApn = {...TEST_APN};
|
||||
currentApn.id = '2';
|
||||
apnDetailDialog.set('apnList', [TEST_APN, currentApn]);
|
||||
apnDetailDialog.set('apnProperties', currentApn);
|
||||
|
||||
const actionButton =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!actionButton);
|
||||
const apnInputField =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLInputElement>(
|
||||
'#apnInput');
|
||||
assertTrue(!!apnInputField);
|
||||
apnInputField.value = 'valid_name';
|
||||
|
||||
// CREATE mode tests
|
||||
apnDetailDialog.mode = ApnDetailDialogMode.CREATE;
|
||||
TEST_APN.state = ApnState.kDisabled;
|
||||
apnDetailDialog.set('apnList', [TEST_APN]);
|
||||
|
||||
// Case: Default APN type is checked
|
||||
updateApnTypeCheckboxes(/* default= */ true, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Case: No enabled default APNs, default unchecked and attach is checked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: No enabled default APNs and both unchecked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Case: Enabled default APNs, default unchecked and attach is checked.
|
||||
TEST_APN.state = ApnState.kEnabled;
|
||||
apnDetailDialog.set('apnList', [TEST_APN]);
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Case: Enabled default APNs and both unchecked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Edit mode tests
|
||||
apnDetailDialog.set('mode', ApnDetailDialogMode.EDIT);
|
||||
TEST_APN.apnTypes = [ApnType.kAttach];
|
||||
currentApn.apnTypes = [ApnType.kDefault, ApnType.kAttach];
|
||||
apnDetailDialog.set('apnList', [TEST_APN, currentApn]);
|
||||
|
||||
// Case: Default APN type is checked
|
||||
updateApnTypeCheckboxes(/* default= */ true, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks the default checkbox, APN being modified is the
|
||||
// only default APN
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks both checkboxes, APN being modified is the
|
||||
// only enabled default APN but there are other enabled attach APNs.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks both checkboxes, APN being modified is the
|
||||
// only enabled default APN and is the only enabled attachApn.
|
||||
currentApn.apnTypes = [ApnType.kDefault, ApnType.kAttach];
|
||||
apnDetailDialog.set('apnList', [currentApn]);
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertNull(getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks default APN type checkbox and checks the attach
|
||||
// APN type checkbox, APN being modified is the only enabled default APN
|
||||
// and there are no other enabled attach type APNs.
|
||||
currentApn.apnTypes = [ApnType.kDefault];
|
||||
apnDetailDialog.set('apnList', [currentApn]);
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
});
|
||||
|
||||
test('Setting mode to edit changes buttons and fields', async () => {
|
||||
const apnWithId = TEST_APN;
|
||||
apnWithId.id = '1';
|
||||
apnWithId.apnTypes = [ApnType.kDefault];
|
||||
|
||||
// Set the dialog mode before opening the dialog so that the default focus
|
||||
// can be tested.
|
||||
await init(
|
||||
/* mode= */ ApnDetailDialogMode.EDIT, /* apnProperties= */ apnWithId);
|
||||
|
||||
const apnDetailDialogTitle =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLElement>(
|
||||
'#apnDetailDialogTitle');
|
||||
assertTrue(!!apnDetailDialogTitle);
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailEditApnDialogTitle'),
|
||||
apnDetailDialogTitle.innerText);
|
||||
assertElementEnabled('#apnDetailCancelBtn');
|
||||
let button = apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!button);
|
||||
assertEquals(apnDetailDialog.i18n('save'), button.innerText);
|
||||
assertNull(apnDetailDialog.shadowRoot!.querySelector('#apnDoneBtn'));
|
||||
assertAllInputsEnabled();
|
||||
|
||||
// Case: clicking on the action button calls the correct method
|
||||
const network = OncMojo.getDefaultManagedProperties(
|
||||
NetworkType.kCellular, apnDetailDialog.guid, apnDetailDialog.guid);
|
||||
mojoApi.setManagedPropertiesForTest(network);
|
||||
await flushTasks();
|
||||
const managedProperties =
|
||||
await mojoApi.getManagedProperties(apnDetailDialog.guid);
|
||||
assertTrue(!!managedProperties);
|
||||
mojoApi.createCustomApn(apnDetailDialog.guid, apnWithId);
|
||||
const newExpectedApn = 'modified';
|
||||
const apnInputField =
|
||||
apnDetailDialog.shadowRoot!.querySelector<HTMLInputElement>(
|
||||
'#apnInput');
|
||||
assertTrue(!!apnInputField);
|
||||
apnInputField.value = newExpectedApn;
|
||||
button = apnDetailDialog.shadowRoot!.querySelector<HTMLButtonElement>(
|
||||
'#apnDetailActionBtn');
|
||||
assertTrue(!!button);
|
||||
button.click();
|
||||
await mojoApi.whenCalled('modifyCustomApn');
|
||||
|
||||
const apn =
|
||||
managedProperties.result.typeProperties.cellular!.customApnList![0];
|
||||
assertTrue(!!apn);
|
||||
assertEquals(newExpectedApn, apn.accessPointName);
|
||||
assertEquals(apnWithId.id, apn.id);
|
||||
assertEquals(apnWithId.username, apn.username);
|
||||
assertEquals(apnWithId.password, apn.password);
|
||||
assertEquals(apnWithId.authentication, apn.authentication);
|
||||
assertEquals(apnWithId.ipType, apn.ipType);
|
||||
assertEquals(apnWithId.apnTypes.length, apn.apnTypes.length);
|
||||
assertEquals(apnWithId.apnTypes[0], apn.apnTypes[0]);
|
||||
assertEquals(
|
||||
apnDetailDialog.shadowRoot!.querySelector('#apnInput'),
|
||||
apnDetailDialog.shadowRoot!.activeElement);
|
||||
});
|
||||
});
|
@ -1,461 +0,0 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'chrome://os-settings/strings.m.js';
|
||||
import 'chrome://resources/ash/common/network/apn_detail_dialog.js';
|
||||
|
||||
import {ApnDetailDialog} from 'chrome://resources/ash/common/network/apn_detail_dialog.js';
|
||||
import {ApnDetailDialogMode} from 'chrome://resources/ash/common/network/cellular_utils.js';
|
||||
import {MojoInterfaceProviderImpl} from 'chrome://resources/ash/common/network/mojo_interface_provider.js';
|
||||
import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js';
|
||||
import {ApnAuthenticationType, ApnIpType, ApnProperties, ApnState, ApnType, ManagedProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js';
|
||||
import {NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js';
|
||||
import {FakeNetworkConfig} from 'chrome://test/chromeos/fake_network_config_mojom.js';
|
||||
import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
|
||||
import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
|
||||
import {eventToPromise} from 'chrome://webui-test/test_util.js';
|
||||
|
||||
/** @type {!ApnProperties} */
|
||||
const TEST_APN = {
|
||||
accessPointName: 'apn',
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
authentication: ApnAuthenticationType.kAutomatic,
|
||||
ipType: ApnIpType.kAutomatic,
|
||||
apnTypes: [ApnType.kDefault],
|
||||
state: ApnState.kEnabled,
|
||||
};
|
||||
|
||||
suite('ApnDetailDialog', function() {
|
||||
/** @type {ApnDetailDialog} */
|
||||
let apnDetailDialog = null;
|
||||
|
||||
let mojoApi_ = null;
|
||||
|
||||
async function toggleAdvancedSettings() {
|
||||
const advancedSettingsBtn =
|
||||
apnDetailDialog.shadowRoot.querySelector('#advancedSettingsBtn');
|
||||
assertTrue(!!advancedSettingsBtn);
|
||||
advancedSettingsBtn.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
*/
|
||||
function assertElementEnabled(selector) {
|
||||
const element = apnDetailDialog.shadowRoot.querySelector(selector);
|
||||
assertTrue(!!element);
|
||||
assertFalse(element.disabled);
|
||||
}
|
||||
|
||||
function assertAllInputsEnabled() {
|
||||
assertElementEnabled('#apnInput');
|
||||
assertElementEnabled('#usernameInput');
|
||||
assertElementEnabled('#passwordInput');
|
||||
assertElementEnabled('#authTypeDropDown');
|
||||
assertElementEnabled('#apnDefaultTypeCheckbox');
|
||||
assertElementEnabled('#apnAttachTypeCheckbox');
|
||||
assertElementEnabled('#ipTypeDropDown');
|
||||
}
|
||||
|
||||
setup(async function() {
|
||||
testing.Test.disableAnimationsAndTransitions();
|
||||
PolymerTest.clearBody();
|
||||
mojoApi_ = new FakeNetworkConfig();
|
||||
MojoInterfaceProviderImpl.getInstance().remote_ = mojoApi_;
|
||||
apnDetailDialog = document.createElement('apn-detail-dialog');
|
||||
apnDetailDialog.guid = 'fake-guid';
|
||||
apnDetailDialog.apnList = [TEST_APN];
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
return flushTasks().then(() => {
|
||||
apnDetailDialog.remove();
|
||||
apnDetailDialog = null;
|
||||
});
|
||||
});
|
||||
|
||||
async function init() {
|
||||
document.body.appendChild(apnDetailDialog);
|
||||
return waitAfterNextRender(apnDetailDialog);
|
||||
}
|
||||
|
||||
test('Element contains dialog', async function() {
|
||||
await init();
|
||||
const dialog = apnDetailDialog.shadowRoot.querySelector('cr-dialog');
|
||||
assertTrue(!!dialog);
|
||||
assertTrue(dialog.open);
|
||||
// Confirm that the dialog has the add apn title.
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailAddApnDialogTitle'),
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailDialogTitle')
|
||||
.innerText);
|
||||
assertTrue(!!apnDetailDialog.shadowRoot.querySelector('#apnInput'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot.querySelector('#usernameInput'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot.querySelector('#passwordInput'));
|
||||
|
||||
assertTrue(!!apnDetailDialog.shadowRoot.querySelector('#authTypeDropDown'));
|
||||
const defaultTypeCheckbox =
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDefaultTypeCheckbox');
|
||||
assertTrue(!!defaultTypeCheckbox);
|
||||
assertTrue(defaultTypeCheckbox.checked);
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot.querySelector('#apnAttachTypeCheckbox'));
|
||||
assertTrue(!!apnDetailDialog.shadowRoot.querySelector('#ipTypeDropDown'));
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot.querySelector('#apnDetailCancelBtn'));
|
||||
assertTrue(
|
||||
!!apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn'));
|
||||
assertFalse(!!apnDetailDialog.shadowRoot.querySelector('#apnDoneBtn'));
|
||||
assertEquals(
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnInput'),
|
||||
apnDetailDialog.shadowRoot.activeElement);
|
||||
});
|
||||
|
||||
test('Clicking the cancel button fires the close event', async function() {
|
||||
await init();
|
||||
const closeEventPromise = eventToPromise('close', window);
|
||||
const cancelBtn =
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailCancelBtn');
|
||||
assertTrue(!!cancelBtn);
|
||||
|
||||
cancelBtn.click();
|
||||
await closeEventPromise;
|
||||
assertFalse(!!apnDetailDialog.$.apnDetailDialog.open);
|
||||
});
|
||||
|
||||
test(
|
||||
'Clicking on the advanced settings button expands/collapses section',
|
||||
async function() {
|
||||
await init();
|
||||
const isAdvancedSettingShowing = () =>
|
||||
apnDetailDialog.shadowRoot.querySelector('iron-collapse').opened;
|
||||
assertFalse(!!isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
assertTrue(!!isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
assertFalse(!!isAdvancedSettingShowing());
|
||||
toggleAdvancedSettings();
|
||||
const assertOptions = (expectedTextArray, optionNodes) => {
|
||||
for (const [idx, expectedText] of expectedTextArray.entries()) {
|
||||
assertTrue(!!optionNodes[idx]);
|
||||
assertTrue(!!optionNodes[idx].text);
|
||||
assertEquals(expectedText, optionNodes[idx].text);
|
||||
}
|
||||
};
|
||||
const authTypeDropDown =
|
||||
apnDetailDialog.shadowRoot.querySelector('#authTypeDropDown');
|
||||
assertTrue(!!authTypeDropDown);
|
||||
const authTypeOptionNodes = authTypeDropDown.querySelectorAll('option');
|
||||
assertEquals(3, authTypeOptionNodes.length);
|
||||
// Note: We are also checking that the items appear in a certain order.
|
||||
assertOptions(
|
||||
[
|
||||
apnDetailDialog.i18n('apnDetailTypeAuto'),
|
||||
apnDetailDialog.i18n('apnDetailAuthTypePAP'),
|
||||
apnDetailDialog.i18n('apnDetailAuthTypeCHAP'),
|
||||
],
|
||||
authTypeOptionNodes);
|
||||
|
||||
const ipTypeDropDown =
|
||||
apnDetailDialog.shadowRoot.querySelector('#ipTypeDropDown');
|
||||
assertTrue(!!ipTypeDropDown);
|
||||
const ipTypeOptionNodes = ipTypeDropDown.querySelectorAll('option');
|
||||
assertEquals(4, ipTypeOptionNodes.length);
|
||||
|
||||
assertOptions(
|
||||
[
|
||||
apnDetailDialog.i18n('apnDetailTypeAuto'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv4'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv6'),
|
||||
apnDetailDialog.i18n('apnDetailIpTypeIpv4_Ipv6'),
|
||||
],
|
||||
ipTypeOptionNodes);
|
||||
});
|
||||
|
||||
test('Clicking on the add button calls createCustomApn', async () => {
|
||||
await init();
|
||||
apnDetailDialog.$.apnInput.value = TEST_APN.accessPointName;
|
||||
apnDetailDialog.$.usernameInput.value = TEST_APN.username;
|
||||
apnDetailDialog.$.passwordInput.value = TEST_APN.password;
|
||||
|
||||
assertAllInputsEnabled();
|
||||
assertElementEnabled('#apnDetailCancelBtn');
|
||||
assertElementEnabled('#apnDetailActionBtn');
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('add'),
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn')
|
||||
.innerText);
|
||||
|
||||
// Add a network.
|
||||
const network = OncMojo.getDefaultManagedProperties(
|
||||
NetworkType.kCellular, apnDetailDialog.guid);
|
||||
mojoApi_.setManagedPropertiesForTest(network);
|
||||
await flushTasks();
|
||||
|
||||
/**
|
||||
* @type {!ManagedProperties}
|
||||
*/
|
||||
const properties =
|
||||
await mojoApi_.getManagedProperties(apnDetailDialog.guid);
|
||||
assertTrue(!!properties);
|
||||
assertFalse(!!properties.result.typeProperties.cellular.customApnList);
|
||||
|
||||
const actionBtn =
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn');
|
||||
assertTrue(!!actionBtn);
|
||||
actionBtn.click();
|
||||
await flushTasks();
|
||||
await mojoApi_.whenCalled('createCustomApn');
|
||||
|
||||
assertEquals(
|
||||
1, properties.result.typeProperties.cellular.customApnList.length);
|
||||
|
||||
const apn = properties.result.typeProperties.cellular.customApnList[0];
|
||||
assertEquals(TEST_APN.accessPointName, apn.accessPointName);
|
||||
assertEquals(TEST_APN.username, apn.username);
|
||||
assertEquals(TEST_APN.password, apn.password);
|
||||
assertEquals(TEST_APN.authentication, apn.authentication);
|
||||
assertEquals(TEST_APN.ipType, apn.ipType);
|
||||
assertEquals(TEST_APN.apnTypes.length, apn.apnTypes.length);
|
||||
assertEquals(TEST_APN.apnTypes[0], apn.apnTypes[0]);
|
||||
});
|
||||
|
||||
test('Setting mode to view changes buttons and fields', async () => {
|
||||
const assertFieldDisabled = (selector) => {
|
||||
const element = apnDetailDialog.shadowRoot.querySelector(selector);
|
||||
assertTrue(!!element);
|
||||
assertTrue(element.disabled);
|
||||
};
|
||||
|
||||
// Set the dialog mode before opening the dialog so that the default focus
|
||||
// can be tested.
|
||||
apnDetailDialog.mode = ApnDetailDialogMode.VIEW;
|
||||
apnDetailDialog.apnProperties = TEST_APN;
|
||||
|
||||
await init();
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailViewApnDialogTitle'),
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailDialogTitle')
|
||||
.innerText);
|
||||
assertFalse(
|
||||
!!apnDetailDialog.shadowRoot.querySelector('#apnDetailCancelBtn'));
|
||||
assertFalse(
|
||||
!!apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn'));
|
||||
const doneBtn = apnDetailDialog.shadowRoot.querySelector('#apnDoneBtn');
|
||||
assertTrue(!!doneBtn);
|
||||
assertFalse(doneBtn.disabled);
|
||||
assertFieldDisabled('#apnInput');
|
||||
assertFieldDisabled('#usernameInput');
|
||||
assertFieldDisabled('#passwordInput');
|
||||
assertFieldDisabled('#authTypeDropDown');
|
||||
assertFieldDisabled('#apnDefaultTypeCheckbox');
|
||||
assertFieldDisabled('#apnAttachTypeCheckbox');
|
||||
assertFieldDisabled('#ipTypeDropDown');
|
||||
assertEquals(doneBtn, apnDetailDialog.shadowRoot.activeElement);
|
||||
});
|
||||
|
||||
test('Dialog input fields are validated', async () => {
|
||||
await init();
|
||||
const apnInputField = apnDetailDialog.$.apnInput;
|
||||
const actionButton =
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn');
|
||||
assertTrue(!!actionButton);
|
||||
// Case: After opening dialog before user input
|
||||
assertFalse(!!apnInputField.invalid);
|
||||
assertTrue(!!actionButton.disabled);
|
||||
|
||||
// Case : After valid user input
|
||||
apnInputField.value = 'test';
|
||||
assertFalse(!!apnInputField.invalid);
|
||||
assertFalse(!!actionButton.disabled);
|
||||
|
||||
// Case : After Removing all user input no error state but button disabled
|
||||
apnInputField.value = '';
|
||||
assertFalse(!!apnInputField.invalid);
|
||||
assertTrue(!!actionButton.disabled);
|
||||
|
||||
// Case : Non ascii user input
|
||||
apnInputField.value = 'testμ';
|
||||
assertTrue(!!apnInputField.invalid);
|
||||
assertTrue(!!actionButton.disabled);
|
||||
assertTrue(apnInputField.value.includes('μ'));
|
||||
|
||||
// Case : longer than 63 characters then removing one character
|
||||
apnInputField.value = 'a'.repeat(64);
|
||||
assertTrue(!!apnInputField.invalid);
|
||||
assertTrue(!!actionButton.disabled);
|
||||
assertFalse(apnInputField.value.length > 63);
|
||||
apnInputField.value = apnInputField.value.slice(0, -1);
|
||||
assertFalse(!!apnInputField.invalid);
|
||||
assertFalse(!!actionButton.disabled);
|
||||
|
||||
// Case : longer than 63 non-ASCII characters
|
||||
apnInputField.value = 'μ'.repeat(64);
|
||||
assertTrue(!!apnInputField.invalid);
|
||||
assertTrue(!!actionButton.disabled);
|
||||
});
|
||||
|
||||
test('Apn types are correctly validated in all modes', async () => {
|
||||
await init();
|
||||
const updateApnTypeCheckboxes = (defaultType, attachType) => {
|
||||
apnDetailDialog.$.apnDefaultTypeCheckbox.checked = defaultType;
|
||||
apnDetailDialog.$.apnAttachTypeCheckbox.checked = attachType;
|
||||
};
|
||||
await toggleAdvancedSettings();
|
||||
const getDefaultApnInfo = () => {
|
||||
return apnDetailDialog.shadowRoot.querySelector(
|
||||
'#defaultApnRequiredInfo');
|
||||
};
|
||||
|
||||
TEST_APN.id = '1';
|
||||
const currentApn = /** @type {ApnProperties} */ ({});
|
||||
Object.assign(currentApn, TEST_APN);
|
||||
currentApn.id = '2';
|
||||
apnDetailDialog.apnList = [TEST_APN, currentApn];
|
||||
apnDetailDialog.apnProperties = currentApn;
|
||||
|
||||
const actionButton =
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn');
|
||||
apnDetailDialog.$.apnInput.value = 'valid_name';
|
||||
|
||||
// CREATE mode tests
|
||||
apnDetailDialog.mode = ApnDetailDialogMode.CREATE;
|
||||
TEST_APN.state = ApnState.kDisabled;
|
||||
apnDetailDialog.apnList = [TEST_APN];
|
||||
|
||||
// Case: Default APN type is checked
|
||||
updateApnTypeCheckboxes(/* default= */ true, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Case: No enabled default APNs, default unchecked and attach is checked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: No enabled default APNs and both unchecked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Case: Enabled default APNs, default unchecked and attach is checked.
|
||||
TEST_APN.state = ApnState.kEnabled;
|
||||
apnDetailDialog.apnList = [TEST_APN];
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Case: Enabled default APNs and both unchecked.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Edit mode tests
|
||||
apnDetailDialog.mode = ApnDetailDialogMode.EDIT;
|
||||
TEST_APN.apnTypes = [ApnType.kAttach];
|
||||
currentApn.apnTypes = [ApnType.kDefault, ApnType.kAttach];
|
||||
apnDetailDialog.apnList = [TEST_APN, currentApn];
|
||||
|
||||
// Case: Default APN type is checked
|
||||
updateApnTypeCheckboxes(/* default= */ true, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertFalse(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks the default checkbox, APN being modified is the
|
||||
// only default APN
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks both checkboxes, APN being modified is the
|
||||
// only enabled default APN but there are other enabled attach APNs.
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks both checkboxes, APN being modified is the
|
||||
// only enabled default APN and is the only enabled attachApn.
|
||||
currentApn.apnTypes = [ApnType.kDefault, ApnType.kAttach];
|
||||
apnDetailDialog.apnList = [currentApn];
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ false);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertFalse(!!getDefaultApnInfo());
|
||||
|
||||
// Case: User unchecks default APN type checkbox and checks the attach
|
||||
// APN type checkbox, APN being modified is the only enabled default APN
|
||||
// and there are no other enabled attach type APNs.
|
||||
currentApn.apnTypes = [ApnType.kDefault];
|
||||
apnDetailDialog.apnList = [currentApn];
|
||||
updateApnTypeCheckboxes(/* default= */ false, /* attach= */ true);
|
||||
await flushTasks();
|
||||
assertTrue(actionButton.disabled);
|
||||
assertTrue(!!getDefaultApnInfo());
|
||||
});
|
||||
|
||||
test('Setting mode to edit changes buttons and fields', async () => {
|
||||
const apnWithId = TEST_APN;
|
||||
apnWithId.id = '1';
|
||||
apnWithId.apnTypes = [ApnType.kDefault];
|
||||
|
||||
// Set the dialog mode before opening the dialog so that the default focus
|
||||
// can be tested.
|
||||
apnDetailDialog.mode = ApnDetailDialogMode.EDIT;
|
||||
apnDetailDialog.apnProperties = apnWithId;
|
||||
|
||||
await init();
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('apnDetailEditApnDialogTitle'),
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailDialogTitle')
|
||||
.innerText);
|
||||
assertElementEnabled('#apnDetailCancelBtn');
|
||||
assertElementEnabled('#apnDetailActionBtn');
|
||||
assertEquals(
|
||||
apnDetailDialog.i18n('save'),
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn')
|
||||
.innerText);
|
||||
assertFalse(!!apnDetailDialog.shadowRoot.querySelector('#apnDoneBtn'));
|
||||
assertAllInputsEnabled();
|
||||
|
||||
// Case: clicking on the action button calls the correct method
|
||||
const network = OncMojo.getDefaultManagedProperties(
|
||||
NetworkType.kCellular, apnDetailDialog.guid);
|
||||
mojoApi_.setManagedPropertiesForTest(network);
|
||||
await flushTasks();
|
||||
const managedProperties =
|
||||
await mojoApi_.getManagedProperties(apnDetailDialog.guid);
|
||||
assertTrue(!!managedProperties);
|
||||
managedProperties.result.typeProperties.cellular = {
|
||||
customApnList: [apnWithId],
|
||||
};
|
||||
const newExpectedApn = 'modified';
|
||||
apnDetailDialog.$.apnInput.value = newExpectedApn;
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnDetailActionBtn').click();
|
||||
await mojoApi_.whenCalled('modifyCustomApn');
|
||||
|
||||
const apn =
|
||||
managedProperties.result.typeProperties.cellular.customApnList[0];
|
||||
assertEquals(newExpectedApn, apn.accessPointName);
|
||||
assertEquals(apnWithId.id, apn.id);
|
||||
assertEquals(apnWithId.username, apn.username);
|
||||
assertEquals(apnWithId.password, apn.password);
|
||||
assertEquals(apnWithId.authentication, apn.authentication);
|
||||
assertEquals(apnWithId.ipType, apn.ipType);
|
||||
assertEquals(apnWithId.apnTypes.length, apn.apnTypes.length);
|
||||
assertEquals(apnWithId.apnTypes[0], apn.apnTypes[0]);
|
||||
assertEquals(
|
||||
apnDetailDialog.shadowRoot.querySelector('#apnInput'),
|
||||
apnDetailDialog.shadowRoot.activeElement);
|
||||
});
|
||||
|
||||
});
|
@ -205,7 +205,7 @@ TEST_F('OSSettingsCrostiniExtraContainerPageTest', 'AllJsTests', () => {
|
||||
});
|
||||
|
||||
[['AboutPage', 'os_about_page_tests.js'],
|
||||
['ApnDetailDialog', 'apn_detail_dialog_tests.js'],
|
||||
['ApnDetailDialog', 'apn_detail_dialog_test.js'],
|
||||
// TODO(crbug.com/1455866): Enable the ApnSubpage test.
|
||||
// [
|
||||
// 'ApnSubpage', 'apn_subpage_tests.js',
|
||||
|
Reference in New Issue
Block a user