text:
<!doctype html>

	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>IUInt32 | hifi</title>
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="../assets/css/main.css">

						Search
						<input id="tsd-search-field" type="text" />

Preparing search index...

The search index is not available

					hifi

						Options

							<input type="checkbox" id="tsd-filter-inherited" checked />
							Inherited
							<input type="checkbox" id="tsd-filter-private" checked />
							Private
							<input type="checkbox" id="tsd-filter-externals" checked />
							Externals
							<input type="checkbox" id="tsd-filter-only-exported" />
							Only exported

					Menu

					Globals

					hifi

					IUInt32

Interface IUInt32

deprecated, just use number and document number type in jsdoc

Hierarchy

						Number

								IUInt32

Index

Methods

to<wbr>Exponential

to<wbr>Fixed

to<wbr>Locale<wbr>String

to<wbr>Precision

to<wbr>String

Methods

to<wbr>Exponential

to<wbr>Exponential(fractionDigits?: number): string

Inherited from         Number.toExponential

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:461

Returns a string containing a number represented in exponential notation.

Parameters

fractionDigits?:         number optional

Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.

Returns         string

to<wbr>Fixed

to<wbr>Fixed(fractionDigits?: number): string

Inherited from         Number.toFixed

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:455

Returns a string representing a number in fixed-point notation.

Parameters

fractionDigits?:         number optional

Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.

Returns         string

to<wbr>Locale<wbr>String

to<wbr>Locale<wbr>String(locales?: Array<string>, options?: Intl.NumberFormatOptions): string

to<wbr>Locale<wbr>String(locale?: string, options?: Intl.NumberFormatOptions): string

Inherited from         Number.toLocaleString

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:1918

Parameters

locales?:         Array<string> optional

options?:         Intl.NumberFormatOptions optional

Returns         string

Inherited from         Number.toLocaleString

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:1919

Parameters

locale?:         string optional

options?:         Intl.NumberFormatOptions optional

Returns         string

to<wbr>Precision

to<wbr>Precision(precision?: number): string

Inherited from         Number.toPrecision

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:467

Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.

Parameters

precision?:         number optional

Number of significant digits. Must be in the range 1 - 21, inclusive.

Returns         string

to<wbr>String

to<wbr>String(radix?: number): string

Inherited from         Number.toString

Defined in node_modules/grunt-typedoc/node_modules/typedoc/node_modules/typescript/bin/lib.d.ts:449

Returns a string representation of an object.

Parameters

radix?:         number optional

Specifies a radix for converting numeric values to strings. This value is only used for numbers.

Returns         string

						Globals

						hifi

						IUInt32

								to<wbr>Exponential

								to<wbr>Fixed

								to<wbr>Locale<wbr>String

								to<wbr>Precision

								to<wbr>String

Legend

Container, dynamic module

Enumeration

Enumeration member

Object literal

Constructor

Variable

Function, call signature, accessor

Index signature

Interface

Constructor

Property

Member, accessor

Index signature

Class

Constructor

Property

Member, accessor

Index signature

Inherited constructor

Inherited property

Inherited member

Private constructor

Private property

Private member

Static property

Static member

Generated using TypeDoc


text:
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/** @fileoverview Runs the Polymer Password Settings tests. */

// clang-format off
import 'chrome://settings/lazy_load.js';

import {isMac, isWindows, isChromeOS, isLacros, webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {PasswordsSectionElement} from 'chrome://settings/lazy_load.js';
import {buildRouter, HatsBrowserProxyImpl, PasswordCheckReferrer, PasswordManagerImpl, Router, routes, SettingsPluralStringProxyImpl,StatusAction, TrustedVaultBannerState, TrustSafetyInteraction} from 'chrome://settings/settings.js';
import {SettingsRoutes} from 'chrome://settings/settings_routes.js';
import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {TestPluralStringProxy} from 'chrome://webui-test/test_plural_string_proxy.js';
import {eventToPromise, flushTasks, isVisible} from 'chrome://webui-test/test_util.js';

import {createExceptionEntry, createPasswordEntry, makeCompromisedCredential, makePasswordCheckStatus, PasswordSectionElementFactory} from './passwords_and_autofill_fake_data.js';
import {getSyncAllPrefs, simulateStoredAccounts, simulateSyncStatus} from './sync_test_util.js';
import {TestHatsBrowserProxy} from './test_hats_browser_proxy.js';
import {TestPasswordManagerProxy} from './test_password_manager_proxy.js';

// clang-format on

const PasswordCheckState = chrome.passwordsPrivate.PasswordCheckState;

/**
 * Helper method that validates a that elements in the password list match
 * the expected data.
 * @param passwordsSection The passwords section element that will be checked.
 * @param expectedPasswords The expected data.
 */
function validatePasswordList(
    passwordsSection: PasswordsSectionElement,
    expectedPasswords: chrome.passwordsPrivate.PasswordUiEntry[]) {
  const passwordList = passwordsSection.$.passwordList;
  if (passwordList.filter) {
    // `passwordList.items` will always contain all items, even when there is a
    // filter to be applied. Thus apply `passwordList.filter` to obtain the list
    // of items that are user visible.
    assertDeepEquals(
        expectedPasswords,
        passwordList.items!.filter(
            passwordList.filter as
                (item: chrome.passwordsPrivate.PasswordUiEntry) => boolean));
  } else {
    assertDeepEquals(expectedPasswords, passwordList.items);
  }

  const listItems =
      passwordsSection.shadowRoot!.querySelectorAll('password-list-item');
  for (let index = 0; index < expectedPasswords.length; ++index) {
    const expected = expectedPasswords[index]!;
    const listItem = listItems[index]!;
    assertTrue(!!listItem);
    assertEquals(expected.urls.shown, listItem.$.originUrl.textContent!.trim());
    assertEquals(expected.urls.link, listItem.$.originUrl.href);
    assertEquals(expected.username, listItem.$.username.textContent!.trim());
  }
}

/**
 * Helper method that validates a that elements in the exception list match
 * the expected data.
 * @param nodes The nodes that will be checked.
 * @param exceptionList The expected data.
 */
function validateExceptionList(
    nodes: NodeListOf<HTMLElement>,
    exceptionList: chrome.passwordsPrivate.ExceptionEntry[]) {
  assertEquals(exceptionList.length, nodes.length);
  for (let index = 0; index < exceptionList.length; ++index) {
    const node = nodes[index]!;
    const exception = exceptionList[index]!;
    assertEquals(
        exception.urls.shown,
        node.querySelector<HTMLElement>('#exception')!.textContent!.trim());
    assertEquals(
        exception.urls.link.toLowerCase(),
        node.querySelector<HTMLAnchorElement>('#exception')!.href);
  }
}

/**
 * Returns all children of an element that has children added by a dom-repeat.
 */
function getDomRepeatChildren(element: HTMLElement): NodeListOf<HTMLElement> {
  const nodes = element.querySelectorAll<HTMLElement>('.list-item:not([id])');
  return nodes;
}

/**
 * Extracts the first password-list-item in the a password-section element.
 */
function getFirstPasswordListItem(passwordsSection: HTMLElement) {
  return passwordsSection.shadowRoot!.querySelector('password-list-item')!;
}

/**
 * Helper method used to test for a url in a list of passwords.
 * @param url The URL that is being searched for.
 */
function listContainsUrl(
    passwordList: (chrome.passwordsPrivate.PasswordUiEntry[]),
    url: string): boolean {
  return passwordList.some(item => item.urls.signonRealm === url);
}

/**
 * Helper method used to test for a url in a list of passwords.
 * @param url The URL that is being searched for.
 */
function exceptionsListContainsUrl(
    exceptionList: chrome.passwordsPrivate.ExceptionEntry[],
    url: string): boolean {
  return exceptionList.some(
      item => (item.urls as unknown as {originUrl: string}).originUrl === url);
}

/**
 * Helper function to check password visibility when open password-edit-dialog.
 */
async function openPasswordEditDialogHelper(
    passwordManager: TestPasswordManagerProxy,
    elementFactory: PasswordSectionElementFactory) {
  const PASSWORD = 'p4ssw0rd';
  const passwordList = [
    createPasswordEntry({username: 'user0', id: 0}),
  ];
  passwordManager.setPlaintextPassword(PASSWORD);

  const passwordsSection =
      elementFactory.createPasswordsSection(passwordManager, passwordList, []);

  const passwordListItem = getFirstPasswordListItem(passwordsSection);
  passwordListItem.shadowRoot!
      .querySelector<HTMLElement>('#showPasswordButton')!.click();
  flush();
  await passwordManager.whenCalled('requestPlaintextPassword');
  await flushTasks();
  passwordManager.resetResolver('requestPlaintextPassword');

  assertEquals(
      'text',
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.type);
  assertFalse(
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.disabled);
  assertTrue(passwordListItem.shadowRoot!
                 .querySelector<HTMLElement>('#showPasswordButton')!.classList
                 .contains('icon-visibility-off'));

  // Open Edit Dialog.
  passwordListItem.$.moreActionsButton.click();
  passwordsSection.$.passwordsListHandler.$.menuEditPassword.click();
  flush();
  await passwordManager.whenCalled('requestPlaintextPassword');
  await flushTasks();
  passwordManager.resetResolver('requestPlaintextPassword');

  assertEquals(
      'password',
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.type);
  assertTrue(
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.disabled);
  assertTrue(
      passwordListItem.shadowRoot!
          .querySelector<HTMLElement>(
              '#showPasswordButton')!.classList.contains('icon-visibility'));

  // Verify that edit dialog password is hidden.
  const passwordEditDialog =
      passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector(
          'password-edit-dialog')!;
  const showPasswordButton =
      passwordEditDialog.shadowRoot!.querySelector<HTMLElement>(
          '#showPasswordButton')!;
  assertEquals('password', passwordEditDialog.$.passwordInput.type);
  assertTrue(showPasswordButton.classList.contains('icon-visibility'));

  showPasswordButton.click();
  flush();

  assertEquals('text', passwordEditDialog.$.passwordInput.type);
  assertTrue(showPasswordButton.classList.contains('icon-visibility-off'));

  // Close the dialog, verify that the list item password remains hidden.
  // Note that the password only gets hidden in the on-close handler, thus we
  // need to await this event first.
  passwordManager.setChangeSavedPasswordResponse(1);
  passwordEditDialog.$.actionButton.click();
  await eventToPromise('close', passwordEditDialog);

  assertEquals('', passwordListItem.entry.password);
  assertEquals(
      'password',
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.type);
  assertTrue(
      passwordListItem.shadowRoot!.querySelector<HTMLInputElement>(
                                      '#password')!.disabled);
  assertTrue(
      passwordListItem.shadowRoot!
          .querySelector<HTMLElement>(
              '#showPasswordButton')!.classList.contains('icon-visibility'));
}

/**
 * Simulates user who is eligible and opted-in for account storage. Should be
 * called after the PasswordsSection element is created.
 */
function simulateAccountStorageUser(passwordManager: TestPasswordManagerProxy) {
  simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION});
  simulateStoredAccounts([{email: 'john@gmail.com'}]);
  passwordManager.setIsOptedInForAccountStorageAndNotify(true);

  flush();
}

