<!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', function() {
    var element;

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

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

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

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

      // There should be no draft initially.
      var 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', function() {
      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };

      var key = element._getDraftKey(location);

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

      var 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.
      var draft = element.getDraftComment(location);

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

      cleanupSpy.restore();
    });

    test('_getDraftKey', function() {
      var changeNum = 1234;
      var patchNum = 5;
      var path = 'my_source_file.js';
      var line = 123;
      var location = {
        changeNum: changeNum,
        patchNum: patchNum,
        path: path,
        line: line,
      };
      var 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', function() {
      element._storage = mockStorage(true);
      assert.isFalse(element._exceededQuota);

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