Pārlūkot izejas kodu

HUE-9096 [doc] Add tests to the linkSharing component

Johan Ahlen 5 gadi atpakaļ
vecāks
revīzija
18eb09231e

+ 1 - 0
desktop/core/src/desktop/js/jest/jest.init.js

@@ -37,6 +37,7 @@ const globalVars = {
   ko: ko,
   AUTOCOMPLETE_TIMEOUT: 1,
   CACHEABLE_TTL: 1,
+  HAS_LINK_SHARING: true,
   HAS_OPTIMIZER: false,
   HUE_I18n: {},
   HUE_BASE_URL: '',

+ 11 - 4
desktop/core/src/desktop/js/jest/koTestUtils.js

@@ -98,10 +98,17 @@ export const koSetup = () => {
         ko.applyBindings(data, setupContainer);
       }),
 
-    waitForKoUpdate: async () => {
-      return new Promise(resolve => {
+    waitForKoUpdate: async () =>
+      new Promise(resolve => {
         window.setTimeout(resolve, 0);
-      });
-    }
+      })
   };
 };
+
+export const waitForObservableChange = async observable =>
+  new Promise(resolve => {
+    const sub = observable.subscribe(() => {
+      sub.dispose();
+      resolve();
+    });
+  });

+ 69 - 0
desktop/core/src/desktop/js/ko/components/doc/__snapshots__/ko.linkSharing.test.js.snap