// TODO(crbug.com/1260310): Split into multiple test suits.
suite('PasswordsSection', function() {
  let passwordManager: TestPasswordManagerProxy;

  let elementFactory: PasswordSectionElementFactory;

  let pluralString: TestPluralStringProxy;

  let testHatsBrowserProxy: TestHatsBrowserProxy;

  setup(function() {
    document.body.innerHTML = '';
    // Override the PasswordManagerImpl for testing.
    passwordManager = new TestPasswordManagerProxy();
    pluralString = new TestPluralStringProxy();
    SettingsPluralStringProxyImpl.setInstance(pluralString);
    testHatsBrowserProxy = new TestHatsBrowserProxy();
    HatsBrowserProxyImpl.setInstance(testHatsBrowserProxy);

    PasswordManagerImpl.setInstance(passwordManager);
    elementFactory = new PasswordSectionElementFactory(document);
    loadTimeData.overrideValues({
      enableAutomaticPasswordChangeInSettings: false,
      enablePasswordViewPage: false,
      biometricAuthenticationForFilling: false,
    });
  });

  test('testPasswordsExtensionIndicator', function() {
    // Initialize with dummy prefs.
    const element = document.createElement('passwords-section');
    element.prefs = {
      credentials_enable_service: {},
    };
    document.body.appendChild(element);

    assertFalse(
        !!element.shadowRoot!.querySelector('#passwordsExtensionIndicator'));
    element.set('prefs.credentials_enable_service.extensionId', 'test-id');
    flush();

    assertTrue(
        !!element.shadowRoot!.querySelector('#passwordsExtensionIndicator'));
  });

  if (isMac || isWindows) {
    test('testBiometricAuthenticationForFillingToggleVisibility', function() {
      loadTimeData.overrideValues({biometricAuthenticationForFilling: false});
      const passwordsSectionBiometricForFillingDisabled =
          elementFactory.createPasswordsSection(passwordManager, [], []);
      assertFalse(
          isVisible(passwordsSectionBiometricForFillingDisabled.shadowRoot!
                        .querySelector<HTMLElement>(
                            '#biometricAuthenticationForFillingToggle')));

      loadTimeData.overrideValues({biometricAuthenticationForFilling: true});
      const passwordsSectionBiometricForFillingEnabled =
          elementFactory.createPasswordsSection(passwordManager, [], []);
      assertTrue(
          isVisible(passwordsSectionBiometricForFillingEnabled.shadowRoot!
                        .querySelector<HTMLElement>(
                            '#biometricAuthenticationForFillingToggle')));
    });
  }

  test('verifyNoSavedPasswords', function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);

    validatePasswordList(passwordsSection, []);

    assertFalse(passwordsSection.$.noPasswordsLabel.hidden);
    assertTrue(passwordsSection.$.savedPasswordsHeaders.hidden);
  });

  test('verifySavedPasswordEntries', function() {
    const passwordList = [
      createPasswordEntry({url: 'site1.com', username: 'luigi', id: 0}),
      createPasswordEntry({url: 'longwebsite.com', username: 'peach', id: 1}),
      createPasswordEntry({url: 'site2.com', username: 'mario', id: 2}),
      createPasswordEntry({url: 'site1.com', username: 'peach', id: 3}),
      createPasswordEntry({url: 'google.com', username: 'mario', id: 4}),
      createPasswordEntry({url: 'site2.com', username: 'luigi', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    // Assert that the data is passed into the iron list. If this fails,
    // then other expectations will also fail.
    assertDeepEquals(passwordList, passwordsSection.$.passwordList.items);

    validatePasswordList(passwordsSection, passwordList);

    assertTrue(passwordsSection.$.noPasswordsLabel.hidden);
    assertFalse(passwordsSection.$.savedPasswordsHeaders.hidden);
  });

  // Test verifies that removing a password will update the elements.
  test('verifyPasswordListRemove', function() {
    const passwordList = [
      createPasswordEntry(
          {url: 'anotherwebsite.com', username: 'luigi', id: 0}),
      createPasswordEntry({url: 'longwebsite.com', username: 'peach', id: 1}),
      createPasswordEntry({url: 'website.com', username: 'mario', id: 2}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    validatePasswordList(passwordsSection, passwordList);
    // Simulate 'longwebsite.com' being removed from the list.
    passwordList.splice(1, 1);
    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();

    assertFalse(
        listContainsUrl(passwordsSection.savedPasswords, 'longwebsite.com'));
    assertFalse(listContainsUrl(passwordList, 'longwebsite.com'));

    validatePasswordList(passwordsSection, passwordList);
  });

  // Regression test for crbug.com/1110290.
  // Test verifies that if the password list is updated, all the plaintext
  // passwords are hidden.
  test('updatingPasswordListHidesPlaintextPasswords', async function() {
    const PASSWORD = 'pwd';
    const passwordList = [
      createPasswordEntry({url: 'goo.gl', username: 'user0', id: 0}),
      createPasswordEntry({url: 'goo.gl', username: 'user1', id: 1}),
    ];
    passwordManager.setPlaintextPassword(PASSWORD);

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    const passwordListItems =
        passwordsSection.shadowRoot!.querySelectorAll('password-list-item');
    assertEquals(2, passwordListItems.length);

    passwordListItems[0]!.shadowRoot!
        .querySelector<HTMLElement>('#showPasswordButton')!.click();
    flush();
    await passwordManager.whenCalled('requestPlaintextPassword');
    await flushTasks();
    passwordManager.resetResolver('requestPlaintextPassword');

    passwordListItems[1]!.shadowRoot!
        .querySelector<HTMLElement>('#showPasswordButton')!.click();
    await passwordManager.whenCalled('requestPlaintextPassword');
    await flushTasks();

    assertEquals(
        'text',
        passwordListItems[0]!.shadowRoot!
            .querySelector<HTMLInputElement>('#password')!.type);
    assertEquals(
        'text',
        passwordListItems[1]!.shadowRoot!
            .querySelector<HTMLInputElement>('#password')!.type);

    // Remove first row and verify that the remaining password is hidden.
    passwordList.splice(0, 1);
    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();
    assertEquals('', getFirstPasswordListItem(passwordsSection).entry.password);
    assertEquals(
        'password',
        getFirstPasswordListItem(passwordsSection)
            .shadowRoot!.querySelector<HTMLInputElement>('#password')!.type);
    assertEquals(
        'user1', getFirstPasswordListItem(passwordsSection).entry.username);
  });

  test('listItemEditDialogShowAndHideInterplay', async function() {
    await openPasswordEditDialogHelper(passwordManager, elementFactory);
  });

  // Test verifies that adding a password will update the elements.
  test('verifyPasswordListAdd', function() {
    const passwordList = [
      createPasswordEntry(
          {url: 'anotherwebsite.com', username: 'luigi', id: 0}),
      createPasswordEntry({url: 'longwebsite.com', username: 'peach', id: 1}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    validatePasswordList(passwordsSection, passwordList);
    // Simulate 'website.com' being added to the list.
    passwordList.unshift(
        createPasswordEntry({url: 'website.com', username: 'mario', id: 2}));
    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();

    validatePasswordList(passwordsSection, passwordList);
  });

  // Test verifies that removing one out of two passwords for the same website
  // will update the elements.
  test('verifyPasswordListRemoveSameWebsite', function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);

    // Set-up initial list.
    let passwordList = [
      createPasswordEntry({url: 'website.com', username: 'mario', id: 0}),
      createPasswordEntry({url: 'website.com', username: 'luigi', id: 1}),
    ];

    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();
    validatePasswordList(passwordsSection, passwordList);

    // Simulate '(website.com, mario)' being removed from the list.
    passwordList.shift();
    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();
    validatePasswordList(passwordsSection, passwordList);

    // Simulate '(website.com, luigi)' being removed from the list as well.
    passwordList = [];
    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();
    validatePasswordList(passwordsSection, passwordList);
  });

  // Test verifies that pressing the 'remove' button will trigger a remove
  // event. Does not actually remove any passwords.
  test('verifyPasswordItemRemoveButton', async function() {
    const passwordList = [
      createPasswordEntry({url: 'one', username: 'six', id: 0}),
      createPasswordEntry({url: 'two', username: 'five', id: 1}),
      createPasswordEntry({url: 'three', username: 'four', id: 2}),
      createPasswordEntry({url: 'four', username: 'three', id: 3}),
      createPasswordEntry({url: 'five', username: 'two', id: 4}),
      createPasswordEntry({url: 'six', username: 'one', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    const firstNode = getFirstPasswordListItem(passwordsSection);
    assertTrue(!!firstNode);
    const firstPassword = passwordList[0]!;

    // Click the remove button on the first password.
    firstNode.$.moreActionsButton.click();
    passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();

    const {id} = await passwordManager.whenCalled('removeSavedPassword');
    // Verify that the expected value was passed to the proxy.
    assertEquals(firstPassword.id, id);
    assertEquals(
        passwordsSection.i18n('passwordDeleted'),
        passwordsSection.$.passwordsListHandler.$.removalNotification
            .textContent);
  });

  // Test verifies that 'Copy password' button is hidden for Federated
  // (passwordless) credentials. Does not test Copy button.
  test('verifyCopyAbsentForFederatedPasswordInMenu', function() {
    const passwordList = [
      createPasswordEntry({federationText: 'with chromium.org'}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    flush();
    assertTrue(
        passwordsSection.$.passwordsListHandler.$.menuCopyPassword.hidden);
  });

  // Test verifies that 'Copy password' button is not hidden for common
  // credentials. Does not test Copy button.
  test('verifyCopyPresentInMenu', function() {
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'hey'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    flush();
    assertFalse(
        passwordsSection.$.passwordsListHandler.$.menuCopyPassword.hidden);
  });

  // Test verifies that 'Edit' button is replaced to 'Details' for Federated
  // (passwordless) credentials. Does not test Details and Edit button.
  test('verifyEditReplacedToDetailsForFederatedPasswordInMenu', function() {
    const passwordList = [
      createPasswordEntry({federationText: 'with chromium.org'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    flush();
    assertEquals(
        passwordsSection.i18n('passwordViewDetails'),
        passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent!
            .trim());
  });

  // Test verifies that 'Edit' button is replaced to 'Details' for Federated
  // (passwordless) credentials.
  // Does not test Details and Edit button.
  test('verifyDetailsForFederatedPasswordInMenu', function() {
    const passwordList = [
      createPasswordEntry({federationText: 'with chromium.org'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    flush();
    assertEquals(
        passwordsSection.i18n('passwordViewDetails'),
        passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent!
            .trim());
  });

  // Test verifies that 'Edit' button is shown instead of 'Details' for
  // common credentials.
  // Does not test Details and Edit button.
  test('verifyEditButtonInMenu', function() {
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'hey'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    flush();
    assertEquals(
        passwordsSection.i18n('editPassword'),
        passwordsSection.$.passwordsListHandler.$.menuEditPassword.textContent!
            .trim());
  });

  test('verifyFilterPasswords', function() {
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
      createPasswordEntry({url: 'three.com/show', username: 'four', id: 2}),
      createPasswordEntry({url: 'four.com', username: 'three', id: 3}),
      createPasswordEntry({url: 'five.com', username: 'two', id: 4}),
      createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);
    passwordsSection.filter = 'SHow';
    flush();

    const expectedList = [
      createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
      createPasswordEntry({url: 'three.com/show', username: 'four', id: 2}),
      createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
    ];

    validatePasswordList(passwordsSection, expectedList);
  });

  test('verifyFilterPasswordsWithRemoval', function() {
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
      createPasswordEntry({url: 'three.com/show', username: 'four', id: 2}),
      createPasswordEntry({url: 'four.com', username: 'three', id: 3}),
      createPasswordEntry({url: 'five.com', username: 'two', id: 4}),
      createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);
    passwordsSection.filter = 'SHow';
    flush();

    let expectedList = [
      createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
      createPasswordEntry({url: 'three.com/show', username: 'four', id: 2}),
      createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
    ];

    validatePasswordList(passwordsSection, expectedList);

    // Simulate removal of three.com/show
    passwordList.splice(2, 1);
    flush();

    expectedList = [
      createPasswordEntry({url: 'one.com', username: 'SHOW', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'shower', id: 1}),
      createPasswordEntry({url: 'six-show.com', username: 'one', id: 5}),
    ];

    passwordManager.lastCallback.addSavedPasswordListChangedListener!
        (passwordList);
    flush();
    validatePasswordList(passwordsSection, expectedList);
  });

  test('verifyFilterPasswordExceptions', function() {
    const exceptionList = [
      createExceptionEntry({url: 'docsshoW.google.com', id: 0}),
      createExceptionEntry({url: 'showmail.com', id: 1}),
      createExceptionEntry({url: 'google.com', id: 2}),
      createExceptionEntry({url: 'inbox.google.com', id: 3}),
      createExceptionEntry({url: 'mapsshow.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.comshow', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [], exceptionList);
    passwordsSection.filter = 'shOW';
    flush();

    const expectedExceptionList = [
      createExceptionEntry({url: 'docsshoW.google.com', id: 0}),
      createExceptionEntry({url: 'showmail.com', id: 1}),
      createExceptionEntry({url: 'mapsshow.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.comshow', id: 5}),
    ];

    validateExceptionList(
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
        expectedExceptionList);
  });

  test('verifyNoPasswordExceptions', function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);

    validateExceptionList(
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList), []);

    assertFalse(passwordsSection.$.noExceptionsLabel.hidden);
  });

  test('verifyPasswordExceptions', function() {
    const exceptionList = [
      createExceptionEntry({url: 'docs.google.com', id: 0}),
      createExceptionEntry({url: 'mail.com', id: 1}),
      createExceptionEntry({url: 'google.com', id: 2}),
      createExceptionEntry({url: 'inbox.google.com', id: 3}),
      createExceptionEntry({url: 'maps.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.com', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [], exceptionList);

    validateExceptionList(
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
        exceptionList);

    assertTrue(passwordsSection.$.noExceptionsLabel.hidden);
  });

  // Test verifies that removing an exception will update the elements.
  test('verifyPasswordExceptionRemove', function() {
    const exceptionList = [
      createExceptionEntry({url: 'docs.google.com', id: 0}),
      createExceptionEntry({url: 'mail.com', id: 1}),
      createExceptionEntry({url: 'google.com', id: 2}),
      createExceptionEntry({url: 'inbox.google.com', id: 3}),
      createExceptionEntry({url: 'maps.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.com', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [], exceptionList);

    validateExceptionList(
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
        exceptionList);

    // Simulate 'mail.com' being removed from the list.
    passwordsSection.splice('passwordExceptions', 1, 1);
    flush();
    assertFalse(exceptionsListContainsUrl(
        passwordsSection.passwordExceptions, 'mail.com'));
    assertFalse(exceptionsListContainsUrl(exceptionList, 'mail.com'));

    const expectedExceptionList = [
      createExceptionEntry({url: 'docs.google.com', id: 0}),
      createExceptionEntry({url: 'google.com', id: 2}),
      createExceptionEntry({url: 'inbox.google.com', id: 3}),
      createExceptionEntry({url: 'maps.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.com', id: 5}),
    ];
    validateExceptionList(
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList),
        expectedExceptionList);
  });

  // Test verifies that pressing the 'remove' button will trigger a remove
  // event. Does not actually remove any exceptions.
  test('verifyPasswordExceptionRemoveButton', function() {
    const exceptionList = [
      createExceptionEntry({url: 'docs.google.com', id: 0}),
      createExceptionEntry({url: 'mail.com', id: 1}),
      createExceptionEntry({url: 'google.com', id: 2}),
      createExceptionEntry({url: 'inbox.google.com', id: 3}),
      createExceptionEntry({url: 'maps.google.com', id: 4}),
      createExceptionEntry({url: 'plus.google.com', id: 5}),
    ];

    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [], exceptionList);

    const exceptions =
        getDomRepeatChildren(passwordsSection.$.passwordExceptionsList);

    // The index of the button currently being checked.
    let item = 0;

    const clickRemoveButton = function() {
      exceptions[item]!.querySelector<HTMLElement>(
                           '#removeExceptionButton')!.click();
    };

    // Removes the next exception item, verifies that the expected method was
    // called on |passwordManager| and continues recursively until no more items
    // exist.
    function removeNextRecursive(): Promise<void> {
      passwordManager.resetResolver('removeException');
      clickRemoveButton();
      return passwordManager.whenCalled('removeException').then(id => {
        // Verify that the event matches the expected value.
        assertTrue(item < exceptionList.length);
        assertEquals(id, exceptionList[item]!.id);

        if (++item < exceptionList.length) {
          return removeNextRecursive();
        }
        return Promise.resolve();
      });
    }

    // Click 'remove' on all passwords, one by one.
    return removeNextRecursive();
  });

  test('showSavedPasswordListItem', async function() {
    const PASSWORD = 'bAn@n@5';
    const item = createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
    passwordManager.setPlaintextPassword(PASSWORD);

    const passwordListItem = elementFactory.createPasswordListItem(item);

    // Hidden passwords should be disabled.
    assertTrue(passwordListItem.shadowRoot!
                   .querySelector<HTMLInputElement>('#password')!.disabled);

    passwordListItem.shadowRoot!
        .querySelector<HTMLElement>('#showPasswordButton')!.click();
    const {id, reason} =
        await passwordManager.whenCalled('requestPlaintextPassword');
    await flushTasks();
    assertEquals(1, id);
    assertEquals('VIEW', reason);

    assertEquals(
        PASSWORD,
        passwordListItem.shadowRoot!
            .querySelector<HTMLInputElement>('#password')!.value);
    // Password should be visible.
    assertEquals(
        'text',
        passwordListItem.shadowRoot!
            .querySelector<HTMLInputElement>('#password')!.type);
    // Visible passwords should not be disabled.
    assertFalse(passwordListItem.shadowRoot!
                    .querySelector<HTMLInputElement>('#password')!.disabled);

    // Hide Password Button should be shown.
    assertTrue(passwordListItem.shadowRoot!
                   .querySelector<HTMLElement>('#showPasswordButton')!.classList
                   .contains('icon-visibility-off'));

    // Hide the Password again.
    passwordListItem.shadowRoot!
        .querySelector<HTMLElement>('#showPasswordButton')!.click();
    flush();

    assertEquals(
        'password',
        passwordListItem.shadowRoot!
            .querySelector<HTMLInputElement>('#password')!.type);
    assertTrue(passwordListItem.shadowRoot!
                   .querySelector<HTMLInputElement>('#password')!.disabled);
    assertTrue(
        passwordListItem.shadowRoot!
            .querySelector<HTMLElement>(
                '#showPasswordButton')!.classList.contains('icon-visibility'));
  });

  test('clickingTheRowDispatchesEventWhenViewPageEnabled', async function() {
    loadTimeData.overrideValues({enablePasswordViewPage: true});
    Router.resetInstanceForTesting(buildRouter());
    routes.PASSWORD_VIEW =
        (Router.getInstance().getRoutes() as SettingsRoutes).PASSWORD_VIEW;
    const URL = 'goo.gl';
    const USERNAME = 'bart';
    const item = createPasswordEntry({url: URL, username: USERNAME, id: 1});

    const passwordSection =
        elementFactory.createPasswordsSection(passwordManager, [item], []);
    const passwordListItem = getFirstPasswordListItem(passwordSection);

    assertFalse(
        isVisible(passwordListItem.shadowRoot!.querySelector<HTMLElement>(
            '#showPasswordButton')));
    assertFalse(isVisible(passwordListItem.$.moreActionsButton));
    const subpageButton = passwordListItem.$.seePasswordDetails;
    assertTrue(isVisible(subpageButton));
    passwordManager.setRequestCredentialDetailsResponse(item);
    const PasswordViewPageRequestedEvent =
        eventToPromise('password-view-page-requested', passwordListItem);
    subpageButton.click();
    await PasswordViewPageRequestedEvent.then((event) => {
      assertDeepEquals(passwordListItem, event.detail);
    });
  });

  // Tests that pressing 'Edit password' sets the corresponding password.
  test('requestPlaintextPasswordInPasswordEditDialog', async function() {
    const PASSWORD = 'password';
    const entry = createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
    passwordManager.setPlaintextPassword(PASSWORD);

    const passwordSection =
        elementFactory.createPasswordsSection(passwordManager, [entry], []);

    getFirstPasswordListItem(passwordSection).$.moreActionsButton.click();
    passwordSection.$.passwordsListHandler.$.menuEditPassword.click();
    flush();

    const {id, reason} =
        await passwordManager.whenCalled('requestPlaintextPassword');
    await flushTasks();
    assertEquals(1, id);
    assertEquals('EDIT', reason);

    const passwordEditDialog =
        passwordSection.$.passwordsListHandler.shadowRoot!.querySelector(
            'password-edit-dialog')!;
    assertEquals('password', passwordEditDialog.$.passwordInput.type);
    assertEquals(PASSWORD, passwordEditDialog.$.passwordInput.value);
    assertTrue(
        passwordEditDialog.shadowRoot!
            .querySelector<HTMLElement>(
                '#showPasswordButton')!.classList.contains('icon-visibility'));
  });

  test('onShowSavedPasswordListItem', async function() {
    const expectedItem =
        createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
    const passwordListItem =
        elementFactory.createPasswordListItem(expectedItem);
    assertEquals('', passwordListItem.entry.password);

    passwordManager.setPlaintextPassword('password');
    passwordListItem.shadowRoot!
        .querySelector<HTMLElement>('#showPasswordButton')!.click();
    const {id, reason} =
        await passwordManager.whenCalled('requestPlaintextPassword');
    await flushTasks();
    assertEquals(1, id);
    assertEquals('VIEW', reason);
    assertEquals('password', passwordListItem.entry.password);
  });

  test('onCopyPasswordListItem', function() {
    const expectedItem =
        createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [expectedItem], []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    passwordsSection.$.passwordsListHandler.$.menuCopyPassword.click();

    return passwordManager.whenCalled('requestPlaintextPassword')
        .then(({id, reason}) => {
          assertEquals(1, id);
          assertEquals('COPY', reason);
        });
  });

  test('onEditPasswordListItem', function() {
    const expectedItem =
        createPasswordEntry({url: 'goo.gl', username: 'bart', id: 1});
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [expectedItem], []);

    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    passwordsSection.$.passwordsListHandler.$.menuEditPassword.click();

    return passwordManager.whenCalled('requestPlaintextPassword')
        .then(({id, reason}) => {
          assertEquals(1, id);
          assertEquals('EDIT', reason);
        });
  });

  test('closingPasswordsSectionHidesUndoToast', function() {
    const passwordEntry =
        createPasswordEntry({url: 'goo.gl', username: 'bart'});
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [passwordEntry], []);
    const toastManager = passwordsSection.$.passwordsListHandler.$.removalToast;

    // Click the remove button on the first password and assert that an undo
    // toast is shown.
    getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
    passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();
    flush();
    assertTrue(toastManager.open);

    // Remove the passwords section from the DOM and check that this closes
    // the undo toast.
    document.body.removeChild(passwordsSection);
    flush();
    assertFalse(toastManager.open);
  });

  // Chrome offers the export option when there are passwords.
  test('offerExportWhenPasswords', function() {
    const passwordList = [
      createPasswordEntry({url: 'googoo.com', username: 'Larry'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    validatePasswordList(passwordsSection, passwordList);
    assertFalse(passwordsSection.$.menuExportPassword.hidden);
  });

  // Chrome shouldn't offer the option to export passwords if there are no
  // passwords.
  test('noExportIfNoPasswords', function() {
    const passwordList: chrome.passwordsPrivate.PasswordUiEntry[] = [];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    validatePasswordList(passwordsSection, passwordList);
    assertTrue(passwordsSection.$.menuExportPassword.disabled);
  });

  test(
      'importPasswordsButtonShownOnlyWhenPasswordsImportFeatureEnabled',
      function() {
        loadTimeData.overrideValues({showImportPasswords: false});
        const passwordsSectionImportPasswordsDisabled =
            elementFactory.createPasswordsSection(passwordManager, [], []);
        assertTrue(
            passwordsSectionImportPasswordsDisabled.shadowRoot!
                .querySelector<HTMLElement>('#menuImportPassword')!.hidden);
        loadTimeData.overrideValues({showImportPasswords: true});
        const passwordsSectionImportPasswordsEnabled =
            elementFactory.createPasswordsSection(passwordManager, [], []);
        assertFalse(
            passwordsSectionImportPasswordsEnabled.shadowRoot!
                .querySelector<HTMLElement>('#menuImportPassword')!.hidden);
      });

  test('importButtonOpensPasswordsImportDialog', function() {
    loadTimeData.overrideValues({showImportPasswords: true});
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    assertFalse(!!passwordsSection.shadowRoot!.querySelector<HTMLElement>(
        '#importPasswordsDialog'));

    passwordsSection.shadowRoot!
        .querySelector<HTMLElement>('#menuImportPassword')!.click();
    flush();
    const importDialog =
        passwordsSection.shadowRoot!.querySelector<HTMLElement>(
            '#importPasswordsDialog');
    assertTrue(!!importDialog);
  });

  // Test that clicking the Export Passwords menu item opens the export
  // dialog.
  test('exportOpen', async function() {
    const passwordList = [
      createPasswordEntry({url: 'googoo.com', username: 'Larry'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);

    passwordsSection.$.menuExportPassword.click();
    // The export dialog calls requestExportProgressStatus() when opening.
    await passwordManager.whenCalled('requestExportProgressStatus');
  });

  if (!(isChromeOS || isLacros)) {
    // Test verifies that the overflow menu does not offer an option to move a
    // password to the account.
    test('noMoveToAccountOption', function() {
      const passwordsSection =
          elementFactory.createPasswordsSection(passwordManager, [], []);
      assertTrue(passwordsSection.$.passwordsListHandler.$
                     .menuMovePasswordToAccount.hidden);
    });

    // Tests that the opt-in/opt-out buttons appear for signed-in (non-sync)
    // users and that the text content changes accordingly.
    test('changeOptInButtonsBasedOnSignInAndAccountStorageOptIn', function() {
      const passwordsSection =
          elementFactory.createPasswordsSection(passwordManager, [], []);

      // Sync is disabled and the user is initially signed out.
      simulateSyncStatus(
          {signedIn: false, statusAction: StatusAction.NO_ACTION});
      function isDisplayed(element: HTMLElement): boolean {
        return !!element && !element.hidden;
      }
      assertFalse(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));

      // User signs in but is not opted in yet.
      simulateStoredAccounts([{email: 'john@gmail.com'}]);
      passwordManager.setIsOptedInForAccountStorageAndNotify(false);
      flush();
      assertTrue(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
      assertTrue(isDisplayed(passwordsSection.$.optInToAccountStorageButton));
      assertFalse(isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
      assertTrue(isDisplayed(passwordsSection.$.accountStorageOptInBody));
      assertFalse(isDisplayed(passwordsSection.$.accountStorageOptOutBody));

      // Opt in.
      passwordManager.setIsOptedInForAccountStorageAndNotify(true);
      flush();
      assertTrue(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
      assertFalse(isDisplayed(passwordsSection.$.optInToAccountStorageButton));
      assertTrue(isDisplayed(passwordsSection.$.optOutOfAccountStorageButton));
      assertTrue(isDisplayed(passwordsSection.$.accountStorageOptOutBody));
      assertFalse(isDisplayed(passwordsSection.$.accountStorageOptInBody));
      assertEquals('john@gmail.com', passwordsSection.$.accountEmail.innerText);

      // Sign out
      simulateStoredAccounts([]);
      assertFalse(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
    });

    // Test verifies the the account storage buttons are not shown for custom
    // passphrase users.
    test('accountStorageButonsNotShownForCustomPassphraseUser', function() {
      const passwordsSection =
          elementFactory.createPasswordsSection(passwordManager, [], []);

      simulateSyncStatus(
          {signedIn: false, statusAction: StatusAction.NO_ACTION});
      simulateStoredAccounts([{email: 'john@gmail.com'}]);
      // Simulate custom passphrase.
      const syncPrefs = getSyncAllPrefs();
      syncPrefs.encryptAllData = true;
      webUIListenerCallback('sync-prefs-changed', syncPrefs);
      flush();

      assertTrue(
          !passwordsSection.$.accountStorageButtonsContainer ||
          passwordsSection.$.accountStorageButtonsContainer.hidden);
    });

    // Test verifies that enabling sync hides the buttons for account storage
    // opt-in/out and the 'device passwords' page.
    test('enablingSyncHidesAccountStorageButtons', function() {
      const passwordsSection =
          elementFactory.createPasswordsSection(passwordManager, [], []);

      simulateAccountStorageUser(passwordManager);
      function isDisplayed(element: HTMLElement): boolean {
        return element && !element.hidden;
      }
      assertTrue(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));

      // Enable sync.
      simulateSyncStatus(
          {signedIn: true, statusAction: StatusAction.NO_ACTION});
      assertFalse(
          isDisplayed(passwordsSection.$.accountStorageButtonsContainer));
    });

    // Test verifies that the button linking to the 'device passwords' page is
    // only visible when there is at least one device password.
    test('verifyDevicePasswordsButtonVisibility', function() {
      // Set up user eligible to the account-scoped password storage, not
      // opted in and with no device passwords. Button should be hidden.
      const passwordList =
          [createPasswordEntry({inAccountStore: true, id: 10})];
      const passwordsSection = elementFactory.createPasswordsSection(
          passwordManager, passwordList, []);
      simulateSyncStatus(
          {signedIn: false, statusAction: StatusAction.NO_ACTION});
      simulateStoredAccounts([{email: 'john@gmail.com'}]);
      assertTrue(passwordsSection.$.devicePasswordsLink.hidden);

      // Opting in still doesn't display it because the user has no device
      // passwords yet.
      passwordManager.setIsOptedInForAccountStorageAndNotify(true);
      flush();
      assertTrue(passwordsSection.$.devicePasswordsLink.hidden);

      // Add a device password. The button shows up.
      passwordList.unshift(createPasswordEntry({inProfileStore: true, id: 20}));
      passwordManager.lastCallback.addSavedPasswordListChangedListener!
          (passwordList);
      flush();
      assertFalse(passwordsSection.$.devicePasswordsLink.hidden);
    });

    // Test verifies that, for account-scoped password storage users, removing
    // a password stored in a single location indicates the location in the
    // toast manager message.
    test(
        'passwordRemovalMessageSpecifiesStoreForAccountStorageUsers',
        function() {
          const passwordList = [
            createPasswordEntry(
                {username: 'account', id: 0, inAccountStore: true}),
            createPasswordEntry(
                {username: 'local', id: 1, inProfileStore: true}),
          ];
          const passwordsSection = elementFactory.createPasswordsSection(
              passwordManager, passwordList, []);

          simulateAccountStorageUser(passwordManager);

          // No removal actually happens, so all passwords keep their position.
          const passwordListItems =
              passwordsSection.shadowRoot!.querySelectorAll(
                  'password-list-item');
          passwordListItems[0]!.$.moreActionsButton.click();
          passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();
          flush();
          assertEquals(
              passwordsSection.i18n('passwordDeletedFromAccount'),
              passwordsSection.$.passwordsListHandler.$.removalNotification
                  .textContent);

          passwordListItems[1]!.$.moreActionsButton.click();
          passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();
          flush();
          assertEquals(
              passwordsSection.i18n('passwordDeletedFromDevice'),
              passwordsSection.$.passwordsListHandler.$.removalNotification
                  .textContent);
        });

    // Test verifies that if the user attempts to remove a password stored
    // both on the device and in the account, the PasswordRemoveDialog shows up.
    // Clicking the button in the dialog then removes both versions of the
    // password.
    test('verifyPasswordRemoveDialogRemoveBothCopies', async function() {
      const password = createPasswordEntry(
          {id: 0, inAccountStore: true, inProfileStore: true});
      const passwordsSection = elementFactory.createPasswordsSection(
          passwordManager, [password], []);

      simulateAccountStorageUser(passwordManager);

      // At first the dialog is not shown.
      assertTrue(
          !passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector(
              'password-remove-dialog'));

      // Clicking remove in the overflow menu shows the dialog.
      getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
      passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();
      flush();
      const removeDialog =
          passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector(
              'password-remove-dialog');
      assertTrue(!!removeDialog);

      // Both checkboxes are selected by default. Confirming removes from both
      // account and device.
      assertTrue(
          removeDialog.$.removeFromAccountCheckbox.checked &&
          removeDialog.$.removeFromDeviceCheckbox.checked);
      removeDialog.$.removeButton.click();
      const {id, fromStores} =
          await passwordManager.whenCalled('removeSavedPassword');
      assertEquals(password.id, id);
      assertEquals('DEVICE_AND_ACCOUNT', fromStores);
    });

    // Test verifies that if the user attempts to remove a password stored
    // both on the device and in the account, the PasswordRemoveDialog shows up.
    // The user then chooses to remove only of the copies.
    test('verifyPasswordRemoveDialogRemoveSingleCopy', async function() {
      const onAccountAndDevice = createPasswordEntry(
          {id: 0, inAccountStore: true, inProfileStore: true});
      const passwordsSection = elementFactory.createPasswordsSection(
          passwordManager, [onAccountAndDevice], []);

      simulateAccountStorageUser(passwordManager);

      // At first the dialog is not shown.
      assertTrue(
          !passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector(
              '#passwordRemoveDialog'));

      // Clicking remove in the overflow menu shows the dialog.
      getFirstPasswordListItem(passwordsSection).$.moreActionsButton.click();
      passwordsSection.$.passwordsListHandler.$.menuRemovePassword.click();
      flush();
      const removeDialog =
          passwordsSection.$.passwordsListHandler.shadowRoot!.querySelector(
              'password-remove-dialog');
      assertTrue(!!removeDialog);

      // Uncheck the account checkboxes then confirm. Only the device copy is
      // removed.
      removeDialog.$.removeFromAccountCheckbox.click();
      flush();
      assertTrue(
          !removeDialog.$.removeFromAccountCheckbox.checked &&
          removeDialog.$.removeFromDeviceCheckbox.checked);
      removeDialog.$.removeButton.click();
      const {id, fromStores} =
          await passwordManager.whenCalled('removeSavedPassword');
      assertEquals(onAccountAndDevice.id, id);
      assertEquals(chrome.passwordsPrivate.PasswordStoreSet.DEVICE, fromStores);
    });
  }

  test(
      'showPasswordCheckBannerWhenNotCheckedBeforeAndSignedInAndHavePasswords',
      function() {
        // Suppose no check done initially, non-empty list of passwords,
        // signed in.
        assertEquals(
            passwordManager.data.checkStatus.elapsedTimeSinceLastCheck,
            undefined);
        const passwordList = [
          createPasswordEntry({url: 'site1.com', username: 'luigi'}),
        ];
        const passwordsSection = elementFactory.createPasswordsSection(
            passwordManager, passwordList, []);
        return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
          simulateSyncStatus(
              {signedIn: true, statusAction: StatusAction.NO_ACTION});
          flush();
          assertFalse(passwordsSection.$.checkPasswordsBannerContainer.hidden);
          assertFalse(passwordsSection.$.checkPasswordsButtonRow.hidden);
          assertTrue(passwordsSection.$.checkPasswordsLinkRow.hidden);
        });
      });

  test(
      'showPasswordCheckBannerWhenCanceledCheckedBeforeAndSignedInAndHavePasswords',
      async function() {
        // Suppose initial check was canceled, non-empty list of passwords,
        // signed in.
        assertEquals(
            passwordManager.data.checkStatus.elapsedTimeSinceLastCheck,
            undefined);
        const passwordList = [
          createPasswordEntry({url: 'site1.com', username: 'luigi', id: 0}),
          createPasswordEntry({url: 'site2.com', username: 'luigi', id: 1}),
        ];
        passwordManager.data.checkStatus.state = PasswordCheckState.CANCELED;
        passwordManager.data.leakedCredentials = [
          makeCompromisedCredential(
              'site1.com', 'luigi',
              chrome.passwordsPrivate.CompromiseType.LEAKED),
        ];
        pluralString.text = '1 compromised password';

        const passwordsSection = elementFactory.createPasswordsSection(
            passwordManager, passwordList, []);

        await passwordManager.whenCalled('getCompromisedCredentials');
        await pluralString.whenCalled('getPluralString');

        flush();
        assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
        assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
        assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
        assertEquals(
            pluralString.text,
            passwordsSection.shadowRoot!
                .querySelector<HTMLElement>(
                    '#checkPasswordLeakCount')!.innerText!.trim());
      });

  test('showPasswordCheckLinkButtonWithoutWarningWhenNotSignedIn', function() {
    // Suppose no check done initially, non-empty list of passwords,
    // signed out.
    assertEquals(
        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, undefined);
    const passwordList = [
      createPasswordEntry({url: 'site1.com', username: 'luigi'}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);
    simulateSyncStatus({signedIn: false, statusAction: StatusAction.NO_ACTION});
    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
      flush();
      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
    });
  });

  test('showPasswordCheckLinkButtonWithoutWarningWhenNoPasswords', function() {
    // Suppose no check done initially, empty list of passwords, signed
    // in.
    assertEquals(
        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, undefined);
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
      flush();
      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
    });
  });

  test(
      'showPasswordCheckLinkButtonWithoutWarningWhenNoCredentialsLeaked',
      function() {
        // Suppose no leaks initially, non-empty list of passwords, signed in.
        passwordManager.data.leakedCredentials = [];
        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck =
            '5 min ago';
        const passwordList = [
          createPasswordEntry({url: 'site1.com', username: 'luigi'}),
        ];
        const passwordsSection = elementFactory.createPasswordsSection(
            passwordManager, passwordList, []);
        return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
          flush();
          assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
          assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
          assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
          assertFalse(passwordsSection.$.checkPasswordLeakDescription.hidden);
          assertTrue(passwordsSection.$.checkPasswordWarningIcon.hidden);
          assertTrue(passwordsSection.$.checkPasswordLeakCount.hidden);
        });
      });

  test(
      'showPasswordCheckLinkButtonWithWarningWhenSomeCredentialsLeaked',
      function() {
        // Suppose no leaks initially, non-empty list of passwords, signed in.
        passwordManager.data.leakedCredentials = [
          makeCompromisedCredential(
              'one.com', 'test4',
              chrome.passwordsPrivate.CompromiseType.LEAKED),
          makeCompromisedCredential(
              'two.com', 'test3',
              chrome.passwordsPrivate.CompromiseType.PHISHED),
        ];
        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck =
            '5 min ago';
        const passwordList = [
          createPasswordEntry({url: 'site1.com', username: 'luigi'}),
        ];
        const passwordsSection = elementFactory.createPasswordsSection(
            passwordManager, passwordList, []);
        return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
          flush();
          assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
          assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
          assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
          assertTrue(passwordsSection.$.checkPasswordLeakDescription.hidden);
          assertFalse(passwordsSection.$.checkPasswordWarningIcon.hidden);
          assertFalse(passwordsSection.$.checkPasswordLeakCount.hidden);
        });
      });

  test('makeWarningAppearWhenLeaksDetected', function() {
    // Suppose no leaks detected initially, non-empty list of passwords,
    // signed in.
    assertEquals(
        passwordManager.data.checkStatus.elapsedTimeSinceLastCheck, undefined);
    passwordManager.data.leakedCredentials = [];
    passwordManager.data.checkStatus.elapsedTimeSinceLastCheck = '5 min ago';
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'test4', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'test3', id: 1}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);
    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
      flush();
      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordLeakDescription.hidden);
      assertTrue(passwordsSection.$.checkPasswordWarningIcon.hidden);
      assertTrue(passwordsSection.$.checkPasswordLeakCount.hidden);
      // Suppose two newly detected leaks come in.
      const leakedCredentials = [
        makeCompromisedCredential(
            'one.com', 'test4', chrome.passwordsPrivate.CompromiseType.LEAKED),
        makeCompromisedCredential(
            'two.com', 'test3', chrome.passwordsPrivate.CompromiseType.PHISHED),
      ];
      const elapsedTimeSinceLastCheck = 'just now';
      passwordManager.data.leakedCredentials = leakedCredentials;
      passwordManager.data.checkStatus.elapsedTimeSinceLastCheck =
          elapsedTimeSinceLastCheck;
      passwordManager.lastCallback.addCompromisedCredentialsListener!
          (leakedCredentials);
      passwordManager.lastCallback.addPasswordCheckStatusListener!
          (makePasswordCheckStatus(
              /*state=*/ PasswordCheckState.RUNNING,
              /*checked=*/ 2,
              /*remaining=*/ 0,
              /*elapsedTime=*/ elapsedTimeSinceLastCheck));
      flush();
      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
      assertTrue(passwordsSection.$.checkPasswordLeakDescription.hidden);
      assertFalse(passwordsSection.$.checkPasswordWarningIcon.hidden);
      assertFalse(passwordsSection.$.checkPasswordLeakCount.hidden);
    });
  });

  test('makeBannerDisappearWhenSignedOut', function() {
    // Suppose no leaks detected initially, non-empty list of passwords,
    // signed in.
    const passwordList = [
      createPasswordEntry({url: 'one.com', username: 'test4', id: 0}),
      createPasswordEntry({url: 'two.com', username: 'test3', id: 1}),
    ];
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, passwordList, []);
    return passwordManager.whenCalled('getPasswordCheckStatus').then(() => {
      simulateSyncStatus(
          {signedIn: true, statusAction: StatusAction.NO_ACTION});
      flush();
      assertFalse(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertFalse(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertTrue(passwordsSection.$.checkPasswordsLinkRow.hidden);

      simulateSyncStatus(
          {signedIn: false, statusAction: StatusAction.NO_ACTION});
      assertTrue(passwordsSection.$.checkPasswordsBannerContainer.hidden);
      assertTrue(passwordsSection.$.checkPasswordsButtonRow.hidden);
      assertFalse(passwordsSection.$.checkPasswordsLinkRow.hidden);
    });
  });

  test('clickingCheckPasswordsButtonStartsCheck', async function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    passwordsSection.shadowRoot!
        .querySelector<HTMLElement>('#checkPasswordsButton')!.click();
    flush();
    const router = Router.getInstance();
    assertEquals(routes.CHECK_PASSWORDS, router.currentRoute);
    assertEquals('true', router.getQueryParameters().get('start'));
    const referrer =
        await passwordManager.whenCalled('recordPasswordCheckReferrer');
    assertEquals(PasswordCheckReferrer.PASSWORD_SETTINGS, referrer);
  });

  test('clickingCheckPasswordsRowStartsCheck', async function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    passwordsSection.shadowRoot!
        .querySelector<HTMLElement>('#checkPasswordsLinkRow')!.click();
    flush();
    const router = Router.getInstance();
    assertEquals(routes.CHECK_PASSWORDS, router.currentRoute);
    assertEquals('true', router.getQueryParameters().get('start'));
    const referrer =
        await passwordManager.whenCalled('recordPasswordCheckReferrer');
    assertEquals(PasswordCheckReferrer.PASSWORD_SETTINGS, referrer);
  });

  test('hatsInformedOnOpen', async function() {
    elementFactory.createPasswordsSection(passwordManager, [], []);
    const interaction =
        await testHatsBrowserProxy.whenCalled('trustSafetyInteractionOccurred');
    assertEquals(TrustSafetyInteraction.OPENED_PASSWORD_MANAGER, interaction);
  });

  test('passwordScriptsRefreshedOnOpen', async function() {
    loadTimeData.overrideValues(
        {enableAutomaticPasswordChangeInSettings: true});
    elementFactory.createPasswordsSection(passwordManager, [], []);
    Router.getInstance().navigateTo(routes.PASSWORDS);
    await passwordManager.whenCalled('refreshScriptsIfNecessary');
  });

  test(
      'addPasswordButtonShownOnlyWhenPasswordManagerNotDisabledByPolicy',
      function() {
        const passwordsSection =
            elementFactory.createPasswordsSection(passwordManager, [], []);
        const addButton =
            passwordsSection.shadowRoot!.querySelector<HTMLElement>(
                '#addPasswordButton')!;

        passwordsSection.set('prefs.credentials_enable_service', {
          enforcement: chrome.settingsPrivate.Enforcement.ENFORCED,
          value: false,
        });
        flush();
        assertTrue(addButton.style.display === 'none');

        passwordsSection.set('prefs.credentials_enable_service.value', true);
        flush();
        assertFalse(addButton.style.display === 'none');
      });

  test('addPasswordButtonOpensAddPasswordDialog', function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    assertFalse(!!passwordsSection.shadowRoot!.querySelector<HTMLElement>(
        '#addPasswordDialog'));

    passwordsSection.shadowRoot!
        .querySelector<HTMLElement>('#addPasswordButton')!.click();
    flush();
    const addDialog = passwordsSection.shadowRoot!.querySelector<HTMLElement>(
        '#addPasswordDialog');
    assertTrue(!!addDialog);
  });

  test('trustedVaultBannerVisibilityChangesWithState', function() {
    const passwordsSection =
        elementFactory.createPasswordsSection(passwordManager, [], []);
    webUIListenerCallback(
        'trusted-vault-banner-state-changed',
        TrustedVaultBannerState.NOT_SHOWN);
    flush();
    assertTrue(passwordsSection.$.trustedVaultBanner.hidden);

    webUIListenerCallback(
        'trusted-vault-banner-state-changed',
        TrustedVaultBannerState.OFFER_OPT_IN);
    flush();
    assertFalse(passwordsSection.$.trustedVaultBanner.hidden);
    assertEquals(
        passwordsSection.i18n('trustedVaultBannerSubLabelOfferOptIn'),
        passwordsSection.$.trustedVaultBanner.subLabel);

    webUIListenerCallback(
        'trusted-vault-banner-state-changed', TrustedVaultBannerState.OPTED_IN);
    flush();
    assertFalse(passwordsSection.$.trustedVaultBanner.hidden);
    assertEquals(
        passwordsSection.i18n('trustedVaultBannerSubLabelOptedIn'),
        passwordsSection.$.trustedVaultBanner.subLabel);
  });

  test('routingWithRemovalParamsShowsNotification', function() {
    const passwordEntry =
        createPasswordEntry({url: 'goo.gl', username: 'bart'});
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [passwordEntry], []);
    const toastManager = passwordsSection.$.passwordsListHandler.$.removalToast;

    const params = new URLSearchParams();
    params.set('removedFromStores', passwordEntry.storedIn);
    Router.getInstance().navigateTo(routes.PASSWORDS, params);

    flush();
    assertTrue(toastManager.open);

    // Remove the passwords section from the DOM and check that this closes
    // the undo toast.
    document.body.removeChild(passwordsSection);
    flush();
    assertFalse(toastManager.open);
  });

  test('routingWithAuthTimeoutParamShowsRemovalDialog', function() {
    const passwordEntry =
        createPasswordEntry({url: 'goo.gl', username: 'bart'});
    const passwordsSection = elementFactory.createPasswordsSection(
        passwordManager, [passwordEntry], []);
    const authTimeoutDialog = passwordsSection.$.authTimeoutDialog;

    const params = new URLSearchParams();
    params.set('authTimeout', 'true');
    Router.getInstance().navigateTo(routes.PASSWORDS, params);

    flush();
    assertTrue(authTimeoutDialog.open);

    authTimeoutDialog.close();
    flush();
    assertFalse(authTimeoutDialog.open);
    assertFalse(!!Router.getInstance().getQueryParameters().get('authTimeout'));
  });
});

redpajama_set_name: RedPajamaGithub


text:
#define ERROR_STRING_SIZE 1024

NAN_METHOD(List);
void EIO_List(uv_work_t* req);
void EIO_AfterList(uv_work_t* req);

struct ListResultItem {
  std::string comName;
  std::string manufacturer;
  std::string serialNumber;
  std::string pnpId;
  std::string locationId;
  std::string vendorId;
  std::string productId;
};

struct ListBaton {
  Nan::Callback callback;
  std::list<ListResultItem*> results;
  char errorString[ERROR_STRING_SIZE];
};

typedef struct SerialDevice {
    char port[MAXPATHLEN];
    char locationId[MAXPATHLEN];
    char vendorId[MAXPATHLEN];
    char productId[MAXPATHLEN];
    char manufacturer[MAXPATHLEN];
    char serialNumber[MAXPATHLEN];
} stSerialDevice;

typedef struct DeviceListItem {
    struct SerialDevice value;
    struct DeviceListItem *next;
    int* length;
} stDeviceListItem;

#endif  // SRC_SERIALPORT_DARWIN_LIST_H_


text:
// <copyright file="ISettingsService.cs" company="DevDigital">
// Copyright (c) DevDigital. All rights reserved.
// </copyright>

namespace AutoResponse.Sample.Domain.Services
{
    /// <summary>
    /// Settings service.
    /// </summary>
    public interface ISettingsService
    {
        /// <summary>
        /// Gets the include full details setting.
        /// </summary>
        /// <returns>True if include full details; false otherwise.</returns>
        bool GetIncludeFullDetails();
    }
}


text:
/*
 * Bean Validation: constrain once, validate everywhere.
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package org.beanvalidation.specexamples.constraintdeclarationvalidation.resolution;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

//tag::include[]
@Documented
@NotNull
@Size(min = 1)
@ReportAsSingleViolation
@Constraint(validatedBy = NotEmpty.NotEmptyValidator.class)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface NotEmpty {

	String message() default "{com.acme.constraint.NotEmpty.message}";

	Class<?>[] groups() default {};

	Class<? extends Payload>[] payload() default {};

	@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
	@Retention(RUNTIME)
	@Documented
	@interface List {
		NotEmpty[] value();
	}

	class NotEmptyValidator implements ConstraintValidator<NotEmpty, String> {

		@Override
		public boolean isValid(String value, ConstraintValidatorContext context) {
			return true;
		}
	}
}
//end::include[]


text:
define('dojox/grid/nls/DataGrid_pt-br',{
'dijit/nls/loading':{"loadingState":"Carregando...","errorState":"Desculpe, ocorreu um erro"}
});


text:
package google

import "reflect"

const NotebooksLocationAssetType string = "notebooks.googleapis.com/Location"

func resourceConverterNotebooksLocation() ResourceConverter {
	return ResourceConverter{
		AssetType: NotebooksLocationAssetType,
		Convert:   GetNotebooksLocationCaiObject,
	}
}

func GetNotebooksLocationCaiObject(d TerraformResourceData, config *Config) ([]Asset, error) {
	name, err := assetName(d, config, "//notebooks.googleapis.com/projects/{{project}}/locations/{{name}}")
	if err != nil {
		return []Asset{}, err
	}
	if obj, err := GetNotebooksLocationApiObject(d, config); err == nil {
		return []Asset{{
			Name: name,
			Type: NotebooksLocationAssetType,
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/notebooks/v1/rest",
				DiscoveryName:        "Location",
				Data:                 obj,
			},
		}}, nil
	} else {
		return []Asset{}, err
	}
}

func GetNotebooksLocationApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	nameProp, err := expandNotebooksLocationName(d.Get("name"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
		obj["name"] = nameProp
	}

	return obj, nil
}

func expandNotebooksLocationName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}


text:
The development of this image will be discontinued. Since [0.104](https://github.com/Cisco-Talos/clamav/blob/main/NEWS.md#01040) Cisco provides official docker images for clamav. This image here will be on hold and supported as long as possible.

At the moment we are faced with unexpected disconnects during database updates. This might be due to changes in the database download handling from the clamav servers.

# docker-clamav

[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)

![ClamAV Logo](https://www.clamav.net/assets/clamav-trademark.png)

![ClamAV latest.stable](https://img.shields.io/badge/ClamAV-latest.stable-brightgreen.svg?style=flat-square)

[![CI-Build](https://github.com/mko-x/docker-clamav/actions/workflows/build-and-push.yml/badge.svg)](https://github.com/mko-x/docker-clamav/actions/workflows/build-and-push.yml)

Dockerized open source antivirus daemons for use with
- file sharing containers like [Nextcloud](https://hub.docker.com/_/nextcloud/) or
- to use it via a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) proxy like [@solita](https://github.com/solita) made [clamav-rest](https://github.com/solita/clamav-rest) or
- to check files on a server via e.g. node.js [kylefarris/clamscan](https://github.com/kylefarris/clamscan)
- to directly connect to *clamav* via TCP port `3310`

ClamAV daemon as a Docker image. It *builds* with a current virus database and
*runs* `freshclam` in the background constantly updating the virus signature database. `clamd` itself
is listening on exposed port `3310`.

# Releases
Find the latest releases at the official [docker hub](https://hub.docker.com/r/mkodockx/docker-clamav) registry. There are different releases for the different platforms.

With special thanks to [@WhiteBahamut](https://github.com/WhiteBahamut) you will find versioned builds to pin to for production use at docker hub.

# Usage
The container run as user `clamav` with `uid=101` and `gid=102`.

## Debian (default, :latest, :buster-slim, :stretch-slim)
- buster-slim
- stretch-slim
```bash
    docker run -d -p 3310:3310 mkodockx/docker-clamav:buster-slim
```

## Alpine (:alpine, :alpine-edge, :alpine-main-idb-amd64)
- alpine
- alpine-idb-amd64 (initialized databases, [more info](alpine/main-idb/README.md))
- alpine-edge
```bash
    docker run -d -p 3310:3310 mkodockx/docker-clamav:alpine
```

## Prefer alpine-idb-amd64

Joel Esler from Cisco (main hosts of ClamAV):

**Downloading using other than FreshClam has now been limited.**

FreshClam supports the Cdiff system, the cdiff system allows for small micro
updates to rebuild your daily.cvd instead of downloading the whole daily.cvd
and main.cvd.

Abuse of the download system has forced us to push people towards FreshClam.
Unfortunately a handful have ruined it for everyone.  (Looking at you, handful
of IPs that download the daily.cvd 3x a second)

We cannot continue to transfer 9PB of traffic a month.

Further enhancements to Freshclam are planned to take advantage of, and handle
our mirror infrastructure more politely.  More details will be published about
this soon.  In the meantime, please immediately discontinue the use of other
command line downloading systems and use FreshClam.

So to clarify:

1. Rate limiting around daily.cvd, main.cvd, and super excessive cdiff
downloading is now in place.  If you are getting "429" back from Cloudflare -
you are part of the problem.
2. Use of Wget, Curl, and the link is now severely limited.
3. Use FreshClam
4. We're modifying FreshClam in upcoming releases to deal with this problem
better.
5. See #3

--
Joel Esler
Manager, Communities Division
Cisco Talos Intelligence Group
http://www.talosintelligence.com | https://www.snort.org

> On Mar 3, 2021, at 9:57 AM, Joel Esler (jesler) via clamav-users
> <clamav-users@lists.clamav.net> wrote:
>
> Signed PGP part
> All —
>
> I've had to be more stringent on the rate limiting for the daily.cvd and
> main.cvd files.  It seems that some people either have stuck cron jobs (or
> are doing it on purpose) and downloading the full file 200k-300k times a day.
>
> We release AV updates once a day, in an emergency slightly more than that.
> There is no reason for this.  I've had to lower the amount of connections you
> are allowed, and raise the amount of time you are blocked.
>
> If you are being blocked with a 429 code from the ClamAV update system, and
> you believe your system isn't broken, and have a valid reason to download
> that much.
>
> 1. Feel free to reach out to me via 1:1 or via this list.
> 2. Consider setting up a local mirror on your network.
>
> Repeat:  You need to be using freshclam, and freshclam only.  It needs to
> check the DNS for the presence of an update, and you need to be downloading
> the diff files.  There's no reason to download the full main and daily.
>
> --
> Joel Esler
> Manager, Communities Division
> Cisco Talos Intelligence Group
> http://www.talosintelligence.com | https://www.snort.org
>
>

Source: https://www.mail-archive.com/clamav-users@lists.clamav.net/msg49810.html

With alpine-idb-amd64 image you download data just from docker hub not from clamav initially.

## Linkage (deprecated)
Linked usage was recommended, to not expose the port to "everyone". Now it is legacy and will be removed some time. Use networks instead.
```bash
    docker run -d --name av mkodockx/docker-clamav(:alpine)
    docker run -d --link av:av application-with-clamdscan-or-something
```
## Networks

There are several possibilities to use the network configuration. Out of the box the host network should fit your needs to connect any client to the ClamAV daemon.

If you need more information, follow instructions at [docker manuals](https://docs.docker.com/network/).

## Environment VARs

### Proxy
Thanks to @mchus proxy configuration is possible.
- HTTPProxyServer: Allows to set a proxy server
- HTTPProxyPort: Allows to set a proxy server port

### Database Mirror
Specifying a particular mirror for freshclam is also possible.
- DatabaseMirror: Hostname of the mirror web server.

### Custom Configuration Files
Mount custom configuration files into the container.
- FRESHCLAM_CONF_FILE: Path to custom `freshclam.conf` file, e.g. `/mnt/freshclam.conf`.
- CLAMD_CONF_FILE: Set the path to a custom `clamd.conf` file, e.g. `/mnt/clamd.conf`.

## Persistency
Virus update definitions are stored in `/var/lib/clamav`. To store the defintion just mount the directory as a volume, `docker run -d -p 3310:3310 -v $(pwd)/clamav:/var/lib/clamav mkodockx/docker-clamav:latest`

## docker-compose
See example with Nextcloud at [docker-compose.yml](https://github.com/mko-x/docker-clamav/blob/master/docker-compose.yml). You still need to configure the *AntiVirus files* app in Nextcloud.

You can find a tutorial here: https://www.virtualconfusion.net/clamav-for-nextcloud-on-docker/

## Healthcheck
The images provide with `check.sh` a file to check for the healthyness of the running container. To enable the health check configure your `docker run` or `compose file`. The _start period_ should be adjusted to your system needs. Slow internet connection, with limited cpu and IO speed might require larger values.

### Examples
Via docker run:

```
docker run --health-cmd=./check.sh \
            --health-start-period=120s \
            --health-interval=60s \
            --health-retries=3 \
            -p 3310:3310 mkodockx/docker-clamav:alpine`
```

Via docker-compose
```yml
  services:
    clamav:
      healthcheck:
        test: ["CMD", "./check.sh"]
        interval: 60s
        retries: 3
        start_period: 120s
```

# Build multi-arch
This image provides support for different platforms
- x86
- amd64
- arm32v7
- arm64v8

# Known Forks
- OpenShift support in [kuanfandevops fork](https://github.com/kuanfandevops/docker-clamav)

# FAQ
## Memory?
Some users are wondering about memory consumption of clamd. Here is an explanation of the reasons I found:

"ClamAV holds the search strings using the classic string (Boyer Moore) and regular expression (Aho Corasick) algorithms. Being algorithms from the 1970s they are extemely memory efficient.

The problem is the huge number of virus signatures. This leads to the algorithms' datastructures growing quite large.

You can't send those datastructures to swap, as there are no parts of the algorithms' datastructures accessed less often than other parts. If you do force pages of them to swap disk, then they'll be referenced moments later and just swap straight back in. (Technically we say "the random access of the datastructure forces the entire datastructure to be in the process's working set of memory".)

The datastructures are needed if you are scanning from the command line or scanning from a daemon.

You can't use just a portion of the virus signatures, as you don't get to choose which viruses you will be sent, and thus can't tell which signatures you will need."
Source [stackexchange.com](https://unix.stackexchange.com/questions/114709/how-to-reduce-clamav-memory-usage/278110#278110)

It is obvious that an antivirus engine based on virus signatures will raise memory consumption over the time as it always has to check for **all** signatures. As the number of virus signatures grows daily, the amount of necessary memory will increase as well.

## Error during DB update
Several users are experiencing problems during the database updates (incremental,diff,initial).

ClamaV is open source and the databases are provided by a network of mirrors that are hosted for free by some folks (Cisco) to support open source antivirus. That was about 9 PB a month. That is why downloads are now protected by Cloudflare. If you're downloading too often you will recieve 429 errors. (See ## Prefer alpine-idb-amd64 at the top of this document)

If you have an error related to the updates on your special OS, machine, iPad ;) or anything special else, first check the [FAQ to clamav troubleshooting](https://www.clamav.net/documents/troubleshooting-faq) and then the [virus database FAQ](https://www.clamav.net/documents/clamav-virus-database-faq.html).

If you keep on getting errors you might try your own [private local mirror](https://www.clamav.net/documents/private-local-mirrors) easily.

### alpine-idb-amd64

If you have problems with freshclam downloads use the alpine image with initialized dbs. [more info](alpine/main-idb/README.md)

# Projects
Several projects are using this image:
- [solita/clamav-rest](https://github.com/solita/clamav-rest)
- [r3kzi/clamav-prometheus-exporter](https://github.com/r3kzi/clamav-prometheus-exporter)
- [US DoD transcom/mymove](https://github.com/transcom/mymove)
- [Inveniem/nextcloud-azure-aks](https://github.com/Inveniem/nextcloud-azure-aks)
- [pivotal.io jzheaux/terracotta-bank](https://github.com/jzheaux/terracotta-bank)
- [Hasso Plattner Institut, Schul Cloud hpi-schul-cloud/antivirus_check_service](https://github.com/hpi-schul-cloud/antivirus_check_service)
- [UK Government Crown-Commercial-Service/ccs-conclave-document-clamav](https://github.com/Crown-Commercial-Service/ccs-conclave-document-clamav)
- [UKHomeOffice/file-vault](https://github.com/UKHomeOffice/file-vault)
- [SICTIAM/stela](https://github.com/SICTIAM/stela)
- [DeloitteDigitalAT/terracotta-bank](https://github.com/DeloitteDigitalAT/terracotta-bank)
- [UK ministryofjustice/moj-clamav-rest](https://github.com/ministryofjustice/moj-clamav-rest)
- [weixian-zhang/Azure-sSFTP](https://github.com/weixian-zhang/Azure-sSFTP)
- [Mattermost](https://github.com/mattermost/mattermost-plugin-antivirus)
- [Province of British Columbia, Transportation Fuels Reporting System (TFRS)](https://github.com/bcgov/tfrs)
- ...

# Thanks

Thank you for using this image. I have only a blink of how many projects are using this, but I know there are some including big tech, governments and many open source. I try to keep it working in my rare spare time. Feel free to participate or get in contact.

# License

For license see file [LICENSE](./LICENSE)

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

Mikhail Chus
💻

DavidJFowler
💻

Eric Mason
💻

Peter Dave Hello
💻

Enrico Tröger
💻

WhiteBahamut
💻

Manuel Habert
💻

Nico Kaiser
💻

Chris Scholz
💻

Mohamed Sahbi
💻

scp-mb
💻

Harry
💻

Charles Bushong
💻

Capusjon
💻

Adam Beck
💻

Alice Ferrazzi
💻

Timo Pick
💻

James Stewart Miller
💻

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!


text:
import { UserScript } from "../../UserScript";
import { UiComponent } from "./UiComponent";

export class ExpandoButton extends UiComponent {
  readonly element: JQuery<HTMLElement>;

  /**
   * Constructs an expando element that is commonly used to expand and
   * collapses a section of the UI.
   *
   * @param host A reference to the host.
   */
  constructor(host: UserScript) {
    super(host);

    const element = $("<div/>", {
      title: host.engine.i18n("ui.itemsShow"),
      text: "+",
    }).addClass("ks-expando-button");

    this.element = element;
  }

  setCollapsed() {
    this.element.prop("title", this._host.engine.i18n("ui.itemsShow"));
    this.element.text("+");
  }
  setExpanded() {
    this.element.prop("title", this._host.engine.i18n("ui.itemsHide"));
    this.element.text("-");
  }
}


