<!DOCTYPE html>
<!--
@license
Copyright (C) 2015 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-date-formatter</title>

<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>

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

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

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

<test-fixture id="basic">
  <template>
    <gr-date-formatter date-str="2015-09-24 23:30:17.033000000"></gr-date-formatter>
  </template>
</test-fixture>

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

    setup(() => {
      sandbox = sinon.sandbox.create();
    });

    teardown(() => {
      sandbox.restore();
    });

    /**
     * Parse server-formatter date and normalize into current timezone.
     */
    function normalizedDate(dateStr) {
      const d = util.parseDate(dateStr);
      d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
      return d;
    }

    function testDates(nowStr, dateStr, expected, expectedWithDateAndTime,
        expectedTooltip, done) {
      // Normalize and convert the date to mimic server response.
      dateStr = normalizedDate(dateStr)
          .toJSON().replace('T', ' ').slice(0, -1);
      sandbox.useFakeTimers(normalizedDate(nowStr).getTime());
      element.dateStr = dateStr;
      flush(() => {
        const span = element.$$('span');
        assert.equal(span.textContent.trim(), expected);
        assert.equal(element.title, expectedTooltip);
        element.showDateAndTime = true;
        flushAsynchronousOperations();
        assert.equal(span.textContent.trim(), expectedWithDateAndTime);
        done();
      });
    }

    function stubRestAPI(preferences) {
      const loggedInPromise = Promise.resolve(preferences !== null);
      const preferencesPromise = Promise.resolve(preferences);
      stub('gr-rest-api-interface', {
        getLoggedIn: sinon.stub().returns(loggedInPromise),
        getPreferences: sinon.stub().returns(preferencesPromise),
      });
      return Promise.all([loggedInPromise, preferencesPromise]);
    }

    suite('24 hours time format preference', () => {
      setup(() => {
        return stubRestAPI(
            {time_format: 'HHMM_24', relative_date_in_change_table: false}
        ).then(() => {
          element = fixture('basic');
          sandbox.stub(element, '_getUtcOffsetString').returns('');
          return element._loadPreferences();
        });
      });

      test('invalid dates are quietly rejected', () => {
        assert.notOk((new Date('foo')).valueOf());
        assert.equal(element._computeDateStr('foo', 'h:mm A'), '');
      });

      test('Within 24 hours on same day', done => {
        testDates('2015-07-29 20:34:14.985000000',
            '2015-07-29 15:34:14.985000000',
            '15:34',
            '15:34',
            'Jul 29, 2015, 15:34:14', done);
      });

      test('Within 24 hours on different days', done => {
        testDates('2015-07-29 03:34:14.985000000',
            '2015-07-28 20:25:14.985000000',
            'Jul 28',
            'Jul 28 20:25',
            'Jul 28, 2015, 20:25:14', done);
      });

      test('More than 24 hours but less than six months', done => {
        testDates('2015-07-29 20:34:14.985000000',
            '2015-06-15 03:25:14.985000000',
            'Jun 15',
            'Jun 15 03:25',
            'Jun 15, 2015, 03:25:14', done);
      });

      test('More than six months', done => {
        testDates('2015-09-15 20:34:00.000000000',
            '2015-01-15 03:25:00.000000000',
            'Jan 15, 2015',
            'Jan 15, 2015 03:25',
            'Jan 15, 2015, 03:25:00', done);
      });
    });

    suite('12 hours time format preference', () => {
      setup(() => {
        // relative_date_in_change_table is not set when false.
        return stubRestAPI(
            {time_format: 'HHMM_12'}
        ).then(() => {
          element = fixture('basic');
          sandbox.stub(element, '_getUtcOffsetString').returns('');
          return element._loadPreferences();
        });
      });

      test('Within 24 hours on same day', done => {
        testDates('2015-07-29 20:34:14.985000000',
            '2015-07-29 15:34:14.985000000',
            '3:34 PM',
            '3:34 PM',
            'Jul 29, 2015, 3:34:14 PM', done);
      });
    });

    suite('relative date preference', () => {
      setup(() => {
        return stubRestAPI(
            {time_format: 'HHMM_12', relative_date_in_change_table: true}
        ).then(() => {
          element = fixture('basic');
          sandbox.stub(element, '_getUtcOffsetString').returns('');
          return element._loadPreferences();
        });
      });

      test('Within 24 hours on same day', done => {
        testDates('2015-07-29 20:34:14.985000000',
            '2015-07-29 15:34:14.985000000',
            '5 hours ago',
            '5 hours ago',
            'Jul 29, 2015, 3:34:14 PM', done);
      });

      test('More than six months', done => {
        testDates('2015-09-15 20:34:00.000000000',
            '2015-01-15 03:25:00.000000000',
            '8 months ago',
            '8 months ago',
            'Jan 15, 2015, 3:25:00 AM', done);
      });
    });

    suite('logged in', () => {
      setup(() => {
        return stubRestAPI(
            {time_format: 'HHMM_12', relative_date_in_change_table: true}
        ).then(() => {
          element = fixture('basic');
          return element._loadPreferences();
        });
      });

      test('Preferences are respected', () => {
        assert.equal(element._timeFormat, 'h:mm A');
        assert.isTrue(element._relative);
      });
    });

    suite('logged out', () => {
      setup(() => {
        return stubRestAPI(null).then(() => {
          element = fixture('basic');
          return element._loadPreferences();
        });
      });

      test('Default preferences are respected', () => {
        assert.equal(element._timeFormat, 'HH:mm');
        assert.isFalse(element._relative);
      });
    });
  });
</script>
