Переглянути джерело

HUE-8981 [editor] Add setup for headless testing of ko components and initial tests for sessionPanel

Johan Ahlen 6 роки тому
батько
коміт
a254a96152

+ 9 - 5
desktop/core/src/desktop/js/ko/components/ko.sessionPanel.js

@@ -17,11 +17,16 @@
 import ko from 'knockout';
 import komapping from 'knockout.mapping';
 
+import 'ko/bindings/ko.slideVisible';
+import 'ko/bindings/ko.toggle';
+import apiHelper from '../../api/apiHelper';
 import componentUtils from './componentUtils';
 import huePubSub from 'utils/huePubSub';
 import I18n from 'utils/i18n';
 import sessionManager from 'apps/notebook2/execution/sessionManager';
-import apiHelper from '../../api/apiHelper';
+
+export const NAME = 'session-panel';
+export const SHOW_EVENT_NAME = 'session.panel.show';
 
 const TEMPLATE = `
 <div class="session-panel" data-bind="slideVisible: visible">
@@ -124,12 +129,11 @@ class EditableSession {
 }
 
 class SessionPanel {
-  constructor(params) {
+  constructor() {
     this.visible = ko.observable(false);
     this.sessions = ko.observableArray();
     this.activeTypeFilter = undefined;
-
-    huePubSub.subscribe('session.panel.show', type => this.showSessions(type));
+    huePubSub.subscribe(SHOW_EVENT_NAME, type => this.showSessions(type));
   }
 
   /**
@@ -184,4 +188,4 @@ class SessionPanel {
   saveDefaultUserProperties(session) {}
 }
 
-componentUtils.registerComponent('session-panel', SessionPanel, TEMPLATE);
+componentUtils.registerComponent(NAME, SessionPanel, TEMPLATE);

+ 29 - 0
desktop/core/src/desktop/js/ko/components/spec/ko.sessionPanel.spec.js

@@ -0,0 +1,29 @@
+import huePubSub from 'utils/huePubSub';
+import sessionManager from 'apps/notebook2/execution/sessionManager';
+import { koSetup } from 'spec/jasmineSetup';
+import { NAME, SHOW_EVENT_NAME } from '../ko.sessionPanel';
+
+describe('ko.sessionPanel.js', () => {
+  const setup = koSetup();
+
+  it('should render component', async () => {
+    const element = await setup.renderComponent(NAME, {});
+
+    expect(element.querySelector('.session-panel')).toBeTruthy();
+  });
+
+  it('should be visible on publish event', async () => {
+    const wrapper = await setup.renderComponent(NAME, {});
+    const sessionPanelElement = wrapper.querySelector('.session-panel');
+    spyOn(sessionManager, 'getAllSessions').and.returnValue(Promise.resolve([]));
+
+    // Initially hidden
+    expect(sessionPanelElement.style['display']).toEqual('none');
+
+    huePubSub.publish(SHOW_EVENT_NAME, 'impala');
+    await setup.waitForKoUpdate();
+
+    // Visible after pubsub
+    expect(sessionPanelElement.style['display']).toBeFalsy();
+  });
+});

+ 43 - 0
desktop/core/src/desktop/js/spec/jasmineSetup.js

@@ -16,6 +16,7 @@
 
 import JasmineCore from 'jasmine-core';
 import { JSDOM } from 'jsdom';
+import ko from 'knockout';
 
 const jsdom = new JSDOM('<!doctype html><html><body></body></html>', {
   url: 'https://www.gethue.com/hue',
@@ -38,3 +39,45 @@ global.sessionStorage = window.sessionStorage;
 global.getJasmineRequireObj = function() {
   return JasmineCore;
 };
+
+export const koSetup = () => {
+  let originalLoadTemplate;
+  let wrapper;
+
+  beforeEach(() => {
+    originalLoadTemplate = ko.components.defaultLoader.loadTemplate;
+    ko.components.defaultLoader.loadTemplate = (name, templateConfig, callback) => {
+      const div = window.document.createElement('div');
+      div.innerHTML = templateConfig;
+      callback(div.children);
+    };
+
+    wrapper = window.document.createElement('div');
+    wrapper.classList.add('component-wrapper');
+    window.document.querySelector('body').appendChild(wrapper);
+  });
+
+  afterEach(() => {
+    ko.components.defaultLoader.loadTemplate = originalLoadTemplate;
+    wrapper.parentNode.removeChild(wrapper);
+  });
+
+  return {
+    renderComponent: async (name, data) =>
+      new Promise(resolve => {
+        const element = window.document.createElement('div');
+        element.setAttribute('data-bind', `component: { name: "${name}", params: $data }`);
+        wrapper.appendChild(element);
+        ko.applyBindings(data, wrapper);
+        window.setTimeout(() => {
+          resolve(wrapper);
+        }, 0);
+      }),
+
+    waitForKoUpdate: async () => {
+      return new Promise(resolve => {
+        window.setTimeout(resolve, 0);
+      });
+    }
+  };
+};