<!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="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>
