<!DOCTYPE html>
<!--
Copyright (C) 2016 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-storage</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-storage.html">

<script>void(0);</script>

<test-fixture id="basic">
  <template>
    <gr-storage></gr-storage>
  </template>
</test-fixture>

<script>
  suite('gr-storage tests', () => {
    let element;

    function mockStorage(opt_quotaExceeded) {
      return {
        getItem(key) { return this[key]; },
        removeItem(key) { delete this[key]; },
        setItem(key, value) {
          // eslint-disable-next-line no-throw-literal
          if (opt_quotaExceeded) { throw {code: 22}; /* Quota exceeded */ }
          this[key] = value;
        },
      };
    }

    setup(() => {
      element = fixture('basic');
      element._storage = mockStorage();
    });

    test('storing, retrieving and erasing drafts', () => {
      const changeNum = 1234;
      const patchNum = 5;
      const path = 'my_source_file.js';
      const line = 123;
      const location = {
        changeNum,
        patchNum,
        path,
        line,
      };

      // The key is in the expected format.
      const key = element._getDraftKey(location);
      assert.equal(key, ['draft', changeNum, patchNum, path, line].join(':'));

      // There should be no draft initially.
      const draft = element.getDraftComment(location);
      assert.isNotOk(draft);

      // Setting the draft stores it under the expected key.
      element.setDraftComment(location, 'my comment');
      assert.isOk(element._storage.getItem(key));
      assert.equal(JSON.parse(element._storage.getItem(key)).message,
          'my comment');
      assert.isOk(JSON.parse(element._storage.getItem(key)).updated);

      // Erasing the draft removes the key.
      element.eraseDraftComment(location);
      assert.isNotOk(element._storage.getItem(key));
    });

    test('automatically removes old drafts', () => {
      const changeNum = 1234;
      const patchNum = 5;
      const path = 'my_source_file.js';
      const line = 123;
      const location = {
        changeNum,
        patchNum,
        path,
        line,
      };

      const key = element._getDraftKey(location);

      // Make sure that the call to cleanup doesn't get throttled.
      element._lastCleanup = 0;

      const cleanupSpy = sinon.spy(element, '_cleanupDrafts');

      // Create a message with a timestamp that is a second behind the max age.
      element._storage.setItem(key, JSON.stringify({
        message: 'old message',
        updated: Date.now() - 24 * 60 * 60 * 1000 - 1000,
      }));

      // Getting the draft should cause it to be removed.
      const draft = element.getDraftComment(location);

      assert.isTrue(cleanupSpy.called);
      assert.isNotOk(draft);
      assert.isNotOk(element._storage.getItem(key));

      cleanupSpy.restore();
    });

    test('_getDraftKey', () => {
      const changeNum = 1234;
      const patchNum = 5;
      const path = 'my_source_file.js';
      const line = 123;
      const location = {
        changeNum,
        patchNum,
        path,
        line,
      };
      let expectedResult = 'draft:1234:5:my_source_file.js:123';
      assert.equal(element._getDraftKey(location), expectedResult);
      location.range = {
        start_character: 1,
        start_line: 1,
        end_character: 1,
        end_line: 2,
      };
      expectedResult = 'draft:1234:5:my_source_file.js:123:1-1-1-2';
      assert.equal(element._getDraftKey(location), expectedResult);
    });

    test('exceeded quota disables storage', () => {
      element._storage = mockStorage(true);
      assert.isFalse(element._exceededQuota);

      const changeNum = 1234;
      const patchNum = 5;
      const path = 'my_source_file.js';
      const line = 123;
      const location = {
        changeNum,
        patchNum,
        path,
        line,
      };
      const key = element._getDraftKey(location);
      element.setDraftComment(location, 'my comment');
      assert.isTrue(element._exceededQuota);
      assert.isNotOk(element._storage.getItem(key));
    });
  });
</script>