text:
"""Next OCW ETL tests"""
from datetime import datetime

import boto3
import pytest
import pytz

from course_catalog.conftest import OCW_NEXT_TEST_PREFIX, setup_s3_ocw_next
from course_catalog.etl.ocw_next import (
    transform_ocw_next_content_files,
    transform_resource,
)
from course_catalog.factories import ContentFileFactory
from course_catalog.models import ContentFile
from course_catalog.utils import get_s3_object_and_read, safe_load_json

pytestmark = pytest.mark.django_db
# pylint:disable=redefined-outer-name,unused-argument

def test_transform_ocw_next_content_files(settings, mocker):
    """
    Test transform_ocw_next_content_files
    """

    setup_s3_ocw_next(settings)
    s3_resource = boto3.resource("s3")
    mocker.patch(
        "course_catalog.etl.ocw_next.extract_text_metadata",
        return_value={"content": "TEXT"},
    )

    content_data = list(
        transform_ocw_next_content_files(s3_resource, OCW_NEXT_TEST_PREFIX, False)
    )

    assert len(content_data) == 4

    assert content_data[0] == {
        "content": "Pages Section",
        "content_type": "page",
        "key": "courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/pages/",
        "published": True,
        "title": "Pages",
        "content_title": "Pages",
        "url": "../courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/pages/",
    }

    assert content_data[1] == {
        "content": "Course Meeting Times Lecture",
        "content_type": "page",
        "key": "courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/pages/syllabus/",
        "published": True,
        "title": "Syllabus",
        "content_title": "Syllabus",
        "url": "../courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/pages/syllabus/",
    }

    assert content_data[2] == {
        "content": "TEXT",
        "content_type": "pdf",
        "description": "This resource contains problem set 1",
        "file_type": "application/pdf",
        "key": "courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/resource/",
        "learning_resource_types": [
            "Activity Assignments",
            "Activity Assignments with Examples",
        ],
        "published": True,
        "title": "Resource Title",
        "content_title": "Resource Title",
        "url": "../courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/resource/",
    }

    assert content_data[3] == {
        "content": "TEXT",
        "content_type": "video",
        "description": "Video Description",
        "file_type": "video/mp4",
        "key": "courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/video/",
        "learning_resource_types": ["Competition Videos"],
        "published": True,
        "title": None,
        "content_title": None,
        "url": "../courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/video/",
        "image_src": "https://img.youtube.com/vi/vKer2U5W5-s/default.jpg",
    }