@@ -0,0 +1,69 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ko.linkSharing.js should render component activated 1`] = `
+"<div data-bind=\\"descendantsComplete: descendantsComplete, component: { name: &quot;link-sharing&quot;, params: params }\\"><div class=\\"hue-link-sharing\\">
+    <div style=\\"float: right\\">
+      <!-- ko ifnot: perms().link_sharing_on --><!-- /ko -->
+      <!-- ko if: perms().link_sharing_on -->
+      <a href=\\"javascript:void(0)\\" data-test=\\"deactivate\\" data-bind=\\"click: deactivateLink\\" title=\\"Deactivate the link sharing\\">
+        <i class=\\"fa fa-wf fa-link\\"></i> Deactivate link
+      </a>
+      <!-- /ko -->
+    </div>
+    <!-- ko if: perms().link_sharing_on -->
+    <div>
+      Any logged in user with the link can
+      <div class=\\"perm-selector\\" data-bind=\\"component: {
+          name: 'hue-drop-down',
+          params: {
+            value: selectedPerm,
+            entries: availablePerms,
+            onSelect: changePerm.bind($data)
+          }
+        }
+      \\"><a class=\\"inactive-action hue-drop-down-active\\" href=\\"javascript:void(0)\\" data-bind=\\"toggle: dropDownVisible, css: { 'blue': dropDownVisible }\\">
+    <!-- ko if: icon --><!-- /ko -->
+    <!-- ko if: !noLabel && value -->
+    <span class=\\"hue-drop-down-selected\\" data-bind=\\"text: value() &amp;&amp; typeof value()[labelAttribute] !== 'undefined' ? value()[labelAttribute] : value(), visible: ! dropDownVisible() || !searchable, attr: { 'title': value() &amp;&amp; typeof value()[labelAttribute] !== 'undefined' ? value()[labelAttribute] : value() }\\" title=\\"read\\">read</span>
+    <!-- /ko -->
+    <i class=\\"fa fa-caret-down\\"></i>
+  </a><input class=\\"hue-drop-down-input\\" type=\\"text\\" data-bind=\\"textInput: filter, attr: { 'placeHolder': inputPlaceHolder }, visible: dropDownVisible, style: { color: filterEdited() ? '#000' : '#AAA', 'min-height': '22px', 'margin-left': '10px' }\\" placeholder=\\"read\\" style=\\"display: none; color: rgb(170, 170, 170); min-height: 22px; margin-left: 10px;\\"><i class=\\"fa fa-caret-down\\"></i><div class=\\"hue-drop-down-container\\" data-bind=\\"css: { 'open' : dropDownVisible, 'hue-drop-down-fixed': fixedPosition, 'hue-drop-down-container-searchable': searchable }, dropDownKeyUp: { onEsc: onEsc, onEnter: onEnter, dropDownVisible: dropDownVisible }\\">
+    <div style=\\"overflow-y: auto;\\" class=\\"dropdown-menu\\" data-bind=\\"visible: filteredEntries().length > 0\\">
+      <!-- ko if: foreachVisible --><!-- /ko -->
+      <!-- ko ifnot: foreachVisible -->
+      <ul class=\\"hue-inner-drop-down\\" data-bind=\\"foreach: filteredEntries\\">
+        <!-- ko if: typeof $data.divider !== 'undefined' && $data.divider --><!-- /ko -->
+        <!-- ko if: typeof $data.divider === 'undefined' || !$data.divider -->
+        <li><a href=\\"javascript:void(0)\\" data-bind=\\"text: $data &amp;&amp; typeof $data[$parent.labelAttribute] !== 'undefined' ? $data[$parent.labelAttribute] : $data, click: function () { let previous = $parent.value(); $parent.value($data); $parent.onSelect($data, previous); }\\">read</a></li>
+        <!-- /ko -->
+      
+        <!-- ko if: typeof $data.divider !== 'undefined' && $data.divider --><!-- /ko -->
+        <!-- ko if: typeof $data.divider === 'undefined' || !$data.divider -->
+        <li><a href=\\"javascript:void(0)\\" data-bind=\\"text: $data &amp;&amp; typeof $data[$parent.labelAttribute] !== 'undefined' ? $data[$parent.labelAttribute] : $data, click: function () { let previous = $parent.value(); $parent.value($data); $parent.onSelect($data, previous); }\\">write</a></li>
+        <!-- /ko -->
+      </ul>
+      <!-- /ko -->
+    </div>
+  </div></div>
+    </div>
+    <div class=\\"shared-link\\">
+      <div id=\\"sharedLinkInput\\" data-bind=\\"text: link\\">https://www.gethue.com/hueundefined</div>
+      <button class=\\"btn\\" data-clipboard-target=\\"#sharedLinkInput\\" data-bind=\\"clipboard\\"><i class=\\"fa fa-clipboard\\"></i></button>
+    </div>
+    <!-- /ko -->
+  </div></div>"
+`;
+
+exports[`ko.linkSharing.js should render component deactivated 1`] = `
+"<div data-bind=\\"descendantsComplete: descendantsComplete, component: { name: &quot;link-sharing&quot;, params: params }\\"><div class=\\"hue-link-sharing\\">
+    <div style=\\"float: right\\">
+      <!-- ko ifnot: perms().link_sharing_on -->
+      <a href=\\"javascript:void(0);\\" data-test=\\"activate\\" data-bind=\\"click: createReadLink\\" title=\\"Share the query via a link\\">
+        <i class=\\"fa fa-wf fa-link\\"></i> Get link
+      </a>
+      <!-- /ko -->
+      <!-- ko if: perms().link_sharing_on --><!-- /ko -->
+    </div>
+    <!-- ko if: perms().link_sharing_on --><!-- /ko -->
+  </div></div>"
+`;

+ 7 - 3
desktop/core/src/desktop/js/ko/components/doc/ko.linkSharing.js

@@ -23,18 +23,22 @@ import DisposableComponent from '../DisposableComponent';
 import { DOCUMENT_UPDATED_EVENT } from 'doc/hueDocument';
 import huePubSub from 'utils/huePubSub';
 
+import 'ko/components/ko.dropDown';
+
+export const NAME = 'link-sharing';
+
 // prettier-ignore
 const TEMPLATE = `
   <!-- ko if: window.HAS_LINK_SHARING && perms() -->
   <div class="hue-link-sharing">
     <div style="float: right">
       <!-- ko ifnot: perms().link_sharing_on -->
-      <a href="javascript:void(0);" data-bind="click: createReadLink" title="${ I18n('Share the query via a link') }" >
+      <a href="javascript:void(0);" data-test="activate" data-bind="click: createReadLink" title="${ I18n('Share the query via a link') }" >
         <i class="fa fa-wf fa-link"></i> ${ I18n('Get link') }
       </a>
       <!-- /ko -->
       <!-- ko if: perms().link_sharing_on -->
-      <a href="javascript:void(0)" data-bind="click: deactivateLink" title="${ I18n('Deactivate the link sharing') }">
+      <a href="javascript:void(0)" data-test="deactivate" data-bind="click: deactivateLink" title="${ I18n('Deactivate the link sharing') }">
         <i class="fa fa-wf fa-link"></i> ${ I18n('Deactivate link') }
       </a>
       <!-- /ko -->
@@ -103,4 +107,4 @@ class LinkSharing extends DisposableComponent {
   }
 }
 
-componentUtils.registerComponent('link-sharing', LinkSharing, TEMPLATE);
+componentUtils.registerComponent(NAME, LinkSharing, TEMPLATE);

