<!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-reporting</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-reporting.html">

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

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

<script>
  suite('gr-reporting tests', () => {
    let element;
    let sandbox;
    let clock;
    let fakePerformance;

    const NOW_TIME = 100;

    setup(() => {
      sandbox = sinon.sandbox.create();
      clock = sinon.useFakeTimers(NOW_TIME);
      element = fixture('basic');
      fakePerformance = {
        navigationStart: 1,
        loadEventEnd: 2,
      };
      sinon.stub(element, 'performanceTiming',
          {get() { return fakePerformance; }});
      sandbox.stub(element, 'reporter');
    });
    teardown(() => {
      sandbox.restore();
      clock.restore();
    });

    test('appStarted', () => {
      element.appStarted();
      assert.isTrue(
          element.reporter.calledWithExactly(
              'timing-report', 'UI Latency', 'App Started',
              NOW_TIME - fakePerformance.navigationStart
      ));
    });

    test('pageLoaded', () => {
      element.pageLoaded();
      assert.isTrue(
          element.reporter.calledWithExactly(
              'timing-report', 'UI Latency', 'Page Loaded',
              fakePerformance.loadEventEnd - fakePerformance.navigationStart)
      );
    });

    test('time and timeEnd', () => {
      const nowStub = sandbox.stub(element, 'now').returns(0);
      element.time('foo');
      nowStub.returns(1);
      element.time('bar');
      nowStub.returns(2);
      element.timeEnd('bar');
      nowStub.returns(3.123);
      element.timeEnd('foo');
      assert.isTrue(element.reporter.calledWithExactly(
          'timing-report', 'UI Latency', 'foo', '3ms'
      ));
      assert.isTrue(element.reporter.calledWithExactly(
          'timing-report', 'UI Latency', 'bar', '1ms'
      ));
    });

    suite('plugins', () => {
      setup(() => {
        element.reporter.restore();
        sandbox.stub(element, 'defaultReporter');
        sandbox.stub(Gerrit, '_arePluginsLoaded');
      });

      test('pluginsLoaded reports time', () => {
        Gerrit._arePluginsLoaded.returns(true);
        sandbox.stub(element, 'now').returns(42);
        element.pluginsLoaded();
        assert.isTrue(element.defaultReporter.calledWithExactly(
            'timing-report', 'UI Latency', 'PluginsLoaded', '42ms'
        ));
      });

      test('caches reports if plugins are not loaded', () => {
        Gerrit._arePluginsLoaded.returns(false);
        element.timeEnd('foo');
        assert.isFalse(element.defaultReporter.called);
      });

      test('reports if plugins are loaded', () => {
        Gerrit._arePluginsLoaded.returns(true);
        element.timeEnd('foo');
        assert.isTrue(element.defaultReporter.called);
      });

      test('reports cached events preserving order', () => {
        Gerrit._arePluginsLoaded.returns(false);
        element.timeEnd('foo');
        Gerrit._arePluginsLoaded.returns(true);
        element.timeEnd('bar');
        assert.isTrue(element.defaultReporter.firstCall.calledWith(
            'timing-report', 'UI Latency', 'foo'
        ));
        assert.isTrue(element.defaultReporter.secondCall.calledWith(
            'timing-report', 'UI Latency', 'bar'
        ));
      });
    });

    suite('location changed', () => {
      let pathnameStub;
      setup(() => {
        pathnameStub = sinon.stub(element, '_getPathname');
      });

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

      test('search', () => {
        pathnameStub.returns('/q/foo');
        element.locationChanged();
        assert.isTrue(element.reporter.calledWithExactly(
            'nav-report', 'Location Changed', 'Page', '/q/'));
      });

      test('change view', () => {
        pathnameStub.returns('/c/42/');
        element.locationChanged();
        assert.isTrue(element.reporter.calledWithExactly(
            'nav-report', 'Location Changed', 'Page', '/c/'));
      });

      test('change view', () => {
        pathnameStub.returns('/c/41/2');
        element.locationChanged();
        assert.isTrue(element.reporter.calledWithExactly(
            'nav-report', 'Location Changed', 'Page', '/c/'));
      });

      test('diff view', () => {
        pathnameStub.returns('/c/41/2/file.txt');
        element.locationChanged();
        assert.isTrue(element.reporter.calledWithExactly(
            'nav-report', 'Location Changed', 'Page', '/c//COMMIT_MSG'));
      });
    });

    suite('exception logging', () => {
      let fakeWindow;
      let reporter;

      const emulateThrow = function(msg, url, line, column, error) {
        return fakeWindow.onerror(msg, url, line, column, error);
      };

      setup(() => {
        reporter = sandbox.stub(GrReporting.prototype, 'reporter');
        fakeWindow = {
          handlers: {},
          addEventListener(type, handler) {
            this.handlers[type] = handler;
          },
        };
        sandbox.stub(console, 'error');
        window.GrReporting._catchErrors(fakeWindow);
      });

      test('is reported', () => {
        const error = new Error('bar');
        emulateThrow('bar', 'http://url', 4, 2, error);
        assert.isTrue(reporter.calledWith('error', 'exception', 'bar'));
        const payload = reporter.lastCall.args[3];
        assert.deepEqual(payload, {
          url: 'http://url',
          line: 4,
          column: 2,
          error,
        });
      });

      test('prevent default event handler', () => {
        assert.isTrue(emulateThrow());
      });

      test('unhandled rejection', () => {
        fakeWindow.handlers['unhandledrejection']({
          reason: {
            message: 'bar',
          },
        });
        assert.isTrue(reporter.calledWith('error', 'exception', 'bar'));
      });
    });
  });
</script>
