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

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

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

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

    var NOW_TIME = 100;

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

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

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

    test('time and timeEnd', function() {
      var 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', 3.123
      ));
      assert.isTrue(element.reporter.calledWithExactly(
          'timing-report', 'UI Latency', 'bar', 1
      ));
    });

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

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

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

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

      test('reports cached events preserving order', function() {
        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', function() {
      var pathnameStub;
      setup(function() {
        pathnameStub = sinon.stub(element, '_getPathname');
      });

      teardown(function() {
        pathnameStub.restore();
      });

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

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

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

      test('diff view', function() {
        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', function() {
      var fakeWindow;
      var reporter;

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

      setup(function() {
        reporter = sandbox.stub(GrReporting.prototype, 'reporter');
        fakeWindow = {};
        sandbox.stub(console, 'error');
        window.GrReporting._catchErrors(fakeWindow);
      });

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

      test('prevent default event handler', function() {
        assert.isTrue(emulateThrow());
      });
    });
  });
</script>