@pytest.mark.parametrize("overwrite", [True, False])
@pytest.mark.parametrize("modified_after_last_import", [True, False])
def test_transform_resource_needs_text_update(
    settings, mocker, overwrite, modified_after_last_import
):
    """
    Test transform_resource
    """

    setup_s3_ocw_next(settings)
    s3_resource = boto3.resource("s3")
    mock_tika = mocker.patch(
        "course_catalog.etl.ocw_next.extract_text_metadata",
        return_value={"content": "TEXT"},
    )
    s3_resource_object = s3_resource.Object(
        settings.OCW_NEXT_LIVE_BUCKET,
        "courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/resource/data.json",
    )
    resource_json = safe_load_json(
        get_s3_object_and_read(s3_resource_object), s3_resource_object.key
    )

    ContentFileFactory.create(
        key="courses/16-01-unified-engineering-i-ii-iii-iv-fall-2005-spring-2006/resources/resource/"
    )

    if modified_after_last_import:
        ContentFile.objects.update(updated_on=datetime(2020, 12, 1, tzinfo=pytz.utc))

    content_data = transform_resource(
        s3_resource_object.key, resource_json, s3_resource, overwrite
    )

    if overwrite or modified_after_last_import:
        mock_tika.assert_called_once()

        assert content_data["content"] == "TEXT"
    else:
        mock_tika.assert_not_called()
        assert "content" not in content_data


