<!DOCTYPE html>
<!--
@license
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-error-manager</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" />
<link rel="import" href="gr-error-manager.html">

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

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

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

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

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

    suite('when authed', () => {
      setup(() => {
        sandbox.stub(window, 'fetch')
            .returns(Promise.resolve({ok: true, status: 204}));
        element = fixture('basic');
      });

      test('does not show auth error on 403 by default', done => {
        const showAuthErrorStub = sandbox.stub(element, '_showAuthErrorAlert');
        const responseText = Promise.resolve('server says no.');
        element.fire('server-error',
            {response: {status: 403, text() { return responseText; }}}
        );
        flush(() => {
          assert.isFalse(showAuthErrorStub.calledOnce);
          done();
        });
      });

      test('show auth required for 403 with auth error and not authed before',
          done => {
            const showAuthErrorStub = sandbox.stub(
                element, '_showAuthErrorAlert'
            );
            const responseText = Promise.resolve('Authentication required\n');
            sinon.stub(element.$.restAPI, 'getLoggedIn')
                .returns(Promise.resolve(true));
            element.fire('server-error',
                {response: {status: 403, text() { return responseText; }}}
            );
            flush(() => {
              assert.isTrue(showAuthErrorStub.calledOnce);
              done();
            });
          });

      test('recheck auth for 403 with auth error if authed before', done => {
        // starts with authed state
        element.$.restAPI.getLoggedIn();
        const responseText = Promise.resolve('Authentication required\n');
        sinon.stub(element.$.restAPI, 'getLoggedIn')
            .returns(Promise.resolve(true));
        element.fire('server-error',
            {response: {status: 403, text() { return responseText; }}}
        );
        flush(() => {
          assert.isTrue(element.$.restAPI.getLoggedIn.calledOnce);
          done();
        });
      });

      test('show logged in error', () => {
        sandbox.stub(element, '_showAuthErrorAlert');
        element.fire('show-auth-required');
        assert.isTrue(element._showAuthErrorAlert.calledWithExactly(
            'Log in is required to perform that action.', 'Log in.'));
      });

      test('show normal Error', done => {
        const showErrorStub = sandbox.stub(element, '_showErrorDialog');
        const textSpy = sandbox.spy(() => Promise.resolve('ZOMG'));
        element.fire('server-error', {response: {status: 500, text: textSpy}});

        assert.isTrue(textSpy.called);
        flush(() => {
          assert.isTrue(showErrorStub.calledOnce);
          assert.isTrue(showErrorStub.lastCall.calledWithExactly(
              'Error 500: ZOMG'));
          done();
        });
      });

      test('_constructServerErrorMsg', () => {
        const errorText = 'change conflicts';
        const status = 409;
        const statusText = 'Conflict';
        const url = '/my/test/url';

        assert.equal(element._constructServerErrorMsg({status}),
            'Error 409');
        assert.equal(element._constructServerErrorMsg({status, url}),
            'Error 409: \nEndpoint: /my/test/url');
        assert.equal(element.
            _constructServerErrorMsg({status, statusText, url}),
        'Error 409 (Conflict): \nEndpoint: /my/test/url');
        assert.equal(element._constructServerErrorMsg({
          status,
          statusText,
          errorText,
          url,
        }), 'Error 409 (Conflict): change conflicts' +
        '\nEndpoint: /my/test/url');
      });

      test('suppress TOO_MANY_FILES error', done => {
        const showAlertStub = sandbox.stub(element, '_showAlert');
        const textSpy = sandbox.spy(
            () => Promise.resolve('too many files to find conflicts')
        );
        element.fire('server-error', {response: {status: 500, text: textSpy}});

        assert.isTrue(textSpy.called);
        flush(() => {
          assert.isFalse(showAlertStub.called);
          done();
        });
      });

      test('show network error', done => {
        const consoleErrorStub = sandbox.stub(console, 'error');
        const showAlertStub = sandbox.stub(element, '_showAlert');
        element.fire('network-error', {error: new Error('ZOMG')});
        flush(() => {
          assert.isTrue(showAlertStub.calledOnce);
          assert.isTrue(showAlertStub.lastCall.calledWithExactly(
              'Server unavailable'));
          assert.isTrue(consoleErrorStub.calledOnce);
          assert.isTrue(consoleErrorStub.lastCall.calledWithExactly('ZOMG'));
          done();
        });
      });

      test('show auth refresh toast', done => {
        // starts with authed state
        element.$.restAPI.getLoggedIn();
        const refreshStub = sandbox.stub(element.$.restAPI, 'getAccount',
            () => Promise.resolve({}));
        const toastSpy = sandbox.spy(element, '_createToastAlert');
        const windowOpen = sandbox.stub(window, 'open');
        const responseText = Promise.resolve('Authentication required\n');
        // fake failed auth
        window.fetch.returns(Promise.resolve({status: 403}));
        element.fire('server-error',
            {response: {status: 403, text() { return responseText; }}}
        );
        assert.equal(window.fetch.callCount, 1);
        flush(() => {
          // auth check again
          assert.equal(window.fetch.callCount, 2);
          flush(() => {
            // auth-error fired
            assert.isTrue(toastSpy.called);

            // toast
            let toast = toastSpy.lastCall.returnValue;
            assert.isOk(toast);
            assert.include(
                Polymer.dom(toast.root).textContent, 'Credentails expired.');
            assert.include(
                Polymer.dom(toast.root).textContent, 'Refresh credentials');

            // noInteractionOverlay
            const noInteractionOverlay = element.$.noInteractionOverlay;
            assert.isOk(noInteractionOverlay);
            sinon.spy(noInteractionOverlay, 'close');
            assert.equal(
                noInteractionOverlay.backdropElement.getAttribute('opened'),
                '');
            assert.isFalse(windowOpen.called);
            MockInteractions.tap(toast.$$('gr-button.action'));
            assert.isTrue(windowOpen.called);

            // @see Issue 5822: noopener breaks closeAfterLogin
            assert.equal(windowOpen.lastCall.args[2].indexOf('noopener=yes'),
                -1);

            const hideToastSpy = sandbox.spy(toast, 'hide');

            // now fake authed
            window.fetch.returns(Promise.resolve({status: 204}));
            element._handleWindowFocus();
            element.flushDebouncer('checkLoggedIn');
            flush(() => {
              assert.isTrue(refreshStub.called);
              assert.isTrue(hideToastSpy.called);

              // toast update
              assert.notStrictEqual(toastSpy.lastCall.returnValue, toast);
              toast = toastSpy.lastCall.returnValue;
              assert.isOk(toast);
              assert.include(
                  Polymer.dom(toast.root).textContent, 'Credentials refreshed');

              // close overlay
              assert.isTrue(noInteractionOverlay.close.called);
              done();
            });
          });
        });
      });

      test('show alert', () => {
        const alertObj = {message: 'foo'};
        sandbox.stub(element, '_showAlert');
        element.fire('show-alert', alertObj);
        assert.isTrue(element._showAlert.calledOnce);
        assert.equal(element._showAlert.lastCall.args[0], 'foo');
        assert.isNotOk(element._showAlert.lastCall.args[1]);
        assert.isNotOk(element._showAlert.lastCall.args[2]);
      });

      test('checks stale credentials on visibility change', () => {
        const refreshStub = sandbox.stub(element,
            '_checkSignedIn');
        sandbox.stub(Date, 'now').returns(999999);
        element._lastCredentialCheck = 0;
        element._handleVisibilityChange();

        // Since there is no known account, it should not test credentials.
        assert.isFalse(refreshStub.called);
        assert.equal(element._lastCredentialCheck, 0);

        element.knownAccountId = 123;
        element._handleVisibilityChange();

        // Should test credentials, since there is a known account.
        assert.isTrue(refreshStub.called);
        assert.equal(element._lastCredentialCheck, 999999);
      });

      test('refreshes with same credentials', done => {
        const accountPromise = Promise.resolve({_account_id: 1234});
        sandbox.stub(element.$.restAPI, 'getAccount')
            .returns(accountPromise);
        const requestCheckStub = sandbox.stub(element, '_requestCheckLoggedIn');
        const handleRefreshStub = sandbox.stub(element,
            '_handleCredentialRefreshed');
        const reloadStub = sandbox.stub(element, '_reloadPage');

        element.knownAccountId = 1234;
        element._refreshingCredentials = true;
        element._checkSignedIn();

        flush(() => {
          assert.isFalse(requestCheckStub.called);
          assert.isTrue(handleRefreshStub.called);
          assert.isFalse(reloadStub.called);
          done();
        });
      });

      test('_showAlert hides existing alerts', () => {
        element._alertElement = element._createToastAlert();
        const hideStub = sandbox.stub(element, '_hideAlert');
        element._showAlert();
        assert.isTrue(hideStub.calledOnce);
      });

      test('show-error', () => {
        const openStub = sandbox.stub(element.$.errorOverlay, 'open');
        const closeStub = sandbox.stub(element.$.errorOverlay, 'close');
        const reportStub = sandbox.stub(
            element.$.reporting,
            'reportErrorDialog'
        );

        const message = 'test message';
        element.fire('show-error', {message});
        flushAsynchronousOperations();

        assert.isTrue(openStub.called);
        assert.isTrue(reportStub.called);
        assert.equal(element.$.errorDialog.text, message);

        element.$.errorDialog.fire('dismiss');
        flushAsynchronousOperations();

        assert.isTrue(closeStub.called);
      });

      test('reloads when refreshed credentials differ', done => {
        const accountPromise = Promise.resolve({_account_id: 1234});
        sandbox.stub(element.$.restAPI, 'getAccount')
            .returns(accountPromise);
        const requestCheckStub = sandbox.stub(
            element,
            '_requestCheckLoggedIn');
        const handleRefreshStub = sandbox.stub(element,
            '_handleCredentialRefreshed');
        const reloadStub = sandbox.stub(element, '_reloadPage');

        element.knownAccountId = 4321; // Different from 1234
        element._refreshingCredentials = true;
        element._checkSignedIn();

        flush(() => {
          assert.isFalse(requestCheckStub.called);
          assert.isFalse(handleRefreshStub.called);
          assert.isTrue(reloadStub.called);
          done();
        });
      });
    });

    suite('when not authed', () => {
      setup(() => {
        stub('gr-rest-api-interface', {
          getLoggedIn() { return Promise.resolve(false); },
        });
        element = fixture('basic');
      });

      test('refresh loop continues on credential fail', done => {
        const requestCheckStub = sandbox.stub(
            element,
            '_requestCheckLoggedIn');
        const handleRefreshStub = sandbox.stub(element,
            '_handleCredentialRefreshed');
        const reloadStub = sandbox.stub(element, '_reloadPage');

        element._refreshingCredentials = true;
        element._checkSignedIn();

        flush(() => {
          assert.isTrue(requestCheckStub.called);
          assert.isFalse(handleRefreshStub.called);
          assert.isFalse(reloadStub.called);
          done();
        });
      });
    });
  });
</script>