+ 138 - 0
desktop/core/src/desktop/js/ko/components/doc/ko.linkSharing.test.js

@@ -0,0 +1,138 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you 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.
+
+import * as ko from 'knockout';
+
+import { koSetup, waitForObservableChange } from 'jest/koTestUtils';
+import { NAME } from './ko.linkSharing';
+import ApiHelper, { LINK_SHARING_PERMS } from 'api/apiHelper';
+
+describe('ko.linkSharing.js', () => {
+  const setup = koSetup();
+
+  let params;
+
+  beforeEach(() => {
+    params = {
+      docDefinition: {
+        uuid: 'some-uuid',
+        perms: {
+          read: {
+            groups: [],
+            users: []
+          },
+          write: {
+            groups: [],
+            users: []
+          },
+          link_write: false,
+          link_read: false,
+          link_sharing_on: false
+        }
+      }
+    };
+  });
+
+  it('should render component deactivated', async () => {
+    const element = await setup.renderComponent(NAME, params);
+
+    expect(element.innerHTML).toMatchSnapshot();
+  });
+
+  it('should render component activated', async () => {
+    params.docDefinition.perms.link_read = true;
+    params.docDefinition.perms.link_sharing_on = true;
+    const element = await setup.renderComponent(NAME, params);
+
+    expect(element.innerHTML).toMatchSnapshot();
+  });
+
+  it('should activate sharing', async () => {
+    let apiHelperCalled = false;
+    jest.spyOn(ApiHelper, 'setLinkSharingPermsAsync').mockImplementation(async options => {
+      expect(options.perm).toEqual(LINK_SHARING_PERMS.READ);
+      apiHelperCalled = true;
+      return Promise.resolve({
+        status: 0,
+        document: {
+          uuid: 'some-uuid',
+          perms: {
+            link_write: false,
+            link_read: true,
+            link_sharing_on: true
+          }
+        }
+      });
+    });
+    const element = await setup.renderComponent(NAME, params);
+
+    // Activate should be visible
+    expect(element.querySelector('[data-test="activate"]')).toBeTruthy();
+    expect(element.querySelector('[data-test="deactivate"]')).toBeFalsy();
+    const model = ko.dataFor(element.querySelector('[data-test="activate"]'));
+    expect(model.perms().link_sharing_on).toBeFalsy();
+    expect(apiHelperCalled).toBeFalsy();
+
+    // Click activate
+    element.querySelector('[data-test="activate"]').click();
+    await waitForObservableChange(model.perms);
+
+    // Deactivate should be visible
+    expect(element.querySelector('[data-test="activate"]')).toBeFalsy();
+    expect(element.querySelector('[data-test="deactivate"]')).toBeTruthy();
+    expect(model.perms().link_sharing_on).toBeTruthy();
+    expect(apiHelperCalled).toBeTruthy();
+  });
+
+  it('should deactivate sharing', async () => {
+    let apiHelperCalled = false;
+    jest.spyOn(ApiHelper, 'setLinkSharingPermsAsync').mockImplementation(async options => {
+      expect(options.perm).toEqual(LINK_SHARING_PERMS.OFF);
+      apiHelperCalled = true;
+      return Promise.resolve({
+        status: 0,
+        document: {
+          uuid: 'some-uuid',
+          perms: {
+            link_write: false,
+            link_read: false,
+            link_sharing_on: false
+          }
+        }
+      });
+    });
+    params.docDefinition.perms.link_read = true;
+    params.docDefinition.perms.link_sharing_on = true;
+    const element = await setup.renderComponent(NAME, params);
+
+    // Deactivate should be visible
+    expect(element.querySelector('[data-test="activate"]')).toBeFalsy();
+    expect(element.querySelector('[data-test="deactivate"]')).toBeTruthy();
+    const model = ko.dataFor(element.querySelector('[data-test="deactivate"]'));
+    expect(model.perms().link_sharing_on).toBeTruthy();
+    expect(apiHelperCalled).toBeFalsy();
+
+    // Click deactivate
+    element.querySelector('[data-test="deactivate"]').click();
+    await waitForObservableChange(model.perms);
+
+    // Activate should be visible
+    expect(element.querySelector('[data-test="activate"]')).toBeTruthy();
+    expect(element.querySelector('[data-test="deactivate"]')).toBeFalsy();
+    expect(model.perms().link_sharing_on).toBeFalsy();
+    expect(apiHelperCalled).toBeTruthy();
+  });
+});