text:
using System.Collections.Generic;

namespace Reference.Lib.DataStructures.Trees
{
    public class BinarySearchTree<T> : BinaryTree<T>
    {
        protected readonly IComparer<T> Comparer;

        public BinarySearchTree()
        {
            Comparer = Comparer<T>.Default;
        }

        public BinarySearchTree(T[] data)
            : this()
        {
            Add(data);
        }

        public override void Add(T value)
        {
            if (Root == null)
            {
                SetRoot(value);
                return;
            }

            var current = Root;
            var previous = Root;
            var lastWasLeftPath = false;

            while (current != null)
            {
                var res = Comparer.Compare(value, current.Value);

                previous = current;

                lastWasLeftPath = res <= 0;

                current = lastWasLeftPath
                    ? current.Left
                    : current.Right;
            }

            if (lastWasLeftPath)
                SetAsLeftChild(previous, value);
            else
                SetAsRightChild(previous, value);
        }
    }
}


text:
package com.smash.smash.Helpers;

import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.Query;

public abstract class FirebaseListAdapter<T> extends BaseAdapter {

    private final Class<T> mModelClass;
    protected int mLayout;
    protected Activity mActivity;
    FirebaseArray mSnapshots;

    public FirebaseListAdapter(Activity activity, Class<T> modelClass, int modelLayout, Query ref) {
        mModelClass = modelClass;
        mLayout = modelLayout;
        mActivity = activity;
        mSnapshots = new FirebaseArray(ref);
        mSnapshots.setOnChangedListener(new FirebaseArray.OnChangedListener() {
				@Override
				public void onChanged(EventType type, int index, int oldIndex) {
					notifyDataSetChanged();
				}

				@Override
				public void onCancelled(DatabaseError databaseError) {
					FirebaseListAdapter.this.onCancelled(databaseError);
				}
			});
    }

