Merge pull request #8 from ediardo/JSUnitTestsBase

Add JavaScript unit tests code base
This commit is contained in:
ldcastell 2016-08-23 14:02:23 -05:00 committed by GitHub
commit f63308d60f
14 changed files with 484 additions and 29 deletions

51
.eslintrc Normal file
View File

@ -0,0 +1,51 @@
# Set up globals
globals:
angular: false
extends: openstack
# Most environment options are not explicitly enabled or disabled, only
# included here for completeness' sake. They are commented out, because the
# global updates.py script would otherwise override them during a global
# requirements synchronization.
#
# Individual projects should choose which platforms they deploy to.
env:
# browser global variables.
browser: true
# Adds all of the Jasmine testing global variables for version 1.3 and 2.0.
jasmine: true
# Below we adjust rules specific to horizon's usage of openstack's linting
# rules, and its own plugin inclusions.
rules:
#############################################################################
# Disabled Rules from eslint-config-openstack
#############################################################################
valid-jsdoc: [1, {
requireParamDescription: false
}]
no-undefined: 1
brace-style: 1
no-extra-parens: 1
callback-return: 1
block-scoped-var: 1
quote-props: 0
space-in-parens: 1
no-use-before-define: 1
no-unneeded-ternary: 1
#############################################################################
# Angular Plugin Customization
#############################################################################
angular/controller-as-vm:
- 1
- "ctrl"
# Remove after migrating to angular 1.4 or later.
angular/no-cookiestore:
- 1

1
.gitignore vendored
View File

@ -6,6 +6,7 @@ dist
ChangeLog
AUTHORS
craton_ui.egg-info/*
node_modules/*
.cache
.testrepository
.tox

View File

@ -2,6 +2,14 @@
Craton UI for Horizon Dashboard
===============================
Test
____
* Python tests: `./run_test.sh`
* JS tests:
1. `npm install` (first do `./run_tests.sh` to create virtual environment)
2. `npm run lint` for eslint
3. `npm run test` for JS unit tests
Install
-------

View File

@ -14,13 +14,28 @@
from cratonclient.v1 import client as craton_client
from cratonclient import session as craton_session
from horizon.utils.memoized import memoized # noqa
from horizon.utils.memoized import memoized_with_request # noqa
from openstack_dashboard.api import base
from six.moves.urllib import request
def cratonclient():
url = base.url_for(request, 'craton')
c = craton_client.Client(session=request.session, url=url)
def get_auth_params_from_request(request):
return(
request.user.username,
request.user.token.id,
request.user.tenant_id,
base.url_for(request, 'craton')
)
@memoized_with_request(get_auth_params_from_request)
def cratonclient(request_auth_params):
username, token, project_id, url = request_auth_params
session = craton_session.Session(username=username, token=token)
c = craton_client.Client(session=session, url=url)
return c
@ -52,6 +67,7 @@ def region_delete(request, **kwargs):
pass
@memoized
def region_list(request, **kwargs):
return cratonclient(request).regions.list(**kwargs)

View File

@ -30,7 +30,7 @@ class Regions(generic.View):
@rest_utils.ajax()
def get(self, request, **kwargs):
"""Get all Regions."""
regions = craton.region_list(request)
regions = craton.region_list(request, **kwargs)
return {'items': regions}
@rest_utils.ajax()

View File

@ -18,25 +18,41 @@
'use strict';
/**
* @ngdoc overview
* @name
* @description
* @ngdoc service
* @name cratonAPI
* @param {Object} apiService
* @param {Object} toastService
* @description provides direct pass through craton with NO abstraction
* @returns {Object} the service
*/
angular
.module('horizon.app.core.openstack-service-api')
.factory('horizon.app.core.openstack-service-api.craton', CratonAPI);
.factory('horizon.app.core.openstack-service-api.craton', cratonAPI);
CratonAPI.$inject = [
cratonAPI.$inject = [
'horizon.framework.util.http.service',
'horizon.framework.widgets.toast.service'
];
function CratonAPI(apiService, toastService) {
function cratonAPI(apiService, toastService) {
var service = {
getRegions: getRegions
};
/**
* @name getRegions
* @description Gets a list of regions
*
* @returns {Object} an object with 'items'
*/
function getRegions() {
return apiService.get('api/craton/regions')
.error(function error() {
toastService.add('error', gettext("Unable to get the Craton regions listing"));
});
}
return service;
}

View File

@ -0,0 +1,62 @@
/**
* Copyright 2016 Intel Corporation
*
* 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.
*/
(function() {
'use strict';
describe('Craton API', function() {
var testCall, service;
var apiService = {};
var toastService = {};
beforeEach(
module('horizon.mock.openstack-service-api',
function($provide, initServices) {
testCall = initServices($provide, apiService, toastService);
})
);
beforeEach(module('horizon.app.core.openstack-service-api'));
beforeEach(inject(['horizon.app.core.openstack-service-api.craton', function(cratonAPI) {
service = cratonAPI;
}]));
it('defines the service', function() {
expect(service).toBeDefined();
});
var tests = [
{
func: "getRegions",
method: "get",
path: "api/craton/regions",
error: "Unable to get the Craton regions listing"
}
];
// Iterate through the defined tests and apply as Jasmine specs.
angular.forEach(tests, function(params) {
it('defines the ' + params.func + ' call properly', function test() {
var callParams = [apiService, service, toastService, params];
testCall.apply(this, callParams);
});
});
});
})();

View File

@ -0,0 +1,22 @@
/**
* Copyright 2016 Intel Corporation
*
* 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.
*/
(function() {
'use strict';
//TODO: ADD Tests!!
})();

View File

@ -38,32 +38,32 @@
var basePath = $windowProvider.$get().STATIC_URL + 'dashboard/project/fleet_management/';
$provide.constant('horizon.dashboard.project.fleet_management.basePath', basePath);
var regions = '/project/regions',
taskflows = '/project/fleet/taskflows',
alerts = '/project/fleet/alerts',
auditor = '/project/fleet/auditor',
reporting = '/project/fleet/reporting',
inventory = '/project/fleet/inventory';
var regions = '/project/regions';
var taskflows = '/project/fleet/taskflows';
var alerts = '/project/fleet/alerts';
var auditor = '/project/fleet/auditor';
var reporting = '/project/fleet/reporting';
var inventory = '/project/fleet/inventory';
$routeProvider
.when(regions, {
templateUrl: basePath + 'regions/index.html'
}).
when(taskflows, {
})
.when(taskflows, {
templateUrl: basePath + 'taskflows/index.html'
}).
when(alerts, {
})
.when(alerts, {
templateUrl: basePath + 'alerts/index.html'
}).
when(auditor, {
})
.when(auditor, {
templateUrl: basePath + 'auditor/index.html'
}).
when(reporting, {
})
.when(reporting, {
templateUrl: basePath + 'reporting/index.html'
}).
when(inventory, {
})
.when(inventory, {
templateUrl: basePath + 'inventory/index.html'
});
});
}
})();

