Rift.IO OSM R1 Initial Submission
Signed-off-by: Jeremy Mordkoff <jeremy.mordkoff@riftio.com>
diff --git a/skyquake/tests/intern.js b/skyquake/tests/intern.js
new file mode 100644
index 0000000..9b4fd44
--- /dev/null
+++ b/skyquake/tests/intern.js
@@ -0,0 +1,54 @@
+// Learn more about configuring this file at <https://theintern.github.io/intern/#configuration>.
+// These default settings work OK for most people. The options that *must* be changed below are the
+// packages, suites, excludeInstrumentation, and (if you want functional tests) functionalSuites
+define({
+ // Default desired capabilities for all environments. Individual capabilities can be overridden by any of the
+ // specified browser environments in the `environments` array below as well. See
+ // <https://theintern.github.io/intern/#option-capabilities> for links to the different capabilities options for
+ // different services.
+ //
+ // Note that the `build` capability will be filled in with the current commit ID or build tag from the CI
+ // environment automatically
+ capabilities: {
+ 'browserstack.selenium_version': '2.45.0'
+ },
+
+ // Browsers to run integration testing against. Note that version numbers must be strings if used with Sauce
+ // OnDemand. Options that will be permutated are browserName, version, platform, and platformVersion; any other
+ // capabilities options specified for an environment will be copied as-is
+ environments: [
+ { browserName: 'internet explorer', version: '11', platform: 'WIN8' },
+ { browserName: 'internet explorer', version: '10', platform: 'WIN8' },
+ { browserName: 'internet explorer', version: '9', platform: 'WINDOWS' },
+ { browserName: 'firefox', version: '37', platform: [ 'WINDOWS', 'MAC' ] },
+ { browserName: 'chrome', version: '39', platform: [ 'WINDOWS', 'MAC' ] },
+ { browserName: 'safari', version: '8', platform: 'MAC' }
+ ],
+
+ // Maximum number of simultaneous integration tests that should be executed on the remote WebDriver service
+ maxConcurrency: 2,
+
+ // Name of the tunnel class to use for WebDriver tests.
+ // See <https://theintern.github.io/intern/#option-tunnel> for built-in options
+ tunnel: 'BrowserStackTunnel',
+
+ // Configuration options for the module loader; any AMD configuration options supported by the AMD loader in use
+ // can be used here.
+ // If you want to use a different loader than the default loader, see
+ // <https://theintern.github.io/intern/#option-useLoader> for instruction
+ loaderOptions: {
+ // Packages that should be registered with the loader in each testing environment
+ packages: [ { name: 'myPackage', location: '.' } ]
+ },
+
+ // Non-functional test suite(s) to run in each browser
+ //suites: [ /* 'myPackage/tests/foo', 'myPackage/tests/bar' */ ],
+ suites: [
+ 'tests/unit/plugin_discoverer'
+ ],
+ // Functional test suite(s) to execute against each browser once non-functional tests are completed
+ functionalSuites: [ /* 'myPackage/tests/functional' */ ],
+
+ // A regular expression matching URLs to files that should not be included in code coverage analysis
+ excludeInstrumentation: /^(?:tests|node_modules)\//
+});
diff --git a/skyquake/tests/react/skyquakeRouter_test.js b/skyquake/tests/react/skyquakeRouter_test.js
new file mode 100644
index 0000000..0c65bbd
--- /dev/null
+++ b/skyquake/tests/react/skyquakeRouter_test.js
@@ -0,0 +1,34 @@
+jest.dontMock('../framework/widgets/skyquake_container/skyquakeNav');
+
+import React from 'react';
+import ReactDOM from 'react-dom';
+import TestUtils from 'react-addons-test-utils';
+import SkyquakeNav from '../framework/widgets/skyquake_container/skyquakeNav';
+// const SkyquakeNav = require('../framework/widgets/skyquake_container/skyquakeNav');
+
+describe('SkyquakeNav', () => {
+
+ let exampleRoutes = [{
+ "label": "Hello World Component 1",
+ "route": "/helloworld/#hello",
+ "component": "./helloWorldOne.jsx",
+ "path": "",
+ "type": "internal",
+ "isExternal": true
+ }];
+ let node;
+ beforeEach(function() {
+ node = document.createElement('div')
+ });
+ describe('returnLinkItem', () => {
+ let element;
+ beforeEach(function() {
+ element = SkyquakeNav.returnLinkItem(exampleRoutes[0]);
+ });
+ it('Returns an <a> tag when external', () => {
+ ReactDOM.render(element, node, function() {
+ expect(node.tagName == "A";
+ })
+ })
+ })
+})
diff --git a/skyquake/tests/stories/button.js b/skyquake/tests/stories/button.js
new file mode 100644
index 0000000..269312d
--- /dev/null
+++ b/skyquake/tests/stories/button.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import Button from '../../framework/widgets/button/rw.button'
+import SqButton from '../../framework/widgets/button/sq-button'
+import reactToJsx from 'react-to-jsx';
+import StyleGuideItem from 'react-style-guide';
+import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+let sqButtonHTML = ( <div style={{display: 'flex', padding: '10px'}}>
+ <SqButton icon="check" label="Normal" className="dark"/>
+ <SqButton label="Medium No Icon" size="medium" className="dark"/>
+ <SqButton size="large" icon="check" label="Large" className="dark"/>
+ <SqButton size="large" primary icon="check" label="Large" className="dark"/>
+ <SqButton size="large" disabled icon="check" label="Disabled" className="dark"/>
+ </div>)
+
+storiesOf('Button', module)
+ .add('A Light Button', () => (
+ <Button onClick={action('clicked')} label="A Light Button!" className="light" />
+ ))
+ .add('A Dark Button', () => (
+ <StyleGuideItem>
+ <Button label="A Dark Button!" className="dark"/>
+ </StyleGuideItem>
+ ))
+ .add('A Sq Button', () => (
+ <StyleGuideItem>
+ <div style={{display: 'flex', margin: '10px 10px 50px 10px'}}>
+ <SqButton icon="check" label="Submit" />
+ <SqButton label="Medium No Icon" size="medium" />
+ <SqButton size="large" icon="check" label="Large" />
+ <SqButton size="large" primary icon="check" label="Large" />
+ <SqButton size="large" disabled icon="check" label="Disabled" />
+ </div>
+ </StyleGuideItem>
+ ));
diff --git a/skyquake/tests/stories/catalogCard.js b/skyquake/tests/stories/catalogCard.js
new file mode 100644
index 0000000..b7e0e57
--- /dev/null
+++ b/skyquake/tests/stories/catalogCard.js
@@ -0,0 +1,538 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import CatalogCard from '../../plugins/launchpad/src/instantiate/catalogCard.jsx'
+import CatalogDescriptorRaw from '../../plugins/launchpad/src/instantiate/catalogDescriptorRaw.jsx'
+import InstantiateDescriptorPanel from '../../plugins/launchpad/src/instantiate/instantiateDescriptorPanel.jsx'
+import InstantiateSelectDescriptorPanel from '../../plugins/launchpad/src/instantiate/InstantiateSelectDescriptorPanel.jsx'
+import InstantiateInputParams from '../../plugins/launchpad/src/instantiate/instantiateInputParams.jsx'
+import reactToJsx from 'react-to-jsx';
+import InstantiateStore from '../../plugins/launchpad/src/instantiate/instantiateStore.js';
+import Alt from '../../framework/widgets/skyquake_container/skyquakeAltInstance.js'
+import {Panel, PanelWrapper} from '../../framework/widgets/panel/panel.jsx'
+import '../../node_modules/open-iconic/font/css/open-iconic.css';
+import 'style/base.scss';
+const Store = Alt.createStore(InstantiateStore)
+// import StyleGuideItem from 'react-style-guide';
+// import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+let SampleNSD = {
+ 'name': 'A Sample NSD for Corp A',
+ 'short-name': 'A Sample NSD',
+ description: 'A description of the sample NSD',
+ vendor: 'RIFT.io',
+ version: '1.0',
+ "constituent-vnfd": [
+ {
+ "start-by-default": "true",
+ "member-vnf-index": 1,
+ "vnfd-id-ref": "358fe806-57f8-11e6-b7de-6cb3113b406f",
+ "name": "trafgen",
+ "vnf-name": "trafgen"
+ },
+ {
+ "start-by-default": "true",
+ "member-vnf-index": 2,
+ "vnfd-id-ref": "3bd17356-57f8-11e6-88db-6cb3113b406f",
+ "name": "trafsink",
+ "vnf-name": "trafsink"
+ }
+ ],
+ "vld": [
+ {
+ "provider-network": {
+ "physical-network": "physnet1",
+ "overlay-type": "VLAN"
+ },
+ "version": "1.0",
+ "vendor": "RIFT.io",
+ "name": "Link1",
+ "short-name": "Link1",
+ "vnfd-connection-point-ref": [
+ {
+ "vnfd-connection-point-ref": "trafgen/cp0",
+ "vnfd-id-ref": "358fe806-57f8-11e6-b7de-6cb3113b406f",
+ "member-vnf-index-ref": 1
+ },
+ {
+ "vnfd-connection-point-ref": "trafsink/cp0",
+ "vnfd-id-ref": "3bd17356-57f8-11e6-88db-6cb3113b406f",
+ "member-vnf-index-ref": 2
+ }
+ ],
+ "description": "Link",
+ "id": "4ef5eebc-57f8-11e6-87d1-6cb3113b406f",
+ "type": "ELAN"
+ }
+ ],
+ "logo": "riftio.png",
+ "vnffgd": [
+ {
+ "name": "vnffgd-1",
+ "id": "23ee7",
+ "short-name": "FG-1"
+ }
+ ]
+}
+
+storiesOf('Instantiate Components', module)
+.add('CatalogCard', () => {
+ let cards = [];
+ for(let i = 0; i < 10; i++) {
+ cards.push(<CatalogCard key={i} clickid={i} descriptor={SampleNSD} />)
+ }
+ return (
+<PanelWrapper>
+<Panel>
+ <div style={{display:'flex', flexWrap:'wrap'}}>
+
+
+ <CatalogCard descriptor={SampleNSD} isSelected={true} isActive={true} />
+ {
+ cards
+ }
+ </div>
+</Panel>
+</PanelWrapper>
+)}
+)
+
+.add('InstantiateDescriptorPanel', () => (
+ <PanelWrapper>
+ <InstantiateDescriptorPanel
+ descriptor={returnNSD()[0]}
+ />
+ <Panel title="Input Parameters">
+ </Panel>
+ </PanelWrapper>
+))
+.add('InstantiateSelectDescriptor', () => (
+ <PanelWrapper>
+ <InstantiateSelectDescriptorPanel
+ descriptors={returnNSD()}
+ />
+ </PanelWrapper>
+))
+.add('Descriptor Review', () => (
+ <PanelWrapper>
+ <Panel title="Select Descriptor">
+ <CatalogCard descriptor={SampleNSD} isSelected={true} isActive={true} />
+ </Panel>
+ <Panel title="Descriptor Preview">
+ <CatalogDescriptorRaw descriptor={SampleNSD} />
+ </Panel>
+</PanelWrapper>))
+
+function returnNSD() {
+ return [
+ {
+ "input-parameter-xpath": [
+ {
+ "xpath": "/nsd:nsd-catalog/nsd:nsd/nsd:vendor"
+ }
+ ],
+ "ip-profiles": [
+ {
+ "name": "InterVNFLink",
+ "description": "Inter VNF Link",
+ "ip-profile-params": {
+ "ip-version": "ipv4",
+ "gateway-address": "31.31.31.210",
+ "subnet-address": "31.31.31.0/24",
+ "dhcp-params": {
+ "enabled": "true"
+ }
+ }
+ }
+ ],
+ "version": "1.0",
+ "initial-config-primitive": [
+ {
+ "seq": 1,
+ "name": "start traffic",
+ "parameter": [
+ {
+ "name": "userid"
+ }
+ ],
+ "user-defined-script": "start_traffic.py"
+ }
+ ],
+ "name": "ping_pong_nsd",
+ "short-name": "ping_pong_nsd",
+ "id": "1b85e414-630c-11e6-9050-3eca272c7412",
+ "logo": "rift_logo.png",
+ "description": "Toy NS",
+ "constituent-vnfd": [
+ {
+ "member-vnf-index": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "start-by-default": "true",
+ "name": "ping_vnfd",
+ "vnf-name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "start-by-default": "true",
+ "name": "pong_vnfd",
+ "vnf-name": "pong_vnfd"
+ }
+ ],
+ "vendor": "RIFT.io",
+ "placement-groups": [
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Orcus",
+ "requirement": "Place this VM on the Kuiper belt object Orcus",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ },
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Quaoar",
+ "requirement": "Place this VM on the Kuiper belt object Quaoar",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ }
+ ],
+ "vld": [
+ {
+ "type": "ELAN",
+ "description": "Toy VL",
+ "version": "1.0",
+ "ip-profile-ref": "InterVNFLink",
+ "vendor": "RIFT.io",
+ "name": "ping_pong_vld",
+ "short-name": "ping_pong_vld",
+ "id": "ping_pong_vld1",
+ "vnfd-connection-point-ref": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "vnfd-connection-point-ref": "ping_vnfd/cp0"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "vnfd-connection-point-ref": "pong_vnfd/cp0"
+ }
+ ]
+ }
+ ],
+ "meta": {
+ "instance-ref-count": 1
+ },
+ "ns-placement-groups": [
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Orcus",
+ "requirement": "Place this VM on the Kuiper belt object Orcus",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ },
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Quaoar",
+ "requirement": "Place this VM on the Kuiper belt object Quaoar",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ }
+ ],
+ "vnf-placement-groups": [
+ {
+ "name": "Eris",
+ "member-vdus": [
+ {
+ "member-vdu-ref": "iovdu_0"
+ }
+ ],
+ "requirement": "Place this VM on the Kuiper belt object Eris",
+ "strategy": "COLOCATION",
+ "host-aggregate": [],
+ "vnf-name": "ping_vnfd",
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "member-vnf-index": 1
+ },
+ {
+ "name": "Weywot",
+ "member-vdus": [
+ {
+ "member-vdu-ref": "iovdu_0"
+ }
+ ],
+ "requirement": "Place this VM on the Kuiper belt object Weywot",
+ "strategy": "COLOCATION",
+ "host-aggregate": [],
+ "vnf-name": "pong_vnfd",
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "member-vnf-index": 2
+ }
+ ]
+ },
+ {
+ "input-parameter-xpath": [
+ {
+ "xpath": "/nsd:nsd-catalog/nsd:nsd/nsd:vendor"
+ }
+ ],
+ "ip-profiles": [
+ {
+ "name": "InterVNFLink",
+ "description": "Inter VNF Link",
+ "ip-profile-params": {
+ "ip-version": "ipv4",
+ "gateway-address": "31.31.31.210",
+ "subnet-address": "31.31.31.0/24",
+ "dhcp-params": {
+ "enabled": "true"
+ }
+ }
+ }
+ ],
+ "version": "1.0",
+ "initial-config-primitive": [
+ {
+ "seq": 1,
+ "name": "start traffic",
+ "parameter": [
+ {
+ "name": "userid"
+ }
+ ],
+ "user-defined-script": "start_traffic.py"
+ }
+ ],
+ "name": "a copy of pingpong",
+ "meta": {
+ "containerPositionMap": {
+ "1": {
+ "top": 130,
+ "left": 260,
+ "right": 510,
+ "bottom": 185,
+ "width": 250,
+ "height": 55
+ },
+ "2": {
+ "top": 130,
+ "left": 635,
+ "right": 885,
+ "bottom": 185,
+ "width": 250,
+ "height": 55
+ },
+ "e0d7f471-ade0-49d3-9f47-225aa724ae08": {
+ "top": 30,
+ "left": 135,
+ "right": 385,
+ "bottom": 85,
+ "width": 250,
+ "height": 55
+ },
+ "ping_pong_vld1": {
+ "top": 300,
+ "left": 447.5,
+ "right": 697.5,
+ "bottom": 338,
+ "width": 250,
+ "height": 38
+ }
+ },
+ "instance-ref-count": 0
+ },
+ "short-name": "ping_pong_nsd",
+ "id": "e0d7f471-ade0-49d3-9f47-225aa724ae08",
+ "logo": "rift_logo.png",
+ "description": "Toy NS",
+ "constituent-vnfd": [
+ {
+ "member-vnf-index": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "start-by-default": "true",
+ "name": "ping_vnfd",
+ "vnf-name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "start-by-default": "true",
+ "name": "pong_vnfd",
+ "vnf-name": "pong_vnfd"
+ }
+ ],
+ "vendor": "RIFT.io",
+ "placement-groups": [
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Orcus",
+ "requirement": "Place this VM on the Kuiper belt object Orcus",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ },
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Quaoar",
+ "requirement": "Place this VM on the Kuiper belt object Quaoar",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ }
+ ],
+ "vld": [
+ {
+ "type": "ELAN",
+ "description": "Toy VL",
+ "version": "1.0",
+ "vendor": "RIFT.io",
+ "name": "ping_pong_vld",
+ "short-name": "ping_pong_vld",
+ "id": "ping_pong_vld1",
+ "vnfd-connection-point-ref": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "vnfd-connection-point-ref": "ping_vnfd/cp0"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "vnfd-connection-point-ref": "pong_vnfd/cp0"
+ }
+ ]
+ }
+ ],
+ "ns-placement-groups": [
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Orcus",
+ "requirement": "Place this VM on the Kuiper belt object Orcus",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ },
+ {
+ "member-vnfd": [
+ {
+ "member-vnf-index-ref": 1,
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "name": "ping_vnfd"
+ },
+ {
+ "member-vnf-index-ref": 2,
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "name": "pong_vnfd"
+ }
+ ],
+ "name": "Quaoar",
+ "requirement": "Place this VM on the Kuiper belt object Quaoar",
+ "strategy": "COLOCATION",
+ "host-aggregate": []
+ }
+ ],
+ "vnf-placement-groups": [
+ {
+ "name": "Eris",
+ "member-vdus": [
+ {
+ "member-vdu-ref": "iovdu_0"
+ }
+ ],
+ "requirement": "Place this VM on the Kuiper belt object Eris",
+ "strategy": "COLOCATION",
+ "host-aggregate": [],
+ "vnf-name": "ping_vnfd",
+ "vnfd-id-ref": "1b84ecbc-630c-11e6-9050-3eca272c7412",
+ "member-vnf-index": 1
+ },
+ {
+ "name": "Weywot",
+ "member-vdus": [
+ {
+ "member-vdu-ref": "iovdu_0"
+ }
+ ],
+ "requirement": "Place this VM on the Kuiper belt object Weywot",
+ "strategy": "COLOCATION",
+ "host-aggregate": [],
+ "vnf-name": "pong_vnfd",
+ "vnfd-id-ref": "1b859c48-630c-11e6-9050-3eca272c7412",
+ "member-vnf-index": 2
+ }
+ ]
+ }
+ ];
+}
diff --git a/skyquake/tests/stories/sq-input-slider.js b/skyquake/tests/stories/sq-input-slider.js
new file mode 100644
index 0000000..e4ebd31
--- /dev/null
+++ b/skyquake/tests/stories/sq-input-slider.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import SqInputRangeSlider from '../../framework/widgets/sq-input-range-slider/sq-input-range-slider'
+import StyleGuideItem from 'react-style-guide';
+import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+let containerStyle = {
+ display: 'flex'
+};
+
+storiesOf('SqInputRangeSlider', module)
+ .add('Horizontal Slider', () => (
+ <div>
+ <div className="inputcontainer" style={containerStyle}>
+ <SqInputRangeSlider className="one two three" max={150} step={10} width={300} onChange={action('valueChanged')} />
+ </div>
+ <div className="inputcontainer" style={containerStyle}>
+ <SqInputRangeSlider className="one two three" max={150} step={10} width={800} onChange={action('valueChanged')} />
+ </div>
+ <div className="inputcontainer" style={containerStyle}>
+ <SqInputRangeSlider className="one two three" max={150} step={10} width={200} disabled onChange={action('valueChanged')} />
+ </div>
+ </div>
+ ))
+ .add('Vertical Slider', () => (
+ <StyleGuideItem>
+<div style={{display:'flex'}}>
+ <div style={containerStyle}>
+ <SqInputRangeSlider vertical={true} width={300} onChange={action('valueChanged')} />
+ </div>
+ <div style={containerStyle}>
+ <SqInputRangeSlider vertical={true} width={600} onChange={action('valueChanged')} />
+ </div>
+ <div style={containerStyle}>
+ <SqInputRangeSlider vertical={true} width={300} onChange={action('valueChanged')} disabled={true} />
+ <SqInputRangeSlider vertical={true} width={300} onChange={action('valueChanged')} disabled={true} />
+ </div>
+</div>
+</StyleGuideItem>
+ ));
diff --git a/skyquake/tests/stories/sshKeyCard.js b/skyquake/tests/stories/sshKeyCard.js
new file mode 100644
index 0000000..649ec4a
--- /dev/null
+++ b/skyquake/tests/stories/sshKeyCard.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { storiesOf, action } from '@kadira/storybook';
+import DashboardCard from '../../framework/widgets/dashboard_card/dashboard_card.jsx'
+import SshKeyCard from '../../plugins/launchpad/src/ssh_keys/sshKeyCard.jsx';
+import SshKeys from '../../plugins/launchpad/src/ssh_keys/sshKeys.jsx';
+import SshKeyStore from '../../plugins/launchpad/src/ssh_keys/sshKeyStore.js';
+import Alt from '../../framework/widgets/skyquake_container/skyquakeAltInstance.js'
+import reactToJsx from 'react-to-jsx';
+import '../../node_modules/open-iconic/font/css/open-iconic.css';
+import 'style/base.scss';
+// import StyleGuideItem from 'react-style-guide';
+// import '../../node_modules/react-style-guide/node_modules/highlight.js/styles/github.css';
+
+const Store = Alt.createStore(SshKeyStore)
+
+storiesOf('CatalogCard', module)
+// .add('page', () => (<SshKeys />))
+.add('sshKeyPage', () => (<Test />))
+
+
+class Test extends React.Component {
+ constructor() {
+ super();
+ let self = this;
+ this.state = Store.getState();
+ console.log(this.state)
+ Store.listen(function(data) {
+ self.setState({data: data.data})
+ })
+ }
+ render() {
+ let self = this;
+ return (
+ <DashboardCard>
+ {
+ self.state.data && self.state.data.keys.map(function(k, i) {
+ let sshKey = self.state.data.entities[k];
+ return (
+ <SshKeyCard key={i} name={sshKey.name} value={sshKey.key}
+ editMode={sshKey.isEditable}
+ editKey= {Store.editSshKeyPair(sshKey.name)}
+ updateSshKeyPair={Store.updateSshKeyPair}
+ cancelEditSshKeyPair={Store.cancelEditSshKeyPair}
+ saveEditSshKeyPair={Store.saveEditSshKeyPair(sshKey.name)}
+ />
+ )
+ })
+ }
+ </DashboardCard>
+ )
+ }
+}
diff --git a/skyquake/tests/support/babel.js b/skyquake/tests/support/babel.js
new file mode 100644
index 0000000..c8f0b73
--- /dev/null
+++ b/skyquake/tests/support/babel.js
@@ -0,0 +1,46 @@
+define([
+ 'intern/dojo/request',
+ 'intern/dojo/node!babel-core',
+ 'intern/dojo/node!react'
+], function (request, babel, react) {
+ /**
+ * React has AMD support so when require is present it will behave as a module
+ * The react example however expects a global React so we need to put it back
+ * into global space.
+ */
+ function globalizeReact() {
+ var global = (function () {
+ return this;
+ })();
+ global.React = global.React || react;
+ }
+
+ return {
+ /**
+ * A function that is called to load a resource.
+ *
+ * @param name The name of the resource to load.
+ * @param req A local "require" function to use to load other modules.
+ * @param onload A function to call with the value for name. This tells the loader that the plugin is done
+ * loading the resource. onload.error() can be called, passing an error object to it, if the plugin
+ * detects an error condition that means the resource will fail to load correctly.
+ */
+ load: function (name, req, onload) {
+ globalizeReact();
+
+ request(req.toUrl(name)).then(function (sourceCode) {
+ // Compile the JSX source into JavaScript code
+ var javascriptCode = babel.transform(sourceCode,{presets:['es2015', 'react']}).code;
+
+ // Execute the compiled function. In this case the example code
+ // puts things into the global space so it needs to be run in a script tag.
+ var codeNode = document.createTextNode(javascriptCode);
+ var node = document.createElement('script');
+ node.type = 'text/javascript';
+ node.appendChild(codeNode);
+ document.head.appendChild(node);
+ onload();
+ });
+ }
+ };
+});
diff --git a/skyquake/tests/unit/plugin_discoverer.js b/skyquake/tests/unit/plugin_discoverer.js
new file mode 100644
index 0000000..337f2fe
--- /dev/null
+++ b/skyquake/tests/unit/plugin_discoverer.js
@@ -0,0 +1,62 @@
+define(function (require) {
+ var base_plugins = ['about', 'accounts', 'composer', 'debug', 'goodbyeworld', 'helloworld', 'launchpad', 'logging'];
+ var registerSuite = require('intern!object');
+ var assert = require('intern/chai!assert');
+ var plugin_discoverer = require('intern/dojo/node!../../framework/core/modules/plugin_discoverer.js');
+ var skyquakeEmitter = require('intern/dojo/node!../../framework/core/modules/skyquakeEmitter.js');
+ var _ = require('intern/dojo/node!lodash');
+ var fs = require('intern/dojo/node!fs');
+ registerSuite({
+ name: 'plugin_discoverer',
+ before: function() {
+
+ },
+ after: function() {
+ // Exit process.
+ // TODO: Should cleanup plugin_discoverer instead and call that
+ setTimeout(function() {
+ var path = process.cwd() + '/plugins/helloworld/test.txt';
+ fs.unlinkSync(path);
+ process.exit(0);
+ });
+ },
+ 'Test init': function () {
+ var res = plugin_discoverer.init();
+ assert.isUndefined(res, 'return value is undefined');
+ },
+ 'Test config': function() {
+ var path = process.cwd() + '/plugins';
+ var res = plugin_discoverer.config({
+ plugins_path: path
+ });
+ assert.isUndefined(res, 'return value is undefined');
+ },
+ 'Test run plugin add discovery': function() {
+ var deferred = this.async();
+
+ var plugins_detected = [];
+
+ skyquakeEmitter.on('plugin_discoverer.plugin_discovered', function(plugin_name) {
+ plugins_detected.push(plugin_name);
+ if (_.intersection(plugins_detected, base_plugins).length == 8 ) {
+ // all expected plugins were discovered
+ deferred.resolve('All expected plugins discovered');
+ }
+ });
+
+ var res = plugin_discoverer.run();
+ },
+ 'Test run plugin update discovery': function() {
+ var deferred = this.async();
+
+ setTimeout(function() {
+ var path = process.cwd() + '/plugins/helloworld/test.txt';
+ fs.openSync(path, 'a+');
+ });
+
+ skyquakeEmitter.on('plugin_discoverer.plugin_updated', function(plugin_name) {
+ deferred.resolve();
+ });
+ },
+ });
+});
diff --git a/skyquake/tests/unit/router.js b/skyquake/tests/unit/router.js
new file mode 100644
index 0000000..3f30831
--- /dev/null
+++ b/skyquake/tests/unit/router.js
@@ -0,0 +1,20 @@
+// import SkyquakeRouter from './../../framework/widgets/skyquake_container/skyquakeRouter.jsx';
+
+define([
+ 'intern!object',
+ 'intern/chai!assert',
+ 'require',
+ './../support/babel!../../framework/widgets/skyquake_container/skyquakeRouter.jsx'
+ ],
+
+ function (registerSuite, assert, require, skyquakeRouter) {
+ console.log(skyquakeRouter)
+ registerSuite({
+ name: 'plugin_discoverer',
+
+ init: function () {
+ // var res = plugin_discoverer.init();
+ // assert.isUndefined(res, 'return value is undefined');
+ }
+ });
+});