	public FirebaseListAdapter(Activity activity, Class<T> modelClass, int modelLayout, DatabaseReference ref) {
        this(activity, modelClass, modelLayout, (Query) ref);
    }

    public void cleanup() {
        // We're being destroyed, let go of our mListener and forget about all of the mModels
        mSnapshots.cleanup();
    }

    @Override
    public int getCount() {
        return mSnapshots.getCount();
    }

    @Override
    public T getItem(int position) {
        return parseSnapshot(mSnapshots.getItem(position));
    }

    protected T parseSnapshot(DataSnapshot snapshot) {
        return snapshot.getValue(mModelClass);
    }

    public DatabaseReference getRef(int position) { return mSnapshots.getItem(position).getRef(); }

    @Override
    public long getItemId(int i) {
        // http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter
        return mSnapshots.getItem(i).getKey().hashCode();
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        if (view == null) {
            view = mActivity.getLayoutInflater().inflate(mLayout, viewGroup, false);
        }

        T model = getItem(position);

        // Call out to subclass to marshall this model into the provided view
        populateView(view, model, position);
        return view;
    }

    protected void onCancelled(DatabaseError databaseError) {
        Log.w("FirebaseListAdapter", databaseError.toException());
    }

    abstract protected void populateView(View v, T model, int position);
}


text:
PYTHON=poetry run

.PHONY: format
format:
	$(PYTHON) black immutabledict tests
	$(PYTHON) ruff --fix immutabledict tests

.PHONY: style
style:
	$(PYTHON) black --check immutabledict tests
	$(PYTHON) ruff immutabledict tests
	$(PYTHON) mypy -- immutabledict

.PHONY: test
test:
	$(PYTHON) pytest tests --cov=immutabledict --cov-report=xml


text:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by org.testng.reporters.JUnitXMLReporter -->
<testsuite hostname="shishkina" name="Test1" tests="1" failures="0" timestamp="11 Aug 2015 15:39:58 GMT" time="12.48" errors="0">
  <testcase name="testLoginMD" time="7.916" classname="ru.st.selenium.loginMD"/>
</testsuite> <!-- Test1 -->