Started xos-util tests and emproved readme
diff --git a/xos/configurations/frontend/README.md b/xos/configurations/frontend/README.md
index a964d91..7e8a771 100644
--- a/xos/configurations/frontend/README.md
+++ b/xos/configurations/frontend/README.md
@@ -13,3 +13,13 @@
- Run `make` command
You'll be able to visit XOS at `0.0.0.0:9000` and the `xos/core/xoslib` folder is shared with the container. This means that any update to that folder is automatically reported in the container.
+
+## Test
+
+To run the FE tests, navigate to: `xos/core/xoslib`, and run 'npm test'.
+
+This will install the required `npm` dependencies and run the test.
+
+Tests are runned in a headless browser (_PhantomJs_) by _Karma_ and the assertions are made with _Jasmine_. This is a pretty common standard for FE testing so you should feel at home.
+
+You can find the tests in the `spec/` folder, each source file has a corresponding `.test` file in it.
diff --git a/xos/core/xoslib/package.json b/xos/core/xoslib/package.json
index dd6714b..831f182 100644
--- a/xos/core/xoslib/package.json
+++ b/xos/core/xoslib/package.json
@@ -4,6 +4,7 @@
"description": "Add to the following in settings.py",
"main": "index.js",
"scripts": {
+ "pretest": "npm install",
"test": "karma start",
"lint": "eslint ."
},
diff --git a/xos/core/xoslib/spec/xoslib/utils.test.js b/xos/core/xoslib/spec/xoslib/utils.test.js
new file mode 100644
index 0000000..ad65067
--- /dev/null
+++ b/xos/core/xoslib/spec/xoslib/utils.test.js
@@ -0,0 +1,69 @@
+'use strict';
+
+describe('The XOS Lib Utilities', function() {
+ describe('The idInArray method', function() {
+ it('should match a string ID', () => {
+ let res = idInArray('1', [1, 2, 3]);
+ expect(res).toBeTruthy();
+ });
+
+ it('should march a number ID', () => {
+ let res = idInArray(1, [1, 2, 3]);
+ expect(res).toBeTruthy();
+ });
+
+ it('should not match this ID', () => {
+ let res = idInArray(4, [1, 2, 3]);
+ expect(res).toBeFalsy();
+ });
+ });
+
+ describe('The firstCharUpper', () => {
+ it('should return the first char UPPERCASE', () => {
+ let res = firstCharUpper('test');
+ expect(res).toEqual('Test');
+ });
+ });
+
+ describe('The toTitleCase', () => {
+ it('should convert all word\'s first letter to uppercase and the other to lowercase', () => {
+ let res = toTitleCase('tesT tEst');
+ expect(res).toEqual('Test Test');
+ });
+ });
+
+ describe('The fieldNameToHumanReadable method', () => {
+ it('should convert lodash to spaces and apply toTitleCase', () => {
+ let res = fieldNameToHumanReadable('tEst_fIelD');
+ expect(res).toEqual('Test Field')
+ });
+ });
+
+ describe('The limitTableRows', () => {
+ it('should be tested', () => {
+
+ });
+ });
+
+ describe('The validateField', () => {
+ it('should should validate notBlank', () => {
+ let res = validateField('notBlank', null);
+ expect(res).toEqual('can not be blank');
+ });
+
+ it('should validate a url', () => {
+ let res = validateField('url', 'test a fake url');
+ expect(res).toEqual('must be a valid url');
+ });
+
+ it('should validate a port', () => {
+ let res = validateField('portspec', 'i a not a port');
+ expect(res).toEqual('must be a valid portspec (example: \'tcp 123, udp 456-789\')');
+ });
+
+ it('should return true for a valid url', () => {
+ let res = validateField('url', 'www.onlab.us');
+ expect(res).toBeTruthy();
+ });
+ });
+});
\ No newline at end of file
diff --git a/xos/core/xoslib/static/js/xoslib/xos-backbone.js b/xos/core/xoslib/static/js/xoslib/xos-backbone.js
index dfc6c38..abce329 100644
--- a/xos/core/xoslib/static/js/xoslib/xos-backbone.js
+++ b/xos/core/xoslib/static/js/xoslib/xos-backbone.js
@@ -40,6 +40,8 @@
CORDSUBSCRIBER_API = XOSLIB_BASE + "/cordsubscriber/";
CORDUSER_API = XOSLIB_BASE + "/corduser/";
+ console.log(Backbone);
+
XOSModel = Backbone.Model.extend({
relatedCollections: [],
foreignCollections: [],
@@ -81,13 +83,13 @@
},
listMethods: function() {
- var res = [];
- for(var m in this) {
- if(typeof this[m] == "function") {
- res.push(m)
- }
- }
- return res;
+ var res = [];
+ for(var m in this) {
+ if(typeof this[m] == "function") {
+ res.push(m)
+ }
+ }
+ return res;
},
save: function(attributes, options) {
@@ -157,93 +159,93 @@
this.isLoaded = false;
this.failedLoad = false;
this.startedLoad = false;
- this.sortVar = 'name';
- this.sortOrder = 'asc';
- this.on( "sort", this.sorted );
- },
-
- relatedCollections: [],
- foreignCollections: [],
- foreignFields: {},
+ this.sortVar = 'name';
+ this.sortOrder = 'asc';
+ this.on( "sort", this.sorted );
+ },
+
+ relatedCollections: [],
+ foreignCollections: [],
+ foreignFields: {},
m2mFields: {},
readonlyFields: [],
- detailLinkFields: [],
-
- sorted: function() {
- //console.log("sorted " + this.modelName);
- },
-
- simpleComparator: function( model ){
- parts=this.sortVar.split(".");
- result = model.get(parts[0]);
- for (index=1; index<parts.length; ++index) {
- result=result[parts[index]];
- }
- return result;
- },
-
- comparator: function (left, right) {
- var l = this.simpleComparator(left);
- var r = this.simpleComparator(right);
-
- if (l === void 0) return -1;
- if (r === void 0) return 1;
-
- if (this.sortOrder=="desc") {
- return l < r ? 1 : l > r ? -1 : 0;
- } else {
- return l < r ? -1 : l > r ? 1 : 0;
- }
- },
-
- fetchSuccess: function(collection, response, options) {
- //console.log("fetch succeeded " + collection.modelName);
- this.failedLoad = false;
- this.fetching = false;
- if (!this.isLoaded) {
- this.isLoaded = true;
- Backbone.trigger("xoslib:collectionLoadChange", this);
- }
- this.trigger("fetchStateChange");
- if (options["orig_success"]) {
- options["orig_success"](collection, response, options);
- }
- },
-
- fetchFailure: function(collection, response, options) {
- //console.log("fetch failed " + collection.modelName);
- this.fetching = false;
- if ((!this.isLoaded) && (!this.failedLoad)) {
- this.failedLoad=true;
- Backbone.trigger("xoslib:collectionLoadChange", this);
- }
- this.trigger("fetchStateChange");
- if (options["orig_failure"]) {
- options["orig_failure"](collection, response, options);
- }
- },
-
- fetch: function(options) {
- var self=this;
- this.fetching=true;
- //console.log("fetch " + this.modelName);
- if (!this.startedLoad) {
- this.startedLoad=true;
- Backbone.trigger("xoslib:collectionLoadChange", this);
- }
- this.trigger("fetchStateChange");
- if (options == undefined) {
- options = {};
- }
- options["orig_success"] = options["success"];
- options["orig_failure"] = options["failure"];
- options["success"] = function(collection, response, options) { self.fetchSuccess.call(self, collection, response, options); };
- options["failure"] = this.fetchFailure;
- Backbone.Collection.prototype.fetch.call(this, options);
- },
-
- startPolling: function() {
- if (!this._polling) {
+ detailLinkFields: [],
+
+ sorted: function() {
+ //console.log("sorted " + this.modelName);
+ },
+
+ simpleComparator: function( model ){
+ parts=this.sortVar.split(".");
+ result = model.get(parts[0]);
+ for (index=1; index<parts.length; ++index) {
+ result=result[parts[index]];
+ }
+ return result;
+ },
+
+ comparator: function (left, right) {
+ var l = this.simpleComparator(left);
+ var r = this.simpleComparator(right);
+
+ if (l === void 0) return -1;
+ if (r === void 0) return 1;
+
+ if (this.sortOrder=="desc") {
+ return l < r ? 1 : l > r ? -1 : 0;
+ } else {
+ return l < r ? -1 : l > r ? 1 : 0;
+ }
+ },
+
+ fetchSuccess: function(collection, response, options) {
+ //console.log("fetch succeeded " + collection.modelName);
+ this.failedLoad = false;
+ this.fetching = false;
+ if (!this.isLoaded) {
+ this.isLoaded = true;
+ Backbone.trigger("xoslib:collectionLoadChange", this);
+ }
+ this.trigger("fetchStateChange");
+ if (options["orig_success"]) {
+ options["orig_success"](collection, response, options);
+ }
+ },
+
+ fetchFailure: function(collection, response, options) {
+ //console.log("fetch failed " + collection.modelName);
+ this.fetching = false;
+ if ((!this.isLoaded) && (!this.failedLoad)) {
+ this.failedLoad=true;
+ Backbone.trigger("xoslib:collectionLoadChange", this);
+ }
+ this.trigger("fetchStateChange");
+ if (options["orig_failure"]) {
+ options["orig_failure"](collection, response, options);
+ }
+ },
+
+ fetch: function(options) {
+ var self=this;
+ this.fetching=true;
+ //console.log("fetch " + this.modelName);
+ if (!this.startedLoad) {
+ this.startedLoad=true;
+ Backbone.trigger("xoslib:collectionLoadChange", this);
+ }
+ this.trigger("fetchStateChange");
+ if (options == undefined) {
+ options = {};
+ }
+ options["orig_success"] = options["success"];
+ options["orig_failure"] = options["failure"];
+ options["success"] = function(collection, response, options) { self.fetchSuccess.call(self, collection, response, options); };
+ options["failure"] = this.fetchFailure;
+ Backbone.Collection.prototype.fetch.call(this, options);
+ },
+
+ startPolling: function() {
+ if (!this._polling) {
var collection=this;
setInterval(function() { collection.fetch(); }, 10000);
this._polling=true;
@@ -333,13 +335,13 @@
},
listMethods: function() {
- var res = [];
- for(var m in this) {
- if(typeof this[m] == "function") {
- res.push(m)
- }
- }
- return res;
+ var res = [];
+ for(var m in this) {
+ if(typeof this[m] == "function") {
+ res.push(m)
+ }
+ }
+ return res;
},
});
@@ -787,29 +789,29 @@
xos = new xoslib();
function getCookie(name) {
- var cookieValue = null;
- if (document.cookie && document.cookie != '') {
- var cookies = document.cookie.split(';');
- for (var i = 0; i < cookies.length; i++) {
- var cookie = jQuery.trim(cookies[i]);
- // Does this cookie string begin with the name we want?
- if (cookie.substring(0, name.length + 1) == (name + '=')) {
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
- break;
- }
- }
- }
- return cookieValue;
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
}
(function() {
- var _sync = Backbone.sync;
- Backbone.sync = function(method, model, options){
- options.beforeSend = function(xhr){
- var token = getCookie("csrftoken");
- xhr.setRequestHeader('X-CSRFToken', token);
- };
- return _sync(method, model, options);
- };
+ var _sync = Backbone.sync;
+ Backbone.sync = function(method, model, options){
+ options.beforeSend = function(xhr){
+ var token = getCookie("csrftoken");
+ xhr.setRequestHeader('X-CSRFToken', token);
+ };
+ return _sync(method, model, options);
+ };
})();
}