chromium/third_party/google-closure-library/closure/goog/format/internationalizedemailaddress_test.js

/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

goog.module('goog.format.InternationalizedEmailAddressTest');
goog.setTestOnly();

const InternationalizedEmailAddress = goog.require('goog.format.InternationalizedEmailAddress');
const testSuite = goog.require('goog.testing.testSuite');

/**
 * Asserts that the given validation function generates the expected outcome for
 * a set of expected valid and a second set of expected invalid addresses.
 * containing the specified address strings, irrespective of their order.
 * @param {function(string):boolean} testFunc Validation function to be tested.
 * @param {!Array<string>} valid List of addresses that should be valid.
 * @param {!Array<string>} invalid List of addresses that should be invalid.
 * @private
 */
function doIsValidTest(testFunc, valid, invalid) {
  valid.forEach(str => {
    assertTrue(`"${str}" should be valid.`, testFunc(str));
  });
  invalid.forEach(str => {
    assertFalse(`"${str}" should be invalid.`, testFunc(str));
  });
}

/**
 * Asserts that parsing the inputString produces a list of email addresses
 * containing the specified address strings, irrespective of their order.
 * @param {string} inputString A raw address list.
 * @param {!Array<string>} expectedList The expected results.
 * @param {string=} opt_message An assertion message.
 * @return {string} the resulting email address objects.
 * @suppress {checkTypes} suppression added to enable type checking
 */
function assertParsedList(inputString, expectedList, opt_message) {
  const message = opt_message || 'Should parse address correctly';
  const result = InternationalizedEmailAddress.parseList(inputString);
  assertEquals(
      'Should have correct # of addresses', expectedList.length, result.length);
  for (let i = 0; i < expectedList.length; ++i) {
    assertEquals(message, expectedList[i], result[i].getAddress());
  }
  return result;
}

