<!doctype html>
<meta charset="utf-8">
<title>
  IndexedDB: scoping for database / object store / index names, and index keys
</title>
<link rel="help" href="https://w3c.github.io/IndexedDB/#constructs">
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support-promises.js"></script>
<script>
'use strict';

// Creates the structure inside a test database.
//
// The structure includes two stores with identical indexes and nearly-similar
// records. The records differ in the "path" attribute values, which are used to
// verify that IndexedDB returns the correct records when queried.
//
// databaseName appears redundant, but we don't want to rely on database.name.
const buildStores = (database, databaseName, useUniqueKeys) => {
  for (let storeName of ['x', 'y']) {
    const store = database.createObjectStore(
        storeName, { keyPath: 'pKey', autoIncrement: true });
    for (let indexName of ['x', 'y']) {
      store.createIndex(
          indexName, `${indexName}Key`, { unique: useUniqueKeys });
    }

    for (let xKeyRoot of ['x', 'y']) {
      for (let yKeyRoot of ['x', 'y']) {
        let xKey, yKey;
        if (useUniqueKeys) {
          xKey = `${xKeyRoot}${yKeyRoot}`;
          yKey = `${yKeyRoot}${xKeyRoot}`;
        } else {
          xKey = xKeyRoot;
          yKey = yKeyRoot;
        }
        const path = `${databaseName}-${storeName}-${xKeyRoot}-${yKeyRoot}`;
        store.put({ xKey: xKey, yKey: yKey, path: path });
      }
    }
  }
};

// Creates two databases with identical structures.
const buildDatabases = (testCase, useUniqueKeys) => {
  return createNamedDatabase(
      testCase, 'x', database => buildStores(database, 'x', useUniqueKeys))
      .then(database => database.close())
      .then(() => createNamedDatabase(
          testCase, 'y', database => buildStores(database, 'y', useUniqueKeys)))
      .then(database => database.close());
};

// Reads all the store's values using an index.
//
// Returns a Promise that resolves with an array of values.
const readIndex = (testCase, index) => {
  return new Promise((resolve, reject) => {
    const results = [];
    const request = index.openCursor(IDBKeyRange.bound('a', 'z'), 'next');
    request.onsuccess = () => {
      const cursor = request.result;
      if (cursor) {
        results.push(cursor.value);
        cursor.continue();
      } else {
        resolve(results);
      }
    }
  });
}

// Verifies that a database contains the expected records.
const checkDatabaseContent =
    (testCase, database, databaseName, usedUniqueKeys) => {
  const promises = [];
  const transaction = database.transaction(['x', 'y'], 'readonly');
  for (let storeName of ['x', 'y']) {
    const store = transaction.objectStore(storeName);
    for (let indexName of ['x', 'y']) {
      const index = store.index(indexName);

      const promise = readIndex(testCase, index).then((results) => {
        assert_array_equals(
            results.map(result => `${result.path}:${result.pKey}`).sort(),
            [`${databaseName}-${storeName}-x-x:1`,
             `${databaseName}-${storeName}-x-y:2`,
             `${databaseName}-${storeName}-y-x:3`,
             `${databaseName}-${storeName}-y-y:4`],
            'The results should include all records put into the store');

        let expectedKeys = (usedUniqueKeys) ?
            ['xx:xx', 'xy:yx', 'yx:xy', 'yy:yy'] : ['x:x', 'x:y', 'y:x', 'y:y'];
        assert_array_equals(
            results.map(result => `${result.xKey}:${result.yKey}`).sort(),
            expectedKeys,
            'The results should include all the index keys put in the store');

        assert_array_equals(
            results.map(result => result[`${indexName}Key`]),
            results.map(result => result[`${indexName}Key`]).sort(),
            'The results should be sorted by the index key');
      });
      promises.push(promise);
    }
  }

  return Promise.all(promises).then(() => database);
}

promise_test(testCase => {
  return buildDatabases(testCase, false)
      .then(() => openNamedDatabase(testCase, 'x', 1))
      .then(database => checkDatabaseContent(testCase, database, 'x', false))
      .then(database => database.close())
      .then(() => openNamedDatabase(testCase, 'y', 1))
      .then(database => checkDatabaseContent(testCase, database, 'y', false))
      .then(database => database.close());
}, 'Non-unique index keys');

promise_test(testCase => {
  return buildDatabases(testCase, true)
      .then(() => openNamedDatabase(testCase, 'x', 1))
      .then(database => checkDatabaseContent(testCase, database, 'x', true))
      .then(database => database.close())
      .then(() => openNamedDatabase(testCase, 'y', 1))
      .then(database => checkDatabaseContent(testCase, database, 'y', true))
      .then(database => database.close());
}, 'Unique index keys');

</script>