View File

@ -0,0 +1,15 @@
/**
* Copyright 2016 Intel Corporation
*
* 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.
*/

View File

@ -0,0 +1,22 @@
/**
* Copyright 2016 Intel Corporation
*
* 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.
*/
(function() {
'use strict';
//TODO: ADD TESTS!!
})();

View File

@ -0,0 +1,22 @@
/**
* Copyright 2016 Intel Corporation
*
* 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.
*/
(function() {
'use strict';
// TODO: ADD TESTS!!
})();

190
karma.conf.js Normal file
View File

@ -0,0 +1,190 @@
/**
*
* 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.
*/
'use-strict';
var fs = require('fs');
var path = require('path');
module.exports = function(config) {
var xstaticPath;
var horizonPath;
var openstackDashboardPath;
var horizonRoot;
var basePaths = [
'./.venv',
'./.tox/py27'
];
for (var i = 0; i < basePaths.length; i++) {
var basePath = path.resolve(basePaths[i]);
if (fs.existsSync(basePath)) {
xstaticPath = basePath + '/lib/python2.7/site-packages/xstatic/pkg/';
horizonRoot = basePath + '/src/horizon/';
horizonPath = basePath + '/src/horizon/horizon/';
openstackDashboardPath = basePath + '/src/horizon/openstack_dashboard/';
break;
}
}
if (!xstaticPath) {
console.error('xStatic libraries not found, please set up venv');
process.exit(1);
}
config.set({
preprocessors: {
// Used to collect templates for preprocessing.
// NOTE: the templates must also be listed in the files section below.
'./**/*.html': ['ng-html2js'],
// Used to indicate files requiring coverage reports.
'./craton_dashboard/static/**/!(*.spec).js': ['coverage']
},
// Sets up module to process templates.
ngHtml2JsPreprocessor: {
moduleName: 'templates',
cacheIdFromPath: function(filepath) {
// This function takes the raw provided path from the file searches
// below (in the files: pattern list), applies the filter from the
// preprocessor above (basically, finds the html files), then uses
// this function to translate the relative file path into a path
// that matches what would actually be called in production.
//
// e.g.
// dashboards/project/static/dashboard/project/workflow/launch-instance/configuration/load-edit.html
// becomes:
// /static/dashboard/project/workflow/launch-instance/configuration/load-edit.html
// We can't just use stripPrefix because there are a couple of
// prefixes that need to be altered (and may be more).
return filepath.replace(/^dashboards\/[^\/]+/, '')
.replace(/^static\/app/, '/static/app');
},
},
// This establishes the base for most referenced paths as being relative
// to this file, i.e. ./craton_dashboard.
basePath: '.',
// Contains both source and test files.
files: [
// from jasmine.html
xstaticPath + 'jquery/data/jquery.js',
xstaticPath + 'angular/data/angular.js',
xstaticPath + 'angular/data/angular-route.js',
xstaticPath + 'angular/data/angular-mocks.js',
xstaticPath + 'angular/data/angular-cookies.js',
xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
xstaticPath + 'angular_gettext/data/angular-gettext.js',
xstaticPath + 'angular_fileupload/data/ng-file-upload-all.js',
xstaticPath + 'angular/data/angular-sanitize.js',
xstaticPath + 'd3/data/d3.js',
xstaticPath + 'rickshaw/data/rickshaw.js',
xstaticPath + 'angular_smart_table/data/smart-table.js',
xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js',
xstaticPath + 'spin/data/spin.js',
xstaticPath + 'spin/data/spin.jquery.js',
xstaticPath + 'tv4/data/tv4.js',
xstaticPath + 'objectpath/data/ObjectPath.js',
xstaticPath + 'angular_schema_form/data/schema-form.js',
/**
* Include framework source code from horizon and openstack_dashboard
* that we need.
* Otherwise, karma will not be able to find them when testing.
* These files should be mocked in the foreseeable future.
* These are located within the project's ./.venv/horizon directory.
*/
// Getting horizon's test-shim.js for gettext modules and others
horizonRoot + 'test-shim.js',
horizonPath + 'static/horizon/js/horizon.js',
horizonPath + 'static/framework/**/*.module.js',
horizonPath + 'static/framework/**/!(*.spec|*.mock).js',
openstackDashboardPath + 'static/app/**/*.module.js',
openstackDashboardPath + 'static/app/**/!(*.spec|*.mock).js',
openstackDashboardPath + 'static/app/**/*.mock.js',
openstackDashboardPath + 'dashboards/**/static/**/**/*.module.js',
/**
* First, list all the files that defines application's angular modules.
* Those files have extension of `.module.js`. The order among them is
* not significant.
*/
'./craton_dashboard/static/app/core/**/*.module.js',
/**
* Followed by other JavaScript files that defines angular providers
* on the modules defined in files listed above. And they are not mock
* files or spec files defined below. The order among them is not
* significant.
*/
'./craton_dashboard/static/app/core/**/!(*.spec|*.mock).js',
/**
* Then, list files for mocks with `mock.js` extension. The order
* among them should not be significant.
*/
'./craton_dashboard/static/app/core/**/*.mock.js',
/**
* Finally, list files for spec with `spec.js` extension. The order
* among them should not be significant.
*/
'./craton_dashboard/static/app/core/**/*.spec.js',
/**
* Angular external templates
*/
'./craton_dashboard/static/app/core/**/*.html'
],
autoWatch: true,
frameworks: ['jasmine'],
browsers: ['Chrome'],
browserNoActivityTimeout: 60000,
reporters: ['progress', 'coverage', 'threshold'],
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-ng-html2js-preprocessor',
'karma-coverage',
'karma-threshold-reporter'
],
// Places coverage report in HTML format in the subdirectory below.
coverageReporter: {
type: 'html',
dir: '../cover/craton_dashboard'
},
// Coverage threshold values.
thresholdReporter: {
statements: 1, // target 100
branches: 1, // target 100
functions: 1, // target 100
lines: 1 // target 100
}
});
};

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"version": "0.0.0",
"private": true,
"name": "craton-dashboard",
"description": "OpenStack Craton Dashboard - Angular",
"repository": "none",
"license": "Apache 2.0",
"devDependencies": {
"eslint": "1.10.3",
"eslint-config-openstack": "1.2.4",
"eslint-plugin-angular": "1.0.1",
"jasmine-core": "2.4.1",
"karma": "1.1.2",
"karma-chrome-launcher": "1.0.1",
"karma-cli": "1.0.1",
"karma-coverage": "1.1.1",
"karma-jasmine": "1.0.2",
"karma-ng-html2js-preprocessor": "1.0.0",
"karma-threshold-reporter": "0.1.15"
},
"scripts": {
"postinstall": "if [ ! -d .venv ]; then tox -epy27 --notest; fi",
"test": "karma start ./karma.conf.js --single-run",
"lint": "eslint --no-color craton_dashboard/static",
"lintq": "eslint --quiet craton_dashboard/static"
},
"dependencies": {
"angular": "1.5.8"
}
}