<!--
@license
Copyright (C) 2017 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.
-->
<!-- Polymer included for the html import polyfill. -->
<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"/>
<title>docs-url-behavior</title>
<script src="/test/common-test-setup.js"></script>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<link rel="import" href="docs-url-behavior.html">

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

<test-fixture id="basic">
  <template>
    <docs-url-behavior-element></docs-url-behavior-element>
  </template>
</test-fixture>

<script>
  suite('docs-url-behavior tests', () => {
    let element;

    suiteSetup(() => {
      // Define a Polymer element that uses this behavior.
      Polymer({
        is: 'docs-url-behavior-element',
        _legacyUndefinedCheck: true,
        behaviors: [Gerrit.DocsUrlBehavior],
      });
    });

    setup(() => {
      element = fixture('basic');
      element._clearDocsBaseUrlCache();
    });

    test('null config', () => {
      const mockRestApi = {
        probePath: sinon.stub().returns(Promise.resolve(true)),
      };
      return element.getDocsBaseUrl(null, mockRestApi)
          .then(docsBaseUrl => {
            assert.isTrue(
                mockRestApi.probePath.calledWith('/Documentation/index.html'));
            assert.equal(docsBaseUrl, '/Documentation');
          });
    });

    test('no doc config', () => {
      const mockRestApi = {
        probePath: sinon.stub().returns(Promise.resolve(true)),
      };
      const config = {gerrit: {}};
      return element.getDocsBaseUrl(config, mockRestApi)
          .then(docsBaseUrl => {
            assert.isTrue(
                mockRestApi.probePath.calledWith('/Documentation/index.html'));
            assert.equal(docsBaseUrl, '/Documentation');
          });
    });

    test('has doc config', () => {
      const mockRestApi = {
        probePath: sinon.stub().returns(Promise.resolve(true)),
      };
      const config = {gerrit: {doc_url: 'foobar'}};
      return element.getDocsBaseUrl(config, mockRestApi)
          .then(docsBaseUrl => {
            assert.isFalse(mockRestApi.probePath.called);
            assert.equal(docsBaseUrl, 'foobar');
          });
    });

    test('no probe', () => {
      const mockRestApi = {
        probePath: sinon.stub().returns(Promise.resolve(false)),
      };
      return element.getDocsBaseUrl(null, mockRestApi)
          .then(docsBaseUrl => {
            assert.isTrue(
                mockRestApi.probePath.calledWith('/Documentation/index.html'));
            assert.isNotOk(docsBaseUrl);
          });
    });
  });
</script>
