<!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.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>

<link rel="import" href="gr-storage.html">

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

<script>
  suite('gr-storage tests', function() {
    var element;
    var storage;

    function cleanupStorage() {
      // Make sure there are no entries in storage.
      for (var key in window.localStorage) {
        window.localStorage.removeItem(key);
      }
    }

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

    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(storage.getItem(key));
      assert.equal(JSON.parse(storage.getItem(key)).message, 'my comment');
      assert.isOk(JSON.parse(storage.getItem(key)).updated);

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

      cleanupStorage();
    });


    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.
      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(storage.getItem(key));

      cleanupSpy.restore();
      cleanupStorage();
    });

    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);
    });
  });
</script>