testSuite({
  testParseList() {
    // Test only the new cases added by EAI (other cases covered in parent
    // class test)
    assertParsedList(
        '<me.みんあ@me.xn--l8jtg9b>', ['me.みんあ@me.xn--l8jtg9b']);
  },

  testIsEaiValid() {
    const valid = [
      '[email protected]',
      '<[email protected]>',
      'eric <[email protected]>',
      '"e" <[email protected]>',
      '[email protected]',
      '[email protected]',
      '[email protected]',
      'o\'[email protected]',
      '[email protected]',
      '!/#$%&\'*+-=~|`{}?^[email protected]',
      '[email protected]',
      'み.ん-あ@みんあ.みんあ',
      'みんあ@test.com',
      'test@test.みんあ',
      'test@みんあ.com',
      'me.みんあ@me.xn--l8jtg9b',
      'みんあ@me.xn--l8jtg9b',
      'fullwidthfullstop@sld' +
          '\uff0e' +
          'tld',
      'ideographicfullstop@sld' +
          '\u3002' +
          'tld',
      'halfwidthideographicfullstop@sld' +
          '\uff61' +
          'tld',
    ];
    const invalid = [
      null,
      undefined,
      'e',
      '',
      'e @c.com',
      'a@b',
      'foo.com',
      '[email protected]',
      'test@gma=il.com',
      'aaa@gmail',
      'has some [email protected]',
      'has@three@[email protected]',
      '@no-local-part.com',
    ];
    doIsValidTest(InternationalizedEmailAddress.isValidAddress, valid, invalid);
  },

  testIsValidLocalPart() {
    const valid = [
      'e',
      'a.b+foo',
      'o\'hara',
      'user+someone',
      '!/#$%&\'*+-=~|`{}?^_',
      'confirm-bhk=modulo.org',
      'me.みんあ',
      'みんあ',
    ];
    const invalid = [
      null,
      undefined,
      'A@b@c',
      'a"b(c)d,e:f;g<h>i[j\\k]l',
      'just"not"right',
      'this is"not\\allowed',
      'this\\ still\"not\\\\allowed',
      'has some spaces',
    ];
    doIsValidTest(
        InternationalizedEmailAddress.isValidLocalPartSpec, valid, invalid);
  },

  testIsValidDomainPart() {
    const valid = [
      'example.com',
      'dept.example.org',
      'long.domain.with.lots.of.dots',
      'me.xn--l8jtg9b',
      'me.みんあ',
      'sld.looooooongtld',
      'sld' +
          '\uff0e' +
          'tld',
      'sld' +
          '\u3002' +
          'tld',
      'sld' +
          '\uff61' +
          'tld',
    ];
    const invalid = [
      null,
      undefined,
      '',
      '@has.an.at.sign',
      '..has.leading.dots',
      'gma=il.com',
      'DoesNotHaveADot',
      'aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffffffffffgggggggggg',
    ];
    doIsValidTest(
        InternationalizedEmailAddress.isValidDomainPartSpec, valid, invalid);
  },

  testparseListWithAdditionalSeparators() {
    assertParsedList(
        '<[email protected]>\u055D <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+055D');
    assertParsedList(
        '<[email protected]>\u055D <[email protected]>\u055D',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+055D');

    assertParsedList(
        '<[email protected]>\u060C <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+060C');
    assertParsedList(
        '<[email protected]>\u060C <[email protected]>\u060C',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+060C');

    assertParsedList(
        '<[email protected]>\u1363 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+1363');
    assertParsedList(
        '<[email protected]>\u1363 <[email protected]>\u1363',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+1363');

    assertParsedList(
        '<[email protected]>\u1802 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+1802');
    assertParsedList(
        '<[email protected]>\u1802 <[email protected]>\u1802',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+1802');

    assertParsedList(
        '<[email protected]>\u1808 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+1808');
    assertParsedList(
        '<[email protected]>\u1808 <[email protected]>\u1808',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+1808');

    assertParsedList(
        '<[email protected]>\u2E41 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+2E41');
    assertParsedList(
        '<[email protected]>\u2E41 <[email protected]>\u2E41',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+2E41');

    assertParsedList(
        '<[email protected]>\u3001 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+3001');
    assertParsedList(
        '<[email protected]>\u3001 <[email protected]>\u3001',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+3001');

    assertParsedList(
        '<[email protected]>\uFF0C <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+FF0C');
    assertParsedList(
        '<[email protected]>\uFF0C <[email protected]>\uFF0C',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+FF0C');

    assertParsedList(
        '<[email protected]>\u0613 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+0613');
    assertParsedList(
        '<[email protected]>\u0613 <[email protected]>\u0613',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+0613');

    assertParsedList(
        '<[email protected]>\u1364 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+1364');
    assertParsedList(
        '<[email protected]>\u1364 <[email protected]>\u1364',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+1364');

    assertParsedList(
        '<[email protected]>\uFF1B <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+FF1B');
    assertParsedList(
        '<[email protected]>\uFF1B <[email protected]>\uFF1B',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+FF1B');

    assertParsedList(
        '<[email protected]>\uFF64 <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+FF64');
    assertParsedList(
        '<[email protected]>\uFF64 <[email protected]>\uFF64',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+FF64');

    assertParsedList(
        '<[email protected]>\u104A <[email protected]>',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with U+104A');
    assertParsedList(
        '<[email protected]>\u104A <[email protected]>\u104A',
        ['[email protected]', '[email protected]'],
        'Failed to parse 2 email addresses with trailing U+104A');
  },

  testToString() {
    const f = (str) => InternationalizedEmailAddress.parse(str).toString();

    // No modification.
    assertEquals('JOHN Doe <[email protected]>', f('JOHN Doe <[email protected]>'));

    // Extra spaces.
    assertEquals(
        'JOHN Doe <[email protected]>', f(' JOHN  Doe  <[email protected]> '));

    // No name.
    assertEquals('[email protected]', f('<[email protected]>'));
    assertEquals('[email protected]', f('[email protected]'));

    // No address.
    assertEquals('JOHN Doe', f('JOHN Doe <>'));

    // Already quoted.
    assertEquals(
        '"JOHN, Doe" <[email protected]>', f('"JOHN, Doe" <[email protected]>'));

    // Needless quotes.
    assertEquals('JOHN Doe <[email protected]>', f('"JOHN Doe" <[email protected]>'));
    // Not quoted-string, but has double quotes.
    assertEquals(
        '"JOHN, Doe" <[email protected]>', f('JOHN, "Doe" <[email protected]>'));

    // No special characters other than quotes.
    assertEquals('JOHN Doe <[email protected]>', f('JOHN "Doe" <[email protected]>'));

    // Escaped quotes are also removed.
    assertEquals(
        '"JOHN, Doe" <[email protected]>', f('JOHN, \\"Doe\\" <[email protected]>'));

    // Characters that require quoting for the display name.
    assertEquals(
        '"JOHN, Doe" <[email protected]>', f('JOHN, Doe <[email protected]>'));
    assertEquals(
        '"JOHN; Doe" <[email protected]>', f('JOHN; Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u055D Doe" <[email protected]>',
        f('JOHN\u055D Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u060C Doe" <[email protected]>',
        f('JOHN\u060C Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u1363 Doe" <[email protected]>',
        f('JOHN\u1363 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u1802 Doe" <[email protected]>',
        f('JOHN\u1802 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u1808 Doe" <[email protected]>',
        f('JOHN\u1808 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u2E41 Doe" <[email protected]>',
        f('JOHN\u2E41 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u3001 Doe" <[email protected]>',
        f('JOHN\u3001 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\uFF0C Doe" <[email protected]>',
        f('JOHN\uFF0C Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u061B Doe" <[email protected]>',
        f('JOHN\u061B Doe <[email protected]>'));
    assertEquals(
        '"JOHN\u1364 Doe" <[email protected]>',
        f('JOHN\u1364 Doe <[email protected]>'));
    assertEquals(
        '"JOHN\uFF1B Doe" <[email protected]>',
        f('JOHN\uFF1B Doe <[email protected]>'));
    assertEquals(
        '"JOHN\uFF64 Doe" <[email protected]>',
        f('JOHN\uFF64 Doe <[email protected]>'));
    assertEquals(
        '"JOHN(Johnny) Doe" <[email protected]>',
        f('JOHN(Johnny) Doe <[email protected]>'));
    assertEquals(
        '"JOHN[Johnny] Doe" <[email protected]>',
        f('JOHN[Johnny] Doe <[email protected]>'));
    assertEquals(
        '"JOHN@work Doe" <[email protected]>',
        f('JOHN@work Doe <[email protected]>'));
    assertEquals(
        '"JOHN:theking Doe" <[email protected]>',
        f('JOHN:theking Doe <[email protected]>'));
    assertEquals(
        '"JOHN\\\\ Doe" <[email protected]>', f('JOHN\\ Doe <[email protected]>'));
    assertEquals(
        '"JOHN.com Doe" <[email protected]>', f('JOHN.com Doe <[email protected]>'));
  },
});