diff --git a/CHANGELOG b/CHANGELOG index 945404249f..f6dd2e0627 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -71,12 +71,6 @@ v2.0.2 (XXXX-XX-XX) * during cluster startup, do not log (somewhat expected) connection errors with log level error, but with log level info -* fixed a memory barrier / cpu synchronisation problem with libev, affecting - Windows with Visual Studio 2013 (probably earlier versions are affected, too) - - The issue is described in detail here: - http://lists.schmorp.de/pipermail/libev/2014q1/002318.html - * fixed dashboard modals * fixed connection check for cluster planning front end: firefox does @@ -363,7 +357,28 @@ v2.0.0-rc1 (2014-02-28) * added collection status "loading" -v1.4.13 (XXXX-XX-XX) +v1.4.14 (XXXX-XX-XX) +-------------------- + +* fixed race conditions during shape / attribute insertion + + A race condition could have led to spurios `cannot find attribute #xx` or + `cannot find shape #xx` (where xx is a number) warning messages being logged + by the server. This happened when a new attribute was inserted and at the same + time was queried by another thread. + + Also fixed a race condition that may have occurred when a thread tried to + access the shapes / attributes hash tables while they were resized. In this + cases, the shape / attribute may have been hashed to a wrong slot. + +* fixed a memory barrier / cpu synchronisation problem with libev, affecting + Windows with Visual Studio 2013 (probably earlier versions are affected, too) + + The issue is described in detail here: + http://lists.schmorp.de/pipermail/libev/2014q1/002318.html + + +v1.4.13 (2014-03-14) -------------------- * added diagnostic output for Foxx application upload diff --git a/UnitTests/Basics/associative-synced-test.cpp b/UnitTests/Basics/associative-synced-test.cpp index e6a8105e5b..33978b8605 100644 --- a/UnitTests/Basics/associative-synced-test.cpp +++ b/UnitTests/Basics/associative-synced-test.cpp @@ -129,17 +129,17 @@ BOOST_AUTO_TEST_CASE (tst_insert_key_unique) { void* r = 0; ELEMENT(e1, (char*) "test1", 1, 2, 3) - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1, false)); BOOST_CHECK_EQUAL((size_t) 1, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e1, TRI_LookupByKeyAssociativeSynced(&a1, "test1")); ELEMENT(e2, (char*) "test2", 2, 3, 4) - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2, false)); BOOST_CHECK_EQUAL((size_t) 2, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e2, TRI_LookupByKeyAssociativeSynced(&a1, "test2")); ELEMENT(e3, (char*) "test3", 99, 3, 5) - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3, false)); BOOST_CHECK_EQUAL((size_t) 3, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e3, TRI_LookupByKeyAssociativeSynced(&a1, "test3")); @@ -156,27 +156,27 @@ BOOST_AUTO_TEST_CASE (tst_insert_key_nonunique) { void* r = 0; ELEMENT(e1, (char*) "test1", 1, 2, 3) - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1, false)); BOOST_CHECK_EQUAL((size_t) 1, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e1, TRI_LookupByKeyAssociativeSynced(&a1, "test1")); ELEMENT(e2, (char*) "test1", 2, 3, 4) - BOOST_CHECK_EQUAL(&e1, TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2)); + BOOST_CHECK_EQUAL(&e1, TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2, false)); BOOST_CHECK_EQUAL((size_t) 1, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e1, TRI_LookupByKeyAssociativeSynced(&a1, "test1")); ELEMENT(e3, (char*) "test2", 99, 3, 5) - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3, false)); BOOST_CHECK_EQUAL((size_t) 2, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e3, TRI_LookupByKeyAssociativeSynced(&a1, "test2")); ELEMENT(e4, (char*) "test1", 99, 3, 5) - BOOST_CHECK_EQUAL(&e1, TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4)); + BOOST_CHECK_EQUAL(&e1, TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4, false)); BOOST_CHECK_EQUAL((size_t) 2, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e1, TRI_LookupByKeyAssociativeSynced(&a1, "test1")); ELEMENT(e5, (char*) "test2", -99, 33, 15) - BOOST_CHECK_EQUAL(&e3, TRI_InsertKeyAssociativeSynced(&a1, e5.key, &e5)); + BOOST_CHECK_EQUAL(&e3, TRI_InsertKeyAssociativeSynced(&a1, e5.key, &e5, false)); BOOST_CHECK_EQUAL((size_t) 2, TRI_GetLengthAssociativeSynced(&a1)); BOOST_CHECK_EQUAL(&e3, TRI_LookupByKeyAssociativeSynced(&a1, "test2")); @@ -193,16 +193,16 @@ BOOST_AUTO_TEST_CASE (tst_lookup_key) { void* r = 0; ELEMENT(e1, (char*) "test1", 1, 2, 3) - TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1); + TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1, false); ELEMENT(e2, (char*) "test2", 2, 3, 4) - TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2); + TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2, false); ELEMENT(e3, (char*) "test3", 3, 4, 5) - TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3); + TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3, false); ELEMENT(e4, (char*) "test4", 4, 5, 6) - TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4); + TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4, false); data_container_t* r1 = (data_container_t*) TRI_LookupByKeyAssociativeSynced(&a1, "test1"); BOOST_CHECK_EQUAL(&e1, r1); @@ -250,16 +250,16 @@ BOOST_AUTO_TEST_CASE (tst_remove_key) { void* r = 0; ELEMENT(e1, (char*) "test1", 1, 2, 3) - TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1); + TRI_InsertKeyAssociativeSynced(&a1, e1.key, &e1, false); ELEMENT(e2, (char*) "test2", 2, 3, 4) - TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2); + TRI_InsertKeyAssociativeSynced(&a1, e2.key, &e2, false); ELEMENT(e3, (char*) "test3", 3, 4, 5) - TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3); + TRI_InsertKeyAssociativeSynced(&a1, e3.key, &e3, false); ELEMENT(e4, (char*) "test4", 4, 5, 6) - TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4); + TRI_InsertKeyAssociativeSynced(&a1, e4.key, &e4, false); data_container_t* r1 = (data_container_t*) TRI_RemoveKeyAssociativeSynced(&a1, "test1"); BOOST_CHECK_EQUAL(&e1, r1); @@ -352,7 +352,7 @@ BOOST_AUTO_TEST_CASE (tst_mass_insert) { e->b = i + 1; e->c = i + 2; - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e->key, e)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e->key, e, false)); BOOST_CHECK_EQUAL(i, TRI_GetLengthAssociativeSynced(&a1)); data_container_t* s = (data_container_t*) TRI_LookupByKeyAssociativeSynced(&a1, key); @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE (tst_mass_insert_remove) { e->b = i + 1; e->c = i + 2; - BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e->key, e)); + BOOST_CHECK_EQUAL(r, TRI_InsertKeyAssociativeSynced(&a1, e->key, e, false)); BOOST_CHECK_EQUAL(i, TRI_GetLengthAssociativeSynced(&a1)); data_container_t* s = (data_container_t*) TRI_LookupByKeyAssociativeSynced(&a1, key); diff --git a/arangod/VocBase/voc-shaper.cpp b/arangod/VocBase/voc-shaper.cpp index 5c9f5c50b8..9999d4016a 100644 --- a/arangod/VocBase/voc-shaper.cpp +++ b/arangod/VocBase/voc-shaper.cpp @@ -464,11 +464,11 @@ static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper, dfi->_sizeAttributes += (int64_t) TRI_DF_ALIGN_BLOCK(totalSize); } - // enter into the dictionaries - f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, result); + f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, result, false); assert(f == NULL); - - f = TRI_InsertKeyAssociativeSynced(&s->_attributeIds, &aid, result); + + // enter into the dictionaries + f = TRI_InsertKeyAssociativeSynced(&s->_attributeNames, name, result, false); assert(f == NULL); // ........................................................................... @@ -748,11 +748,11 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper, // enter into the dictionaries l = (TRI_shape_t*) (((char*) result) + sizeof(TRI_df_shape_marker_t)); - - f = TRI_InsertElementAssociativeSynced(&s->_shapeDictionary, l); + + f = TRI_InsertKeyAssociativeSynced(&s->_shapeIds, &l->_sid, l, false); assert(f == NULL); - f = TRI_InsertKeyAssociativeSynced(&s->_shapeIds, &l->_sid, l); + f = TRI_InsertElementAssociativeSynced(&s->_shapeDictionary, l, false); assert(f == NULL); TRI_UnlockMutex(&s->_shapeLock); @@ -1299,20 +1299,14 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s, TRI_LockMutex(&shaper->_shapeLock); // remove the old marker - f = TRI_RemoveKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid); + // and re-insert the marker with the new pointer + f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l, true); assert(f != NULL); - - // re-insert the marker with the new pointer - f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l); - assert(f == NULL); // same for the shape dictionary - f = TRI_RemoveElementAssociativeSynced(&shaper->_shapeDictionary, l); + // delete and re-insert + f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l, true); assert(f != NULL); - - // re-insert - f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l); - assert(f == NULL); TRI_UnlockMutex(&shaper->_shapeLock); } @@ -1325,20 +1319,14 @@ int TRI_MoveMarkerVocShaper (TRI_shaper_t* s, // remove attribute by name (p points to new location of name, but names // are identical in old and new marker) - f = TRI_RemoveKeyAssociativeSynced(&shaper->_attributeNames, p); + // and re-insert same attribute with adjusted pointer + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m, true); assert(f != NULL); - - // now re-insert same attribute with adjusted pointer - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m); - assert(f == NULL); // same for attribute ids - f = TRI_RemoveKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid); + // delete and re-insert same attribute with adjusted pointer + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m, true); assert(f != NULL); - - // now re-insert same attribute with adjusted pointer - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m); - assert(f == NULL); TRI_UnlockMutex(&shaper->_attributeLock); } @@ -1359,10 +1347,10 @@ int TRI_InsertShapeVocShaper (TRI_shaper_t* s, LOG_TRACE("found shape %lu", (unsigned long) l->_sid); - f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l); + f = TRI_InsertElementAssociativeSynced(&shaper->_shapeDictionary, l, false); assert(f == NULL); - f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l); + f = TRI_InsertKeyAssociativeSynced(&shaper->_shapeIds, &l->_sid, l, false); assert(f == NULL); if (shaper->_nextSid <= l->_sid) { @@ -1385,7 +1373,7 @@ int TRI_InsertAttributeVocShaper (TRI_shaper_t* s, LOG_TRACE("found attribute '%s', aid: %lu", p, (unsigned long) m->_aid); - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m); + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeNames, p, m, false); if (f != NULL) { char const* name = shaper->_collection->base.base._info._name; @@ -1397,7 +1385,7 @@ int TRI_InsertAttributeVocShaper (TRI_shaper_t* s, #endif } - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m); + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributeIds, &m->_aid, m, false); if (f != NULL) { char const* name = shaper->_collection->base.base._info._name; diff --git a/js/apps/system/aardvark/frontend/js/views/clusterCollectionView.js b/js/apps/system/aardvark/frontend/js/views/clusterCollectionView.js deleted file mode 100644 index e483c7fb41..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterCollectionView.js +++ /dev/null @@ -1,61 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterCollectionView = Backbone.View.extend({ - - el: '#clusterCollections', - - template: templateEngine.createTemplate("clusterCollectionView.ejs"), - - events: { - "click .collection": "loadCollection" - }, - - initialize: function() { - this.shardsView = new window.ClusterShardsView({ - collection: new window.ClusterShards() - }); - var rerender = function() { - this.render(this.db, this.server); - }; - this.collection.bind("add", rerender.bind(this)); - this.collection.bind("change", rerender.bind(this)); - this.collection.bind("remove", rerender.bind(this)); - }, - - loadCollection: function(e) { - var id = e.currentTarget.id; - this.shardsView.render( - this.db, - id, - this.server - ); - }, - - unrender: function() { - $(this.el).html(""); - this.shardsView.unrender(); - }, - - stopUpdating: function() { - this.collection.stopUpdating(); - this.shardsView.stopUpdating(); - }, - - render: function(db, server) { - this.db = db; - this.server = server; - this.collection.startUpdating(); - $(this.el).html(this.template.render({ - collections: this.collection.getList(this.db) - })); - this.shardsView.unrender(); - return this; - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterCoordinatorView.js b/js/apps/system/aardvark/frontend/js/views/clusterCoordinatorView.js deleted file mode 100644 index f138d25dcc..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterCoordinatorView.js +++ /dev/null @@ -1,26 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterCoordinatorView = Backbone.View.extend({ - - el: '#clusterServers', - - template: templateEngine.createTemplate("clusterCoordinatorView.ejs"), - - unrender: function() { - $(this.el).html(""); - }, - - render: function() { - $(this.el).html(this.template.render({ - coordinators: this.collection.getList() - })); - return this; - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterDashboardView.js b/js/apps/system/aardvark/frontend/js/views/clusterDashboardView.js deleted file mode 100644 index c40f9dcdd5..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterDashboardView.js +++ /dev/null @@ -1,36 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterDashboardView = Backbone.View.extend({ - - el: '#content', - - template: templateEngine.createTemplate("clusterDashboardView.ejs"), - - initialize: function() { - this.dbservers = new window.ClusterServers(); - this.coordinators = new window.ClusterCoordinators(); - }, - - render: function(){ - $(this.el).html(this.template.render({})); - if (!this.overView) { - this.overView = new window.ClusterOverviewView({ - dbservers: this.dbservers, - coordinators: this.coordinators - }); - } - this.overView.render(); - return this; - }, - - stopUpdating: function() { - this.overView.stopUpdating(); - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterDatabaseView.js b/js/apps/system/aardvark/frontend/js/views/clusterDatabaseView.js deleted file mode 100644 index bfbd1fa6ca..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterDatabaseView.js +++ /dev/null @@ -1,56 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterDatabaseView = Backbone.View.extend({ - - el: '#clusterDatabases', - - template: templateEngine.createTemplate("clusterDatabaseView.ejs"), - - events: { - "click .database": "loadDatabase" - }, - - initialize: function() { - this.colView = new window.ClusterCollectionView({ - collection: new window.ClusterCollections() - }); - var rerender = function() { - this.render(this.server); - }; - this.collection.bind("add", rerender.bind(this)); - this.collection.bind("change", rerender.bind(this)); - this.collection.bind("remove", rerender.bind(this)); - }, - - loadDatabase: function(e) { - var id = e.currentTarget.id; - this.colView.render(id, this.server); - }, - - unrender: function() { - $(this.el).html(""); - this.colView.unrender(); - }, - - stopUpdating: function() { - this.collection.stopUpdating(); - this.colView.stopUpdating(); - }, - - render: function(server) { - this.server = server; - this.collection.startUpdating(); - $(this.el).html(this.template.render({ - databases: this.collection.getList() - })); - this.colView.unrender(); - return this; - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js b/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js deleted file mode 100644 index 8cb3e40363..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterOverviewView.js +++ /dev/null @@ -1,84 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true */ -/*global Backbone, templateEngine, window, $ */ - -(function() { - "use strict"; - - window.ClusterOverviewView = Backbone.View.extend({ - - el: '#clusterOverview', - - template: templateEngine.createTemplate("clusterOverviewView.ejs"), - - events: { - "click #dbserver": "loadDBServers", - "click #coordinator": "loadCoordinators" - }, - - initialize: function() { - this.isMinified = false; - this.dbservers = this.options.dbservers; - this.coordinators = this.options.coordinators; - this.serverView = new window.ClusterServerView({ - collection: this.dbservers - }); - this.coordinatorView = new window.ClusterCoordinatorView({ - collection: this.coordinators - }); - var rerender = function() { - this.render(this.isMinified); - if (this.selectedSub === "server") { - this.serverView.render(this.serverView.isMinified); - } - if (this.selectedSub === "coordinators") { - this.coordinatorView.render(); - } - }; - this.selectedSub = null; - this.dbservers.bind("add", rerender.bind(this)); - this.dbservers.bind("change", rerender.bind(this)); - this.dbservers.bind("remove", rerender.bind(this)); - this.coordinators.bind("add", rerender.bind(this)); - this.coordinators.bind("change", rerender.bind(this)); - this.coordinators.bind("remove", rerender.bind(this)); - }, - - loadDBServers: function() { - this.selectedSub = "server"; - this.coordinatorView.unrender(); - this.serverView.render(); - this.render(true); - }, - - loadCoordinators: function() { - this.selectedSub = "coordinators"; - this.serverView.unrender(); - this.coordinatorView.render(); - this.render(true); - }, - - stopUpdating: function() { - this.dbservers.stopUpdating(); - this.coordinators.stopUpdating(); - this.serverView.stopUpdating(); - }, - - render: function(minify){ - this.dbservers.startUpdating(); - this.coordinators.startUpdating(); - this.isMinified = !!minify; - if (!minify) { - this.selectedSub = null; - } - $(this.el).html(this.template.render({ - minify: minify, - dbservers: this.dbservers.getOverview(), - coordinators: this.coordinators.getOverview() - })); - $(this.el).toggleClass("clusterColumnMax", !minify); - return this; - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterServerView.js b/js/apps/system/aardvark/frontend/js/views/clusterServerView.js deleted file mode 100644 index 0e1f8cfe0e..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterServerView.js +++ /dev/null @@ -1,53 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterServerView = Backbone.View.extend({ - - el: '#clusterServers', - - template: templateEngine.createTemplate("clusterServerView.ejs"), - - events: { - "click .server": "loadServer" - }, - - initialize: function() { - this.dbView = new window.ClusterDatabaseView({ - collection: new window.ClusterDatabases() - }); - this.isMinified = false; - }, - - loadServer: function(e) { - var id = e.currentTarget.id; - this.dbView.render(id); - this.render(true); - }, - - stopUpdating: function() { - this.dbView.stopUpdating(); - }, - - unrender: function() { - $(this.el).html(""); - this.dbView.unrender(); - }, - - render: function(minify){ - this.isMinified = !!minify; - if(!minify) { - this.dbView.unrender(); - } - $(this.el).html(this.template.render({ - minify: minify, - servers: this.collection.getList() - })); - return this; - } - - }); - -}()); diff --git a/js/apps/system/aardvark/frontend/js/views/clusterShardsView.js b/js/apps/system/aardvark/frontend/js/views/clusterShardsView.js deleted file mode 100644 index e67e1644bf..0000000000 --- a/js/apps/system/aardvark/frontend/js/views/clusterShardsView.js +++ /dev/null @@ -1,46 +0,0 @@ -/*jslint indent: 2, nomen: true, maxlen: 100, vars: true, white: true, plusplus: true*/ -/*global Backbone, templateEngine, $, window */ - -(function() { - "use strict"; - - window.ClusterShardsView = Backbone.View.extend({ - - el: '#clusterShards', - - template: templateEngine.createTemplate("clusterShardsView.ejs"), - - initialize: function() { - var rerender = function() { - if ($(this.el).html().trim() !== "") { - this.render(this.db, this.col, this.server); - } - }; - this.collection.bind("add", rerender.bind(this)); - this.collection.bind("change", rerender.bind(this)); - this.collection.bind("remove", rerender.bind(this)); - }, - - unrender: function() { - $(this.el).html(""); - }, - - stopUpdating: function() { - this.collection.stopUpdating(); - }, - - render: function(db, col, server) { - this.db = db; - this.col = col; - this.server = server; - this.collection.startUpdating(); - $(this.el).html(this.template.render({ - shards: this.collection.getList(db, col, server) - })); - return this; - } - - }); - -}()); - diff --git a/js/apps/system/aardvark/frontend/js/views/documentsView.js b/js/apps/system/aardvark/frontend/js/views/documentsView.js index dfb531f2ab..84fd73b5dc 100644 --- a/js/apps/system/aardvark/frontend/js/views/documentsView.js +++ b/js/apps/system/aardvark/frontend/js/views/documentsView.js @@ -498,24 +498,11 @@ drawTable: function() { var self = this; - /* - if (this.addDocumentSwitch === true) { - $(self.table).dataTable().fnAddData( - [ - 'Add document', - '', - '' - ] - ); - }*/ - - if (window.arangoDocumentsStore.models.length === 0) { + if (window.arangoDocumentsStore.models.length === 0) { $('.dataTables_empty').text('No documents'); } else { - $.each(window.arangoDocumentsStore.models, function(key, value) { - var tempObj = {}; $.each(value.attributes.content, function(k, v) { if (! (k === '_id' || k === '_rev' || k === '_key')) { @@ -679,7 +666,7 @@ }); return fields; }, - createIndex: function (e) { + createIndex: function () { //e.preventDefault(); var self = this; var collection = this.collectionName; diff --git a/js/apps/system/aardvark/test/karma/files.json b/js/apps/system/aardvark/test/karma/files.json index eb45c50443..ef3b8a0216 100755 --- a/js/apps/system/aardvark/test/karma/files.json +++ b/js/apps/system/aardvark/test/karma/files.json @@ -164,13 +164,6 @@ "frontend/js/views/dbSelectionView.js", "frontend/js/views/editListEntryView.js", "frontend/js/views/loginView.js", - "frontend/js/views/clusterDashboardView.js", - "frontend/js/views/clusterOverviewView.js", - "frontend/js/views/clusterServerView.js", - "frontend/js/views/clusterCoordinatorView.js", - "frontend/js/views/clusterDatabaseView.js", - "frontend/js/views/clusterCollectionView.js", - "frontend/js/views/clusterShardsView.js", "frontend/js/views/userManagementView.js", "frontend/js/views/userProfileView.js", "frontend/js/views/userBarView.js", diff --git a/js/apps/system/aardvark/test/specs/collections/arangoCollectionsSpec.js b/js/apps/system/aardvark/test/specs/collections/arangoCollectionsSpec.js index 3eba6b2e95..2b4c17c4ee 100644 --- a/js/apps/system/aardvark/test/specs/collections/arangoCollectionsSpec.js +++ b/js/apps/system/aardvark/test/specs/collections/arangoCollectionsSpec.js @@ -287,7 +287,7 @@ expect(opt.processData).toEqual(false); expect(opt.data).toEqual(JSON.stringify( { - name: "heinz", waitForSync: true, isSystem: true, + name: "heinz", waitForSync: true, journalSize :2, isSystem: true, type: 3, numberOfShards: 3, shardKeys: ["a", "b", "c"] } )); @@ -310,7 +310,7 @@ expect(opt.processData).toEqual(false); expect(opt.data).toEqual(JSON.stringify( { - name: "heinz", waitForSync: true, isSystem: true, + name: "heinz", waitForSync: true, journalSize: 2, isSystem: true, type: 3, numberOfShards: 3, shardKeys: ["a", "b", "c"] } )); diff --git a/js/apps/system/aardvark/test/specs/views/documentsViewSpec.js b/js/apps/system/aardvark/test/specs/views/documentsViewSpec.js index ef2c818863..b6d706f134 100644 --- a/js/apps/system/aardvark/test/specs/views/documentsViewSpec.js +++ b/js/apps/system/aardvark/test/specs/views/documentsViewSpec.js @@ -1,1795 +1,2780 @@ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true, browser: true*/ -/*global describe, beforeEach, afterEach, it, spyOn, expect*/ +/*global $, arangoHelper, jasmine, describe, beforeEach, afterEach, it, spyOn, expect*/ -(function() { - "use strict"; +(function () { + "use strict"; - describe("The documents view", function() { + describe("The documents view", function () { - var view, jQueryDummy; + var view, jQueryDummy; - beforeEach(function() { - view = new window.DocumentsView(); - }); - - it("assert the basics", function() { - expect(view.collectionID).toEqual(0); - expect(view.currentPage).toEqual(1); - expect(view.documentsPerPage).toEqual(10); - expect(view.totalPages).toEqual(1); - expect(view.filters).toEqual({ "0" : true }); - expect(view.filterId).toEqual(0); - expect(view.addDocumentSwitch).toEqual(true); - expect(view.allowUpload).toEqual(false); - expect(view.collectionContext).toEqual({ - prev: null, - next: null + beforeEach(function () { + view = new window.DocumentsView(); }); - expect(view.alreadyClicked).toEqual(false); - expect(view.table).toEqual('#documentsTableID'); - expect(view.events).toEqual({ - "click #collectionPrev" : "prevCollection", - "click #collectionNext" : "nextCollection", - "click #filterCollection" : "filterCollection", - "click #indexCollection" : "indexCollection", - "click #importCollection" : "importCollection", - "click #filterSend" : "sendFilter", - "click #addFilterItem" : "addFilterItem", - "click .removeFilterItem" : "removeFilterItem", - "click #confirmCreateEdge" : "addEdge", - "click #documentsTableID tr" : "clicked", - "click #deleteDoc" : "remove", - "click #addDocumentButton" : "addDocument", - "click #documents_first" : "firstDocuments", - "click #documents_last" : "lastDocuments", - "click #documents_prev" : "prevDocuments", - "click #documents_next" : "nextDocuments", - "click #confirmDeleteBtn" : "confirmDelete", - "keyup #createEdge" : "listenKey", - "click .key" : "nop", - "keyup" : "returnPressedHandler", - "keydown .filterValue" : "filterValueKeydown", - "click #importModal" : "showImportModal", - "click #resetView" : "resetView", - "click #confirmDocImport" : "startUpload", - "change #newIndexType" : "selectIndexType", - "click #createIndex" : "createIndex", - "click .deleteIndex" : "prepDeleteIndex", - "click #confirmDeleteIndexBtn" : "deleteIndex", - "click #documentsToolbar ul" : "resetIndexForms", - "click #indexHeader #addIndex" : "toggleNewIndexView", - "click #indexHeader #cancelIndex" : "toggleNewIndexView" + + it("assert the basics", function () { + expect(view.collectionID).toEqual(0); + expect(view.currentPage).toEqual(1); + expect(view.documentsPerPage).toEqual(10); + expect(view.totalPages).toEqual(1); + expect(view.filters).toEqual({ "0": true }); + expect(view.filterId).toEqual(0); + expect(view.addDocumentSwitch).toEqual(true); + expect(view.allowUpload).toEqual(false); + expect(view.collectionContext).toEqual({ + prev: null, + next: null + }); + expect(view.alreadyClicked).toEqual(false); + expect(view.table).toEqual('#documentsTableID'); + expect(view.events).toEqual({ + "click #collectionPrev": "prevCollection", + "click #collectionNext": "nextCollection", + "click #filterCollection": "filterCollection", + "click #indexCollection": "indexCollection", + "click #importCollection": "importCollection", + "click #filterSend": "sendFilter", + "click #addFilterItem": "addFilterItem", + "click .removeFilterItem": "removeFilterItem", + "click #confirmCreateEdge": "addEdge", + "click #documentsTableID tr": "clicked", + "click #deleteDoc": "remove", + "click #addDocumentButton": "addDocument", + "click #documents_first": "firstDocuments", + "click #documents_last": "lastDocuments", + "click #documents_prev": "prevDocuments", + "click #documents_next": "nextDocuments", + "click #confirmDeleteBtn": "confirmDelete", + "keyup #createEdge": "listenKey", + "click .key": "nop", + "keyup": "returnPressedHandler", + "keydown .filterValue": "filterValueKeydown", + "click #importModal": "showImportModal", + "click #resetView": "resetView", + "click #confirmDocImport": "startUpload", + "change #newIndexType": "selectIndexType", + "click #createIndex": "createIndex", + "click .deleteIndex": "prepDeleteIndex", + "click #confirmDeleteIndexBtn": "deleteIndex", + "click #documentsToolbar ul": "resetIndexForms", + "click #indexHeader #addIndex": "toggleNewIndexView", + "click #indexHeader #cancelIndex": "toggleNewIndexView" + }); }); + + + it("showSpinner", function () { + jQueryDummy = { + show: function () { + } + }; + spyOn(jQueryDummy, "show"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.showSpinner(); + expect(window.$).toHaveBeenCalledWith("#uploadIndicator"); + expect(jQueryDummy.show).toHaveBeenCalled(); + }); + + it("hideSpinner", function () { + jQueryDummy = { + hide: function () { + } + }; + spyOn(jQueryDummy, "hide"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.hideSpinner(); + expect(window.$).toHaveBeenCalledWith("#uploadIndicator"); + expect(jQueryDummy.hide).toHaveBeenCalled(); + }); + + + it("showImportModal", function () { + jQueryDummy = { + modal: function () { + } + }; + spyOn(jQueryDummy, "modal"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.showImportModal(); + expect(window.$).toHaveBeenCalledWith("#docImportModal"); + expect(jQueryDummy.modal).toHaveBeenCalledWith("show"); + }); + + + it("hideImportModal", function () { + jQueryDummy = { + modal: function () { + } + }; + spyOn(jQueryDummy, "modal"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.hideImportModal(); + expect(window.$).toHaveBeenCalledWith("#docImportModal"); + expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); + }); + + + it("returnPressedHandler call confirmDelete if keyCode == 13", function () { + jQueryDummy = { + attr: function () { + return false; + } + }; + spyOn(jQueryDummy, "attr").andCallThrough(); + spyOn(window, "$").andReturn( + jQueryDummy + ); + spyOn(view, "confirmDelete").andCallFake(function () { + }); + view.returnPressedHandler({keyCode: 13}); + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled"); + expect(view.confirmDelete).toHaveBeenCalled(); + }); + + it("returnPressedHandler does not call confirmDelete if keyCode !== 13", function () { + jQueryDummy = { + attr: function () { + return false; + } + }; + spyOn(jQueryDummy, "attr"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + spyOn(view, "confirmDelete").andCallFake(function () { + }); + view.returnPressedHandler({keyCode: 11}); + expect(jQueryDummy.attr).not.toHaveBeenCalled(); + expect(view.confirmDelete).not.toHaveBeenCalled(); + }); + + it("returnPressedHandler does not call confirmDelete if keyCode == 13 but" + + " confirmButton is disabled", function () { + jQueryDummy = { + attr: function () { + return true; + } + }; + spyOn(jQueryDummy, "attr"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + spyOn(view, "confirmDelete").andCallFake(function () { + }); + view.returnPressedHandler({keyCode: 13}); + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled"); + expect(view.confirmDelete).not.toHaveBeenCalled(); + }); + + it("toggleNewIndexView", function () { + jQueryDummy = { + toggle: function () { + } + }; + spyOn(jQueryDummy, "toggle"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + spyOn(view, "resetIndexForms").andCallFake(function () { + }); + view.toggleNewIndexView(); + expect(window.$).toHaveBeenCalledWith("#indexEditView"); + expect(window.$).toHaveBeenCalledWith("#newIndexView"); + expect(jQueryDummy.toggle).toHaveBeenCalledWith("fast"); + expect(view.resetIndexForms).toHaveBeenCalled(); + }); + + + it("nop", function () { + var event = {stopPropagation: function () { + }}; + spyOn(event, "stopPropagation"); + view.nop(event); + expect(event.stopPropagation).toHaveBeenCalled(); + }); + + it("listenKey with keyCode 13", function () { + spyOn(view, "addEdge"); + view.listenKey({keyCode: 13}); + expect(view.addEdge).toHaveBeenCalled(); + }); + + it("listenKey with keyCode != 13", function () { + spyOn(view, "addEdge"); + view.listenKey({keyCode: 12}); + expect(view.addEdge).not.toHaveBeenCalled(); + }); + + + it("resetView", function () { + jQueryDummy = { + val: function () { + }, + css: function () { + } + }; + spyOn(jQueryDummy, "val"); + spyOn(jQueryDummy, "css"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + spyOn(view, "removeAllFilterItems").andCallFake(function () { + }); + spyOn(view, "clearTable").andCallFake(function () { + }); + var arangoDocStoreDummy = { + getDocuments: function () { + } + }; + spyOn(arangoDocStoreDummy, "getDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + view.resetView(); + expect(window.$).toHaveBeenCalledWith("input"); + expect(window.$).toHaveBeenCalledWith("select"); + expect(window.$).toHaveBeenCalledWith("#documents_last"); + expect(window.$).toHaveBeenCalledWith("#documents_first"); + expect(jQueryDummy.val).toHaveBeenCalledWith(''); + expect(jQueryDummy.val).toHaveBeenCalledWith('=='); + expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "visible"); + expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "visible"); + expect(arangoDocStoreDummy.getDocuments).toHaveBeenCalledWith(view.collectionID, 1); + expect(view.removeAllFilterItems).toHaveBeenCalled(); + expect(view.clearTable).toHaveBeenCalled(); + expect(view.addDocumentSwitch).toEqual(true); + }); + + + it("start succesful Upload mit XHR ready state = 4, " + + "XHR status = 201 and parseable JSON", function () { + spyOn(view, "showSpinner"); + spyOn(view, "hideSpinner"); + spyOn(view, "hideImportModal"); + spyOn(view, "resetView"); + spyOn($, "ajax").andCallFake(function (opt) { + expect(opt.url).toEqual('/_api/import?type=auto&collection=' + + encodeURIComponent(view.colid) + + '&createCollection=false'); + expect(opt.dataType).toEqual("json"); + expect(opt.contentType).toEqual("json"); + expect(opt.processData).toEqual(false); + expect(opt.data).toEqual(view.file); + expect(opt.async).toEqual(false); + expect(opt.type).toEqual("POST"); + opt.complete({readyState: 4, status: 201, responseText: '{"a" : 1}'}); + }); + + view.allowUpload = true; + + view.startUpload(); + expect(view.showSpinner).toHaveBeenCalled(); + expect(view.hideSpinner).toHaveBeenCalled(); + expect(view.hideImportModal).toHaveBeenCalled(); + expect(view.resetView).toHaveBeenCalled(); + }); + + it("start succesful Upload mit XHR ready state != 4", function () { + spyOn(view, "showSpinner"); + spyOn(view, "hideSpinner"); + spyOn(view, "hideImportModal"); + spyOn(view, "resetView"); + spyOn($, "ajax").andCallFake(function (opt) { + expect(opt.url).toEqual('/_api/import?type=auto&collection=' + + encodeURIComponent(view.colid) + + '&createCollection=false'); + expect(opt.dataType).toEqual("json"); + expect(opt.contentType).toEqual("json"); + expect(opt.processData).toEqual(false); + expect(opt.data).toEqual(view.file); + expect(opt.async).toEqual(false); + expect(opt.type).toEqual("POST"); + opt.complete({readyState: 3, status: 201, responseText: '{"a" : 1}'}); + }); + + view.allowUpload = true; + spyOn(arangoHelper, "arangoError"); + view.startUpload(); + expect(view.showSpinner).toHaveBeenCalled(); + expect(view.hideSpinner).toHaveBeenCalled(); + expect(view.hideImportModal).not.toHaveBeenCalled(); + expect(view.resetView).not.toHaveBeenCalled(); + expect(arangoHelper.arangoError).toHaveBeenCalledWith("Upload error"); + }); + + it("start succesful Upload mit XHR ready state = 4, " + + "XHR status = 201 and not parseable JSON", function () { + spyOn(view, "showSpinner"); + spyOn(view, "hideSpinner"); + spyOn(view, "hideImportModal"); + spyOn(view, "resetView"); + spyOn($, "ajax").andCallFake(function (opt) { + expect(opt.url).toEqual('/_api/import?type=auto&collection=' + + encodeURIComponent(view.colid) + + '&createCollection=false'); + expect(opt.dataType).toEqual("json"); + expect(opt.contentType).toEqual("json"); + expect(opt.processData).toEqual(false); + expect(opt.data).toEqual(view.file); + expect(opt.async).toEqual(false); + expect(opt.type).toEqual("POST"); + opt.complete({readyState: 4, status: 201, responseText: "blub"}); + }); + + view.allowUpload = true; + spyOn(arangoHelper, "arangoError"); + view.startUpload(); + expect(view.showSpinner).toHaveBeenCalled(); + expect(view.hideSpinner).toHaveBeenCalled(); + expect(view.hideImportModal).toHaveBeenCalled(); + expect(view.resetView).toHaveBeenCalled(); + expect(arangoHelper.arangoError).toHaveBeenCalledWith( + 'Error: SyntaxError: Unable to parse JSON string' + ); + }); + + + it("uploadSetup", function () { + jQueryDummy = { + change: function (e) { + e({target: {files: ["BLUB"]}}); + } + }; + spyOn(jQueryDummy, "change").andCallThrough(); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.uploadSetup(); + expect(window.$).toHaveBeenCalledWith("#importDocuments"); + expect(jQueryDummy.change).toHaveBeenCalledWith(jasmine.any(Function)); + expect(view.files).toEqual(["BLUB"]); + expect(view.file).toEqual("BLUB"); + expect(view.allowUpload).toEqual(true); + }); + + it("buildCollectionLink", function () { + expect(view.buildCollectionLink({get: function () { + return "blub"; + }})).toEqual( + "collection/" + encodeURIComponent("blub") + '/documents/1' + ); + }); + + + it("prevCollection with no collectionContext.prev", function () { + jQueryDummy = { + parent: function (e) { + return jQueryDummy; + }, + addClass: function () { + + } + + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "addClass"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.collectionContext = {prev: null}; + view.prevCollection(); + expect(window.$).toHaveBeenCalledWith("#collectionPrev"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.addClass).toHaveBeenCalledWith("disabledPag"); + }); + + it("prevCollection with collectionContext.prev", function () { + jQueryDummy = { + parent: function (e) { + return jQueryDummy; + }, + removeClass: function () { + + } + + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "removeClass"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.collectionContext = {prev: 1}; + spyOn(window.App, "navigate"); + spyOn(view, "buildCollectionLink").andReturn(1); + view.prevCollection(); + expect(window.$).toHaveBeenCalledWith("#collectionPrev"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(view.buildCollectionLink).toHaveBeenCalledWith(1); + expect(window.App.navigate).toHaveBeenCalledWith(1, { + trigger: true + }); + expect(jQueryDummy.removeClass).toHaveBeenCalledWith("disabledPag"); + }); + + + it("nextCollection with no collectionContext.next", function () { + jQueryDummy = { + parent: function (e) { + return jQueryDummy; + }, + addClass: function () { + + } + + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "addClass"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.collectionContext = {next: null}; + view.nextCollection(); + expect(window.$).toHaveBeenCalledWith("#collectionNext"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.addClass).toHaveBeenCalledWith("disabledPag"); + }); + + it("nextCollection with collectionContext.next", function () { + jQueryDummy = { + parent: function (e) { + return jQueryDummy; + }, + removeClass: function () { + + } + + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "removeClass"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.collectionContext = {next: 1}; + spyOn(window.App, "navigate"); + spyOn(view, "buildCollectionLink").andReturn(1); + view.nextCollection(); + expect(window.$).toHaveBeenCalledWith("#collectionNext"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(view.buildCollectionLink).toHaveBeenCalledWith(1); + expect(window.App.navigate).toHaveBeenCalledWith(1, { + trigger: true + }); + expect(jQueryDummy.removeClass).toHaveBeenCalledWith("disabledPag"); + }); + + + it("filterCollection", function () { + jQueryDummy = { + removeClass: function () { + }, + toggleClass: function () { + }, + slideToggle: function () { + }, + hide: function () { + }, + focus: function () { + } + + }; + spyOn(jQueryDummy, "removeClass"); + spyOn(jQueryDummy, "toggleClass"); + spyOn(jQueryDummy, "slideToggle"); + spyOn(jQueryDummy, "hide"); + spyOn(jQueryDummy, "focus"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.filters = [ + {0: "bla"}, + {1: "blub"} + ]; + view.filterCollection(); + expect(window.$).toHaveBeenCalledWith("#indexCollection"); + expect(window.$).toHaveBeenCalledWith("#importCollection"); + expect(window.$).toHaveBeenCalledWith("#filterCollection"); + expect(window.$).toHaveBeenCalledWith("#filterHeader"); + expect(window.$).toHaveBeenCalledWith("#importHeader"); + expect(window.$).toHaveBeenCalledWith("#indexHeader"); + expect(window.$).toHaveBeenCalledWith("#attribute_name0"); + // next assertion seems strange but follows the strange implementation + expect(window.$).not.toHaveBeenCalledWith("#attribute_name1"); + expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); + expect(jQueryDummy.hide).toHaveBeenCalled(); + expect(jQueryDummy.focus).toHaveBeenCalled(); + }); + + it("importCollection", function () { + jQueryDummy = { + removeClass: function () { + }, + toggleClass: function () { + }, + slideToggle: function () { + }, + hide: function () { + } + + }; + spyOn(jQueryDummy, "removeClass"); + spyOn(jQueryDummy, "toggleClass"); + spyOn(jQueryDummy, "slideToggle"); + spyOn(jQueryDummy, "hide"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.importCollection(); + + expect(window.$).toHaveBeenCalledWith("#filterCollection"); + expect(window.$).toHaveBeenCalledWith("#indexCollection"); + expect(window.$).toHaveBeenCalledWith("#importCollection"); + expect(window.$).toHaveBeenCalledWith("#filterHeader"); + expect(window.$).toHaveBeenCalledWith("#importHeader"); + expect(window.$).toHaveBeenCalledWith("#indexHeader"); + expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); + expect(jQueryDummy.hide).toHaveBeenCalled(); + }); + + it("indexCollection", function () { + jQueryDummy = { + removeClass: function () { + }, + toggleClass: function () { + }, + slideToggle: function () { + }, + hide: function () { + }, + show: function () { + } + + }; + spyOn(jQueryDummy, "removeClass"); + spyOn(jQueryDummy, "toggleClass"); + spyOn(jQueryDummy, "slideToggle"); + spyOn(jQueryDummy, "hide"); + spyOn(jQueryDummy, "show"); + spyOn(window, "$").andReturn( + jQueryDummy + ); + view.indexCollection(); + expect(window.$).toHaveBeenCalledWith("#filterCollection"); + expect(window.$).toHaveBeenCalledWith("#importCollection"); + expect(window.$).toHaveBeenCalledWith("#indexCollection"); + expect(window.$).toHaveBeenCalledWith("#newIndexView"); + expect(window.$).toHaveBeenCalledWith("#indexEditView"); + expect(window.$).toHaveBeenCalledWith("#indexHeader"); + expect(window.$).toHaveBeenCalledWith("#importHeader"); + expect(window.$).toHaveBeenCalledWith("#filterHeader"); + expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); + expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); + expect(jQueryDummy.hide).toHaveBeenCalled(); + expect(jQueryDummy.show).toHaveBeenCalled(); + }); + + + it("getFilterContent", function () { + + jQueryDummy = { + e: undefined, + val: function () { + var e = jQueryDummy.e; + if (e === '#attribute_value0') { + return '{"jsonval" : 1}'; + } + if (e === '#attribute_value1') { + return "stringval"; + } + if (e === '#attribute_name0') { + return 'name0'; + } + if (e === '#attribute_name1') { + return 'name1'; + } + if (e === '#operator0') { + return 'operator0'; + } + if (e === '#operator1') { + return 'operator1'; + } + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(window, "$").andCallFake( + function (e) { + jQueryDummy.e = e; + return jQueryDummy; + } + ); + view.filters = [ + {0: "bla"}, + {1: "blub"} + ]; + expect(view.getFilterContent()).toEqual([ + [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ]); + expect(window.$).toHaveBeenCalledWith("#attribute_value0"); + expect(window.$).toHaveBeenCalledWith("#attribute_value1"); + expect(window.$).toHaveBeenCalledWith("#attribute_name0"); + expect(window.$).toHaveBeenCalledWith("#attribute_name1"); + expect(window.$).toHaveBeenCalledWith("#operator0"); + expect(window.$).toHaveBeenCalledWith("#operator1"); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + }); + + + it("sendFilter", function () { + + jQueryDummy = { + css: function () { + } + + }; + spyOn(jQueryDummy, "css"); + spyOn(window, "$").andReturn(jQueryDummy); + spyOn(view, "getFilterContent").andReturn( + [ + [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ] + + ); + + var arangoDocStoreDummy = { + getFilteredDocuments: function () { + } + }, + documentsViewDummy = { + clearTable: function () { + } + }; + spyOn(arangoDocStoreDummy, "getFilteredDocuments"); + spyOn(documentsViewDummy, "clearTable"); + spyOn(window, "arangoDocuments").andReturn(arangoDocStoreDummy); + spyOn(window, "DocumentsView").andReturn(documentsViewDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + window.documentsView = new window.DocumentsView(); + + + view.sendFilter(); + + expect(view.addDocumentSwitch).toEqual(false); + expect(documentsViewDummy.clearTable).toHaveBeenCalled(); + expect(arangoDocStoreDummy.getFilteredDocuments).toHaveBeenCalledWith( + view.colid, 1, + [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ); + + + expect(window.$).toHaveBeenCalledWith("#documents_last"); + expect(window.$).toHaveBeenCalledWith("#documents_first"); + expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "hidden"); + expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "hidden"); + }); + + it("addFilterItem", function () { + + jQueryDummy = { + append: function () { + } + + }; + spyOn(jQueryDummy, "append"); + spyOn(window, "$").andReturn(jQueryDummy); + + view.filterId = 1; + var num = 2; + view.addFilterItem(); + expect(window.$).toHaveBeenCalledWith("#filterHeader"); + expect(jQueryDummy.append).toHaveBeenCalledWith( + '
' + + '' + + '' + + '' + + ' ' + + '
'); + expect(view.filters[num]).toEqual(true); + + }); + + + it("filterValueKeydown with keyCode == 13", function () { + spyOn(view, "sendFilter"); + view.filterValueKeydown({keyCode: 13}); + expect(view.sendFilter).toHaveBeenCalled(); + }); + + it("filterValueKeydown with keyCode !== 13", function () { + spyOn(view, "sendFilter"); + view.filterValueKeydown({keyCode: 11}); + expect(view.sendFilter).not.toHaveBeenCalled(); + }); + + + it("removeFilterItem with keyCode !== 13", function () { + jQueryDummy = { + remove: function () { + } + + }; + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andReturn(jQueryDummy); + view.filters[1] = "bla"; + + view.removeFilterItem({currentTarget: {id: "removeFilter1", parentElement: "#blub"}}); + expect(window.$).toHaveBeenCalledWith("#blub"); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(view.filters[1]).toEqual(undefined); + }); + + it("removeAllFilterItems", function () { + jQueryDummy = { + children: function () { + }, + parent: function () { + } + + }; + spyOn(jQueryDummy, "children").andReturn([1, 2, 3]); + spyOn(jQueryDummy, "parent").andReturn({remove: function () { + }}); + spyOn(window, "$").andReturn(jQueryDummy); + + view.removeAllFilterItems(); + expect(window.$).toHaveBeenCalledWith("#filterHeader"); + expect(window.$).toHaveBeenCalledWith("#removeFilter1"); + expect(window.$).toHaveBeenCalledWith("#removeFilter2"); + expect(window.$).toHaveBeenCalledWith("#removeFilter3"); + expect(jQueryDummy.children).toHaveBeenCalled(); + expect(jQueryDummy.parent).toHaveBeenCalled(); + + expect(view.filters).toEqual({ "0": true }); + expect(view.filterId).toEqual(0); + }); + + it("addDocument without an error", function () { + var arangoDocStoreDummy = { + createTypeDocument: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn("newDoc"); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoHelper, "collectionApiType").andReturn("document"); + window.location.hash = "1/2"; + view.addDocument(); + + expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); + expect(arangoDocStoreDummy.createTypeDocument).toHaveBeenCalledWith("2"); + expect(window.location.hash).toEqual("#collection/" + "newDoc"); + + }); + + it("addDocument with an edge", function () { + var arangoDocStoreDummy = { + createTypeDocument: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn("newDoc"); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + jQueryDummy = { + modal: function () { + } + + }; + spyOn(jQueryDummy, "modal"); + spyOn(arangoHelper, "fixTooltips"); + spyOn(window, "$").andReturn(jQueryDummy); + + spyOn(arangoHelper, "collectionApiType").andReturn("edge"); + window.location.hash = "1/2"; + view.addDocument(); + + expect(window.$).toHaveBeenCalledWith("#edgeCreateModal"); + expect(jQueryDummy.modal).toHaveBeenCalledWith('show'); + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith(".modalTooltips", "left"); + expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); + expect(arangoDocStoreDummy.createTypeDocument).not.toHaveBeenCalled(); + expect(window.location.hash).toEqual("#1/2"); + + }); + + it("addDocument with an error", function () { + var arangoDocStoreDummy = { + createTypeDocument: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn(false); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoHelper, "collectionApiType").andReturn("document"); + spyOn(arangoHelper, "arangoError"); + window.location.hash = "1/2"; + view.addDocument(); + + expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); + expect(arangoHelper.arangoError).toHaveBeenCalledWith('Creating document failed'); + expect(arangoDocStoreDummy.createTypeDocument).toHaveBeenCalledWith("2"); + expect(window.location.hash).toEqual("#1/2"); + + }); + + + it("addEdge with missing to ", function () { + jQueryDummy = { + e: undefined, + val: function () { + if (jQueryDummy.e === "#new-document-from") { + return ""; + } + if (jQueryDummy.e === "#new-document-to") { + return "bla"; + } + + } + + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + + }); + + var arangoDocStoreDummy = { + createTypeEdge: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeEdge"); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + window.location.hash = "1/2"; + view.addEdge(); + expect(window.$).toHaveBeenCalledWith("#new-document-from"); + expect(window.$).toHaveBeenCalledWith("#new-document-to"); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(arangoDocStoreDummy.createTypeEdge).not.toHaveBeenCalled(); + + }); + + + it("addEdge with missing to ", function () { + jQueryDummy = { + e: undefined, + val: function () { + if (jQueryDummy.e === "#new-document-from") { + return "bla"; + } + if (jQueryDummy.e === "#new-document-to") { + return ""; + } + + } + + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + + }); + + var arangoDocStoreDummy = { + createTypeEdge: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeEdge"); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + window.location.hash = "1/2"; + view.addEdge(); + expect(window.$).toHaveBeenCalledWith("#new-document-from"); + expect(window.$).toHaveBeenCalledWith("#new-document-to"); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(arangoDocStoreDummy.createTypeEdge).not.toHaveBeenCalled(); + + }); + + + it("addEdge with success", function () { + jQueryDummy = { + e: undefined, + val: function () { + if (jQueryDummy.e === "#new-document-from") { + return "bla"; + } + if (jQueryDummy.e === "#new-document-to") { + return "blub"; + } + }, + modal: function () { + + } + + + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "modal"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + + }); + + var arangoDocStoreDummy = { + createTypeEdge: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeEdge").andReturn("newEdge"); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + window.location.hash = "1/2"; + view.addEdge(); + expect(window.$).toHaveBeenCalledWith("#new-document-from"); + expect(window.$).toHaveBeenCalledWith("#new-document-to"); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.modal).toHaveBeenCalledWith('hide'); + expect(arangoDocStoreDummy.createTypeEdge).toHaveBeenCalledWith("2", "bla", "blub"); + expect(window.location.hash).toEqual("#collection/newEdge"); + + }); + + it("addEdge with error", function () { + jQueryDummy = { + e: undefined, + val: function () { + if (jQueryDummy.e === "#new-document-from") { + return "bla"; + } + if (jQueryDummy.e === "#new-document-to") { + return "blub"; + } + }, + modal: function () { + + } + + + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "modal"); + spyOn(arangoHelper, "arangoError"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + + }); + + var arangoDocStoreDummy = { + createTypeEdge: function () { + } + }; + spyOn(arangoDocStoreDummy, "createTypeEdge").andReturn(false); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + window.location.hash = "1/2"; + view.addEdge(); + expect(window.$).toHaveBeenCalledWith("#new-document-from"); + expect(window.$).toHaveBeenCalledWith("#new-document-to"); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(arangoHelper.arangoError).toHaveBeenCalledWith('Creating edge failed'); + expect(jQueryDummy.modal).not.toHaveBeenCalled(); + expect(arangoDocStoreDummy.createTypeEdge).toHaveBeenCalledWith("2", "bla", "blub"); + expect(window.location.hash).toEqual("#1/2"); + + }); + + it("first-last-next-prev document", function () { + var arangoDocumentsStoreDummy = { + getFirstDocuments: function () { + }, + getLastDocuments: function () { + }, + getPrevDocuments: function () { + }, + getNextDocuments: function () { + } + }; + spyOn(arangoDocumentsStoreDummy, "getFirstDocuments"); + spyOn(arangoDocumentsStoreDummy, "getLastDocuments"); + spyOn(arangoDocumentsStoreDummy, "getPrevDocuments"); + spyOn(arangoDocumentsStoreDummy, "getNextDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocumentsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + + view.firstDocuments(); + expect(arangoDocumentsStoreDummy.getFirstDocuments).toHaveBeenCalled(); + view.lastDocuments(); + expect(arangoDocumentsStoreDummy.getLastDocuments).toHaveBeenCalled(); + view.prevDocuments(); + expect(arangoDocumentsStoreDummy.getPrevDocuments).toHaveBeenCalled(); + view.nextDocuments(); + expect(arangoDocumentsStoreDummy.getNextDocuments).toHaveBeenCalled(); + + + }); + + + it("remove", function () { + jQueryDummy = { + e: undefined, + prev: function () { + return jQueryDummy; + }, + attr: function () { + + }, + modal: function () { + + } + + + }; + spyOn(jQueryDummy, "prev").andCallThrough(); + spyOn(jQueryDummy, "attr"); + spyOn(jQueryDummy, "modal"); + spyOn(window, "$").andReturn(jQueryDummy); + + view.remove({currentTarget: {parentElement: "#thiselement"}}); + + expect(window.$).toHaveBeenCalledWith("#thiselement"); + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); + expect(jQueryDummy.prev).toHaveBeenCalled(); + expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", false); + expect(jQueryDummy.modal).toHaveBeenCalledWith("show"); + expect(view.alreadyClicked).toEqual(true); + expect(view.idelement).toEqual(jQueryDummy); + + }); + + + it("confirmDelete with check != source", function () { + jQueryDummy = { + attr: function () { + + } + }; + spyOn(jQueryDummy, "attr"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/4"; + spyOn(view, "reallyDelete"); + view.confirmDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", true); + expect(view.reallyDelete).toHaveBeenCalled(); + }); + + + it("confirmDelete with check = source", function () { + jQueryDummy = { + attr: function () { + + } + }; + spyOn(jQueryDummy, "attr"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/source"; + spyOn(view, "reallyDelete"); + view.confirmDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", true); + expect(view.reallyDelete).not.toHaveBeenCalled(); + }); + + + it("reallyDelete a document with error", function () { + jQueryDummy = { + closest: function () { + return jQueryDummy; + }, + get: function () { + + }, + next: function () { + return jQueryDummy; + }, + text: function () { + + } + }; + spyOn(jQueryDummy, "closest").andCallThrough(); + spyOn(jQueryDummy, "get"); + spyOn(jQueryDummy, "next").andCallThrough(); + spyOn(jQueryDummy, "text").andReturn("4"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/source"; + + view.type = "document"; + view.colid = "collection"; + + spyOn(arangoHelper, "arangoError"); + var arangoDocStoreDummy = { + deleteDocument: function () { + } + }, arangoDocsStoreDummy = { + getDocuments: function () { + } + }; + + spyOn(arangoDocStoreDummy, "deleteDocument").andReturn(false); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoDocsStoreDummy, "getDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + view.target = "#confirmDeleteBtn"; + + view.reallyDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(arangoDocsStoreDummy.getDocuments).not.toHaveBeenCalled(); + expect(arangoHelper.arangoError).toHaveBeenCalledWith('Doc error'); + expect(arangoDocStoreDummy.deleteDocument).toHaveBeenCalledWith("collection", "4"); + }); + + + it("reallyDelete a edge with error", function () { + jQueryDummy = { + closest: function () { + return jQueryDummy; + }, + get: function () { + + }, + next: function () { + return jQueryDummy; + }, + text: function () { + + } + }; + spyOn(jQueryDummy, "closest").andCallThrough(); + spyOn(jQueryDummy, "get"); + spyOn(jQueryDummy, "next").andCallThrough(); + spyOn(jQueryDummy, "text").andReturn("4"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/source"; + + view.type = "edge"; + view.colid = "collection"; + + spyOn(arangoHelper, "arangoError"); + var arangoDocStoreDummy = { + deleteEdge: function () { + } + }, arangoDocsStoreDummy = { + getDocuments: function () { + } + }; + spyOn(arangoDocStoreDummy, "deleteEdge").andReturn(false); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoDocsStoreDummy, "getDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + view.target = "#confirmDeleteBtn"; + + view.reallyDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(arangoHelper.arangoError).toHaveBeenCalledWith('Edge error'); + expect(arangoDocsStoreDummy.getDocuments).not.toHaveBeenCalled(); + expect(arangoDocStoreDummy.deleteEdge).toHaveBeenCalledWith("collection", "4"); + }); + + + it("reallyDelete a document with no error", function () { + jQueryDummy = { + closest: function () { + return jQueryDummy; + }, + get: function () { + + }, + next: function () { + return jQueryDummy; + }, + text: function () { + + }, + dataTable: function () { + return jQueryDummy; + }, + fnDeleteRow: function () { + + }, + fnGetPosition: function () { + + }, + fnClearTable: function () { + + }, + modal: function () { + + } + + }; + spyOn(jQueryDummy, "closest").andCallThrough(); + spyOn(jQueryDummy, "get").andReturn(1); + spyOn(jQueryDummy, "fnClearTable"); + spyOn(jQueryDummy, "modal"); + spyOn(jQueryDummy, "fnGetPosition").andReturn(3); + spyOn(jQueryDummy, "next").andCallThrough(); + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnDeleteRow").andCallThrough(); + spyOn(jQueryDummy, "text").andReturn("4"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/source"; + + view.type = "document"; + view.colid = "collection"; + + spyOn(arangoHelper, "arangoError"); + var arangoDocStoreDummy = { + deleteDocument: function () { + } + }, arangoDocsStoreDummy = { + getDocuments: function () { + } + }; + spyOn(arangoDocStoreDummy, "deleteDocument").andReturn(true); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoDocsStoreDummy, "getDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + view.target = "#confirmDeleteBtn"; + + view.reallyDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + expect(window.$).toHaveBeenCalledWith("#documentsTableID"); + expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); + + expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); + expect(jQueryDummy.dataTable).toHaveBeenCalled(); + expect(jQueryDummy.fnGetPosition).toHaveBeenCalledWith(1); + expect(jQueryDummy.fnDeleteRow).toHaveBeenCalledWith(3); + expect(jQueryDummy.fnClearTable).toHaveBeenCalledWith(); + expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); + + + expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); + expect(arangoHelper.arangoError).not.toHaveBeenCalledWith('Doc error'); + expect(arangoDocStoreDummy.deleteDocument).toHaveBeenCalledWith("collection", "4"); + }); + + + it("reallyDelete a edge with no error", function () { + jQueryDummy = { + closest: function () { + return jQueryDummy; + }, + get: function () { + + }, + next: function () { + return jQueryDummy; + }, + text: function () { + + }, + dataTable: function () { + return jQueryDummy; + }, + fnDeleteRow: function () { + + }, + fnGetPosition: function () { + + }, + fnClearTable: function () { + + }, + modal: function () { + + } + + }; + spyOn(jQueryDummy, "closest").andCallThrough(); + spyOn(jQueryDummy, "get").andReturn(1); + spyOn(jQueryDummy, "fnClearTable"); + spyOn(jQueryDummy, "modal"); + spyOn(jQueryDummy, "fnGetPosition").andReturn(3); + spyOn(jQueryDummy, "next").andCallThrough(); + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnDeleteRow").andCallThrough(); + spyOn(jQueryDummy, "text").andReturn("4"); + spyOn(window, "$").andReturn(jQueryDummy); + window.location.hash = "1/2/3/source"; + + view.type = "edge"; + view.colid = "collection"; + + spyOn(arangoHelper, "arangoError"); + var arangoDocStoreDummy = { + deleteEdge: function () { + } + }, arangoDocsStoreDummy = { + getDocuments: function () { + } + }; + spyOn(arangoDocStoreDummy, "deleteEdge").andReturn(true); + spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); + window.arangoDocumentStore = new window.arangoDocument(); + + spyOn(arangoDocsStoreDummy, "getDocuments"); + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + view.target = "#confirmDeleteBtn"; + + view.reallyDelete(); + + expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); + + + expect(window.$).toHaveBeenCalledWith("#documentsTableID"); + expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); + + expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); + expect(jQueryDummy.dataTable).toHaveBeenCalled(); + expect(jQueryDummy.fnGetPosition).toHaveBeenCalledWith(1); + expect(jQueryDummy.fnDeleteRow).toHaveBeenCalledWith(3); + expect(jQueryDummy.fnClearTable).toHaveBeenCalledWith(); + expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); + + expect(arangoHelper.arangoError).not.toHaveBeenCalledWith('Edge error'); + expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); + expect(arangoDocStoreDummy.deleteEdge).toHaveBeenCalledWith("collection", "4"); + }); + + + it("clicked when alreadyClicked", function () { + view.alreadyClicked = true; + expect(view.clicked("anything")).toEqual(0); + }); + + it("clicked when clicked event has no target", function () { + jQueryDummy = { + dataTable: function () { + return jQueryDummy; + }, + fnGetPosition: function () { + + } + + }; + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnGetPosition").andReturn(null); + spyOn(window, "$").andReturn(jQueryDummy); + view.alreadyClicked = false; + expect(view.clicked("anything")).toEqual(undefined); + }); + + it("clicked when clicked event has target but no valid checkData", function () { + jQueryDummy = { + dataTable: function () { + return jQueryDummy; + }, + fnGetPosition: function () { + + }, + fnGetData: function () { + + } + }; + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnGetPosition").andReturn(1); + spyOn(jQueryDummy, "fnGetData").andReturn([0, ""]); + spyOn(window, "$").andReturn(jQueryDummy); + spyOn(view, "addDocument"); + view.alreadyClicked = false; + expect(view.clicked("anything")).toEqual(undefined); + expect(view.addDocument).toHaveBeenCalled(); + }); + + it("clicked when clicked event has target and valid checkData", function () { + jQueryDummy = { + dataTable: function () { + return jQueryDummy; + }, + fnGetPosition: function () { + + }, + fnGetData: function () { + + }, + next: function () { + return jQueryDummy; + }, + text: function () { + + } + + }; + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "next").andCallThrough(); + spyOn(jQueryDummy, "text").andReturn(12); + spyOn(jQueryDummy, "fnGetPosition").andReturn(1); + spyOn(jQueryDummy, "fnGetData").andReturn([0, "true"]); + spyOn(window, "$").andReturn(jQueryDummy); + spyOn(view, "addDocument"); + view.alreadyClicked = false; + view.colid = "coll"; + expect(view.clicked({currentTarget: {firstChild: "blub"}})).toEqual(undefined); + expect(view.addDocument).not.toHaveBeenCalled(); + expect(window.$).toHaveBeenCalledWith("blub"); + expect(window.location.hash).toEqual("#collection/coll/12"); + }); + + it("initTable", function () { + jQueryDummy = { + dataTable: function () { + } + }; + spyOn(jQueryDummy, "dataTable"); + spyOn(window, "$").andReturn(jQueryDummy); + view.initTable(); + expect(jQueryDummy.dataTable).toHaveBeenCalledWith({ + "bSortClasses": false, + "bFilter": false, + "bPaginate": false, + "bRetrieve": true, + "bSortable": false, + "bSort": false, + "bLengthChange": false, + "bAutoWidth": false, + "iDisplayLength": -1, + "bJQueryUI": false, + "aoColumns": [ + { "sClass": "docsFirstCol", "bSortable": false}, + { "sClass": "docsSecCol", "bSortable": false}, + { "bSortable": false, "sClass": "docsThirdCol"} + ], + "oLanguage": { "sEmptyTable": "Loading..."} + }); + }); + + it("clearTable", function () { + jQueryDummy = { + dataTable: function () { + return jQueryDummy; + }, + fnClearTable: function () { + } + }; + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnClearTable"); + spyOn(window, "$").andReturn(jQueryDummy); + view.table = "blub"; + view.clearTable(); + expect(window.$).toHaveBeenCalledWith("blub"); + expect(jQueryDummy.fnClearTable).toHaveBeenCalled(); + }); + + + it("drawTable with empty collection", function () { + jQueryDummy = { + text: function () { + + } + }; + spyOn(jQueryDummy, "text"); + spyOn(window, "$").andReturn(jQueryDummy); + + var arangoDocsStoreDummy = { + models: [], + totalPages: 1, + currentPage: 1, + documentsCount: 0 + + }; + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + window.arangoDocumentsStore = new window.arangoDocuments(); + + view.drawTable(); + expect(view.totalPages).toEqual(1); + expect(view.currentPage).toEqual(1); + expect(view.documentsCount).toEqual(0); + expect(window.$).toHaveBeenCalledWith(".dataTables_empty"); + expect(jQueryDummy.text).toHaveBeenCalledWith('No documents'); + }); + + + it("drawTable with not empty collection", function () { + jQueryDummy = { + dataTable: function () { + return jQueryDummy; + }, + fnAddData: function () { + }, + snippet: function () { + } + + }; + spyOn(jQueryDummy, "dataTable").andCallThrough(); + spyOn(jQueryDummy, "fnAddData"); + spyOn(jQueryDummy, "snippet"); + spyOn(window, "$").andReturn(jQueryDummy); + $.each = function (list, callback) { + var callBackWraper = function (a, b) { + callback(b, a); + }; + list.forEach(callBackWraper); + }; + + var arangoDocsStoreDummy = { + models: [ + new window.arangoDocumentModel( + {content: [ + {_id: 1}, + {_rev: 1}, + {_key: 1} , + {bla: 1} + ]} + ), + new window.arangoDocumentModel( + {content: [ + {_id: 1}, + {_rev: 1}, + {_key: 1} , + {bla: 1} + ]} + ), + new window.arangoDocumentModel( + {content: [ + {_id: 1}, + {_rev: 1}, + {_key: 1} , + {bla: 1} + ]} + ) + ], + totalPages: 1, + currentPage: 2, + documentsCount: 3 + + }; + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + spyOn(arangoHelper, "fixTooltips"); + window.arangoDocumentsStore = new window.arangoDocuments(); + + view.drawTable(); + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith( + ".icon_arangodb, .arangoicon", "top" + ); + expect(view.totalPages).toEqual(1); + expect(view.currentPage).toEqual(2); + expect(view.documentsCount).toEqual(3); + expect(window.$).toHaveBeenCalledWith(".prettify"); + expect(jQueryDummy.dataTable).toHaveBeenCalled(); + expect(jQueryDummy.snippet).toHaveBeenCalledWith("javascript", { + style: "nedit", + menu: false, + startText: false, + transparent: true, + showNum: false + }); + expect(jQueryDummy.fnAddData).toHaveBeenCalled(); + }); + + describe("render", function () { + var jQueryDummy, arangoCollectionsDummy; + beforeEach(function () { + jQueryDummy = { + parent: function () { + return jQueryDummy; + }, + addClass: function () { + }, + tooltip: function () { + + }, + html: function () { + + } + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "addClass"); + spyOn(jQueryDummy, "tooltip"); + spyOn(jQueryDummy, "html"); + spyOn(window, "$").andReturn(jQueryDummy); + arangoCollectionsDummy = { + getPosition: function () { + } + + }; + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + window.arangoCollectionsStore = new window.arangoCollections(); + spyOn(view, "getIndex"); + spyOn(view, "initTable"); + spyOn(view, "breadcrumb"); + spyOn(view, "uploadSetup"); + spyOn(arangoHelper, "fixTooltips"); + view.el = 1; + view.colid = "1"; + view.template = { + render: function () { + return "tmp"; + } + }; + + }); + + it("render with no prev and no next page", function () { + spyOn(arangoCollectionsDummy, "getPosition").andReturn({prev: null, next: null}); + + expect(view.render()).toEqual(view); + + expect(arangoCollectionsDummy.getPosition).toHaveBeenCalledWith("1"); + expect(view.getIndex).toHaveBeenCalled(); + expect(view.initTable).toHaveBeenCalled(); + expect(view.breadcrumb).toHaveBeenCalled(); + expect(view.uploadSetup).toHaveBeenCalled(); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.addClass).toHaveBeenCalledWith('disabledPag'); + expect(jQueryDummy.html).toHaveBeenCalledWith('tmp'); + expect(jQueryDummy.tooltip).toHaveBeenCalled(); + expect(jQueryDummy.tooltip).toHaveBeenCalledWith({placement: "left"}); + expect(window.$).toHaveBeenCalledWith("#collectionPrev"); + expect(window.$).toHaveBeenCalledWith("#collectionNext"); + expect(window.$).toHaveBeenCalledWith("[data-toggle=tooltip]"); + expect(window.$).toHaveBeenCalledWith('.modalImportTooltips'); + expect(window.$).toHaveBeenCalledWith(1); + + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith( + ".icon_arangodb, .arangoicon", "top" + ); + }); + + it("render with no prev but next page", function () { + spyOn(arangoCollectionsDummy, "getPosition").andReturn({prev: null, next: 1}); + + expect(view.render()).toEqual(view); + + expect(arangoCollectionsDummy.getPosition).toHaveBeenCalledWith("1"); + expect(view.getIndex).toHaveBeenCalled(); + expect(view.initTable).toHaveBeenCalled(); + expect(view.breadcrumb).toHaveBeenCalled(); + expect(view.uploadSetup).toHaveBeenCalled(); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.addClass).toHaveBeenCalledWith('disabledPag'); + expect(jQueryDummy.html).toHaveBeenCalledWith('tmp'); + expect(jQueryDummy.tooltip).toHaveBeenCalled(); + expect(jQueryDummy.tooltip).toHaveBeenCalledWith({placement: "left"}); + expect(window.$).toHaveBeenCalledWith("#collectionPrev"); + expect(window.$).not.toHaveBeenCalledWith("#collectionNext"); + expect(window.$).toHaveBeenCalledWith("[data-toggle=tooltip]"); + expect(window.$).toHaveBeenCalledWith('.modalImportTooltips'); + expect(window.$).toHaveBeenCalledWith(1); + + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith( + ".icon_arangodb, .arangoicon", "top" + ); + }); + + it("render with prev but no next page", function () { + spyOn(arangoCollectionsDummy, "getPosition").andReturn({prev: 1, next: null}); + + expect(view.render()).toEqual(view); + + expect(arangoCollectionsDummy.getPosition).toHaveBeenCalledWith("1"); + expect(view.getIndex).toHaveBeenCalled(); + expect(view.initTable).toHaveBeenCalled(); + expect(view.breadcrumb).toHaveBeenCalled(); + expect(view.uploadSetup).toHaveBeenCalled(); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.addClass).toHaveBeenCalledWith('disabledPag'); + expect(jQueryDummy.html).toHaveBeenCalledWith('tmp'); + expect(jQueryDummy.tooltip).toHaveBeenCalled(); + expect(jQueryDummy.tooltip).toHaveBeenCalledWith({placement: "left"}); + expect(window.$).not.toHaveBeenCalledWith("#collectionPrev"); + expect(window.$).toHaveBeenCalledWith("#collectionNext"); + expect(window.$).toHaveBeenCalledWith("[data-toggle=tooltip]"); + expect(window.$).toHaveBeenCalledWith('.modalImportTooltips'); + expect(window.$).toHaveBeenCalledWith(1); + + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith( + ".icon_arangodb, .arangoicon", "top" + ); + }); + + }); + + it("showLoadingState", function () { + jQueryDummy = { + text: function () { + } + }; + spyOn(jQueryDummy, "text"); + spyOn(window, "$").andReturn(jQueryDummy); + view.showLoadingState(); + expect(jQueryDummy.text).toHaveBeenCalledWith('Loading...'); + expect(window.$).toHaveBeenCalledWith('.dataTables_empty'); + + }); + + it("renderPagination with filter check and totalDocs > 0 ", function () { + jQueryDummy = { + html: function () { + }, + css: function () { + }, + pagination: function (o) { + o.click(5); + }, + prepend: function () { + }, + append: function () { + }, + length: 10 + + }; + spyOn(jQueryDummy, "html"); + spyOn(jQueryDummy, "css"); + spyOn(jQueryDummy, "prepend"); + spyOn(jQueryDummy, "append"); + spyOn(jQueryDummy, "pagination").andCallThrough(); + spyOn(window, "$").andReturn(jQueryDummy); + + + var arangoDocsStoreDummy = { + currentFilterPage: 2, + getFilteredDocuments: function () { + + } + }; + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + spyOn(arangoDocsStoreDummy, "getFilteredDocuments"); + spyOn(arangoHelper, "fixTooltips"); + window.arangoDocumentsStore = new window.arangoDocuments(); + + + spyOn(view, "getFilterContent").andReturn( + [ + [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ] + + ); + spyOn(view, "clearTable"); + window.documentsView = view; + view.colid = 1; + view.documentsCount = 11; + view.renderPagination(3, true); + + + expect(jQueryDummy.html).toHaveBeenCalledWith(''); + expect(jQueryDummy.html).toHaveBeenCalledWith("Total: 11 documents"); + expect(jQueryDummy.prepend).toHaveBeenCalledWith(''); + expect(jQueryDummy.append).toHaveBeenCalledWith(''); + expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "hidden"); + expect(jQueryDummy.pagination).toHaveBeenCalledWith( + { + left: 2, + right: 2, + page: 5, + lastPage: 3, + click: jasmine.any(Function) + } + ); + expect(arangoDocsStoreDummy.getFilteredDocuments).toHaveBeenCalledWith( + 1, 5, [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ); + expect(window.$).toHaveBeenCalledWith('#documentsToolbarF'); + expect(window.$).toHaveBeenCalledWith('#documents_last'); + expect(window.$).toHaveBeenCalledWith('#documents_first'); + expect(window.$).toHaveBeenCalledWith('#totalDocuments'); + + }); + + it("renderPagination with no filter check and totalDocs = 0 ", function () { + jQueryDummy = { + html: function () { + }, + css: function () { + }, + pagination: function (o) { + o.click(5); + }, + prepend: function () { + }, + append: function () { + }, + length: 0 + + }; + spyOn(jQueryDummy, "html"); + spyOn(jQueryDummy, "css"); + spyOn(jQueryDummy, "prepend"); + spyOn(jQueryDummy, "append"); + spyOn(jQueryDummy, "pagination").andCallThrough(); + spyOn(window, "$").andReturn(jQueryDummy); + + + var arangoDocsStoreDummy = { + currentFilterPage: 2, + getFilteredDocuments: function () { + + } + }; + spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); + spyOn(arangoDocsStoreDummy, "getFilteredDocuments"); + spyOn(arangoHelper, "fixTooltips"); + window.arangoDocumentsStore = new window.arangoDocuments(); + + + spyOn(view, "getFilterContent").andReturn( + [ + [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], + { param0: {jsonval: 1}, param1: "stringval"} + ] + + ); + spyOn(view, "clearTable"); + window.documentsView = view; + view.colid = 1; + view.documentsCount = 0; + view.pageid = "1"; + view.renderPagination(3, false); + + + expect(jQueryDummy.html).toHaveBeenCalledWith(''); + expect(view.clearTable).not.toHaveBeenCalled(); + expect(jQueryDummy.html).not.toHaveBeenCalledWith("Total: 0 documents"); + expect(jQueryDummy.prepend).toHaveBeenCalledWith(''); + expect(jQueryDummy.append).toHaveBeenCalledWith(''); + expect(jQueryDummy.css).not.toHaveBeenCalledWith("visibility", "hidden"); + expect(jQueryDummy.pagination).toHaveBeenCalledWith( + { + left: 2, + right: 2, + page: 5, + lastPage: 3, + click: jasmine.any(Function) + } + ); + expect(arangoDocsStoreDummy.getFilteredDocuments).not.toHaveBeenCalled(); + expect(window.$).toHaveBeenCalledWith('#documentsToolbarF'); + expect(window.$).not.toHaveBeenCalledWith('#documents_last'); + expect(window.$).not.toHaveBeenCalledWith('#documents_first'); + expect(window.$).toHaveBeenCalledWith('#totalDocuments'); + expect(window.location.hash).toEqual('#collection/1/documents/5'); + + }); + + + it("breadcrumb", function () { + jQueryDummy = { + append: function () { + } + }; + spyOn(jQueryDummy, "append"); + spyOn(window, "$").andReturn(jQueryDummy); + + window.location.hash = "1/2"; + view.breadcrumb(); + expect(view.collectionName).toEqual("2"); + expect(jQueryDummy.append).toHaveBeenCalledWith(''); + expect(window.$).toHaveBeenCalledWith('#transparentHeader'); + }); + + it("cutByResolution with small string", function () { + + expect(view.cutByResolution("blub")).toEqual(view.escaped("blub")); + + }); + + it("cutByResolution with string longer than 1024", function () { + var string = "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890", + + resultString = "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "12345678901234567890123456789012345678901234567890" + + "123456789012345678901234..."; + + expect(view.cutByResolution(string)).toEqual(view.escaped(resultString)); + + }); + + it("escaped", function () { + expect(view.escaped('&<>"\'')).toEqual("&<>"'"); + }); + + + it("resetIndexForms", function () { + jQueryDummy = { + val: function () { + return jQueryDummy; + }, + prop: function () { + + } + + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "prop"); + spyOn(window, "$").andReturn(jQueryDummy); + + spyOn(view, "selectIndexType"); + view.resetIndexForms(); + expect(view.selectIndexType).toHaveBeenCalled(); + expect(jQueryDummy.prop).toHaveBeenCalledWith("checked", false); + expect(jQueryDummy.prop).toHaveBeenCalledWith('selected', true); + expect(jQueryDummy.val).toHaveBeenCalledWith(''); + expect(jQueryDummy.val).toHaveBeenCalledWith('Cap'); + expect(window.$).toHaveBeenCalledWith('#indexHeader input'); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + + }); + + it("stringToArray", function () { + expect(view.stringToArray("1,2,3,4,5,")).toEqual(["1", "2", "3", "4", "5"]); + }); + + + it("createCap Index", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Cap"; + } + if (jQueryDummy.e === "#newCapSize") { + return "1024"; + } + if (jQueryDummy.e === "#newCapByteSize") { + return 2048; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(true); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'cap', + size: 1024, + byteSize: 2048 + }); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newCapSize'); + expect(window.$).toHaveBeenCalledWith('#newCapByteSize'); + expect(window.$).toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).toHaveBeenCalled(); + expect(view.toggleNewIndexView).toHaveBeenCalled(); + expect(view.resetIndexForms).toHaveBeenCalled(); + + }); + + it("create Geo Index", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Geo"; + } + if (jQueryDummy.e === "#newGeoFields") { + return "1,2,3,4,5,6"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + spyOn(view, "checkboxToValue").andCallFake( + function (a) { + if (a === "#newGeoJson") { + return "newGeoJson"; + } + if (a === "#newGeoConstraint") { + return "newGeoConstraint"; + } + if (a === "#newGeoIgnoreNull") { + return "newGeoIgnoreNull"; + } + } + ); + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(true); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'geo', + fields: ["1", "2", "3", "4", "5", "6"], + geoJson: "newGeoJson", + constraint: "newGeoConstraint", + ignoreNull: "newGeoIgnoreNull" + }); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newGeoFields'); + expect(window.$).toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).toHaveBeenCalled(); + expect(view.toggleNewIndexView).toHaveBeenCalled(); + expect(view.resetIndexForms).toHaveBeenCalled(); + + }); + + + it("create Hash Index", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Hash"; + } + if (jQueryDummy.e === "#newHashFields") { + return "1,2,3,4,5,6"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + spyOn(view, "checkboxToValue").andCallFake( + function (a) { + if (a === "#newHashUnique") { + return "newHashUnique"; + } + } + ); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(true); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'hash', + fields: ["1", "2", "3", "4", "5", "6"], + unique: "newHashUnique" + }); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newHashFields'); + expect(window.$).toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).toHaveBeenCalled(); + expect(view.toggleNewIndexView).toHaveBeenCalled(); + expect(view.resetIndexForms).toHaveBeenCalled(); + + }); + + + it("create Fulltext Index", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Fulltext"; + } + if (jQueryDummy.e === "#newFulltextFields") { + return "1,2,3,4,5,6"; + } + if (jQueryDummy.e === "#newFulltextMinLength") { + return "100"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(true); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'fulltext', + fields: ["1", "2", "3", "4", "5", "6"], + minLength: 100 + }); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newFulltextFields'); + expect(window.$).toHaveBeenCalledWith('#newFulltextMinLength'); + expect(window.$).toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).toHaveBeenCalled(); + expect(view.toggleNewIndexView).toHaveBeenCalled(); + expect(view.resetIndexForms).toHaveBeenCalled(); + + }); + + + it("create Skiplist Index", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Skiplist"; + } + if (jQueryDummy.e === "#newSkiplistFields") { + return "1,2,3,4,5,6"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + spyOn(view, "checkboxToValue").andCallFake( + function (a) { + if (a === "#newSkiplistUnique") { + return "newSkiplistUnique"; + } + } + ); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(true); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'skiplist', + fields: ["1", "2", "3", "4", "5", "6"], + unique: "newSkiplistUnique" + }); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newSkiplistFields'); + expect(window.$).toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).toHaveBeenCalled(); + expect(view.toggleNewIndexView).toHaveBeenCalled(); + expect(view.resetIndexForms).toHaveBeenCalled(); + + }); + + + it("create Skiplist Index with error and no response text", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Skiplist"; + } + if (jQueryDummy.e === "#newSkiplistFields") { + return "1,2,3,4,5,6"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + spyOn(view, "checkboxToValue").andCallFake( + function (a) { + if (a === "#newSkiplistUnique") { + return "newSkiplistUnique"; + } + } + ); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn(false); + spyOn(arangoHelper, "arangoNotification"); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).not.toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'skiplist', + fields: ["1", "2", "3", "4", "5", "6"], + unique: "newSkiplistUnique" + }); + + expect(arangoHelper.arangoNotification).toHaveBeenCalledWith( + "Document error", "Could not create index."); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newSkiplistFields'); + expect(window.$).not.toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).not.toHaveBeenCalled(); + expect(view.toggleNewIndexView).not.toHaveBeenCalled(); + expect(view.resetIndexForms).not.toHaveBeenCalled(); + + }); + + + it("create Skiplist Index with error and response text", function () { + view.collectionName = "coll"; + + spyOn(view, "getIndex"); + spyOn(view, "toggleNewIndexView"); + spyOn(view, "resetIndexForms"); + + + jQueryDummy = { + val: function (a) { + if (jQueryDummy.e === "#newIndexType") { + return "Skiplist"; + } + if (jQueryDummy.e === "#newSkiplistFields") { + return "1,2,3,4,5,6"; + } + }, + remove: function () { + + } + }; + spyOn(jQueryDummy, "val").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(window, "$").andCallFake(function (e) { + jQueryDummy.e = e; + return jQueryDummy; + }); + + spyOn(view, "checkboxToValue").andCallFake( + function (a) { + if (a === "#newSkiplistUnique") { + return "newSkiplistUnique"; + } + } + ); + + var arangoCollectionsDummy = { + createIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "createIndex").andReturn( + {responseText: '{"errorMessage" : "blub"}'}); + spyOn(arangoHelper, "arangoNotification"); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.createIndex(); + + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.remove).not.toHaveBeenCalled(); + expect(arangoCollectionsDummy.createIndex).toHaveBeenCalledWith('coll', { + type: 'skiplist', + fields: ["1", "2", "3", "4", "5", "6"], + unique: "newSkiplistUnique" + }); + + expect(arangoHelper.arangoNotification).toHaveBeenCalledWith( + "Document error", 'blub'); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newSkiplistFields'); + expect(window.$).not.toHaveBeenCalledWith('#collectionEditIndexTable tr'); + + expect(view.getIndex).not.toHaveBeenCalled(); + expect(view.toggleNewIndexView).not.toHaveBeenCalled(); + expect(view.resetIndexForms).not.toHaveBeenCalled(); + + }); + + + it("prepDeleteIndex", function () { + jQueryDummy = { + parent: function () { + return jQueryDummy; + }, + first: function () { + return jQueryDummy; + }, + children: function () { + return jQueryDummy; + }, + text: function () { + }, + modal: function () { + + } + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "first").andCallThrough(); + spyOn(jQueryDummy, "children").andCallThrough(); + spyOn(jQueryDummy, "text"); + spyOn(jQueryDummy, "modal"); + + spyOn(window, "$").andReturn(jQueryDummy); + + view.prepDeleteIndex({currentTarget: "blub"}); + + expect(window.$).toHaveBeenCalledWith("blub"); + expect(window.$).toHaveBeenCalledWith("#indexDeleteModal"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.first).toHaveBeenCalled(); + expect(jQueryDummy.children).toHaveBeenCalled(); + expect(jQueryDummy.text).toHaveBeenCalled(); + expect(jQueryDummy.modal).toHaveBeenCalledWith('show'); + + }); + + + it("deleteIndex", function () { + jQueryDummy = { + parent: function () { + return jQueryDummy; + }, + remove: function () { + }, + modal: function () { + + } + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(jQueryDummy, "modal"); + + spyOn(window, "$").andReturn(jQueryDummy); + + var arangoCollectionsDummy = { + deleteIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "deleteIndex").andReturn(true); + spyOn(arangoHelper, "arangoError"); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.lastTarget = {currentTarget: "blub"}; + view.collectionName = "coll"; + view.lastId = "lastId"; + view.deleteIndex(); + + expect(window.$).toHaveBeenCalledWith("blub"); + expect(window.$).toHaveBeenCalledWith("#indexDeleteModal"); + expect(arangoCollectionsDummy.deleteIndex).toHaveBeenCalledWith("coll", "lastId"); + expect(jQueryDummy.parent).toHaveBeenCalled(); + expect(jQueryDummy.modal).toHaveBeenCalledWith('hide'); + expect(jQueryDummy.remove).toHaveBeenCalled(); + + }); + + it("deleteIndex with error", function () { + jQueryDummy = { + parent: function () { + return jQueryDummy; + }, + remove: function () { + }, + modal: function () { + + } + }; + spyOn(jQueryDummy, "parent").andCallThrough(); + spyOn(jQueryDummy, "remove"); + spyOn(jQueryDummy, "modal"); + + spyOn(window, "$").andReturn(jQueryDummy); + + var arangoCollectionsDummy = { + deleteIndex: function () { + } + + }; + + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "deleteIndex").andReturn(false); + spyOn(arangoHelper, "arangoError"); + window.arangoCollectionsStore = new window.arangoCollections(); + + view.lastTarget = {currentTarget: "blub"}; + view.collectionName = "coll"; + view.lastId = "lastId"; + view.deleteIndex(); + + expect(window.$).not.toHaveBeenCalledWith("blub"); + expect(window.$).toHaveBeenCalledWith("#indexDeleteModal"); + expect(arangoCollectionsDummy.deleteIndex).toHaveBeenCalledWith("coll", "lastId"); + expect(jQueryDummy.parent).not.toHaveBeenCalled(); + expect(jQueryDummy.modal).toHaveBeenCalledWith('hide'); + expect(jQueryDummy.remove).not.toHaveBeenCalled(); + expect(arangoHelper.arangoError).toHaveBeenCalledWith("Could not delete index"); + + }); + + + it("selectIndexType", function () { + jQueryDummy = { + hide: function () { + }, + val: function () { + }, + show: function () { + } + }; + spyOn(jQueryDummy, "hide"); + spyOn(jQueryDummy, "show"); + spyOn(jQueryDummy, "val").andReturn("newType"); + + spyOn(window, "$").andReturn(jQueryDummy); + + view.selectIndexType(); + + expect(window.$).toHaveBeenCalledWith(".newIndexClass"); + expect(window.$).toHaveBeenCalledWith('#newIndexType'); + expect(window.$).toHaveBeenCalledWith('#newIndexTypenewType'); + expect(jQueryDummy.hide).toHaveBeenCalled(); + expect(jQueryDummy.val).toHaveBeenCalled(); + expect(jQueryDummy.show).toHaveBeenCalled(); + }); + + + it("checkboxToValue", function () { + jQueryDummy = { + prop: function () { + } + }; + spyOn(jQueryDummy, "prop"); + + spyOn(window, "$").andReturn(jQueryDummy); + + view.checkboxToValue("anId"); + + expect(window.$).toHaveBeenCalledWith("anId"); + expect(jQueryDummy.prop).toHaveBeenCalledWith("checked"); + + }); + + it("getIndex", function () { + jQueryDummy = { + append: function () { + } + }; + spyOn(jQueryDummy, "append"); + + spyOn(window, "$").andReturn(jQueryDummy); + + var arangoCollectionsDummy = { + getIndex: function () { + } + + }; + spyOn(arangoHelper, "fixTooltips"); + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "getIndex").andReturn( + { + indexes: [ + {id: "abc/def1", type: 'primary', name: "index1"}, + {id: "abc/def2", type: 'edge', name: "index2"}, + {id: "abc/def3", type: 'dummy', name: "index3", fields: [1, 2, 3]} + + + ] + } + ); + window.arangoCollectionsStore = new window.arangoCollections(); + $.each = function (list, callback) { + var callBackWraper = function (a, b) { + callback(b, a); + }; + list.forEach(callBackWraper); + }; + + view.collectionID = "coll"; + view.getIndex(); + + expect(arangoCollectionsDummy.getIndex).toHaveBeenCalledWith("coll", true); + expect(view.index).toEqual({ + indexes: [ + {id: "abc/def1", type: 'primary', name: "index1"}, + {id: "abc/def2", type: 'edge', name: "index2"}, + {id: "abc/def3", type: 'dummy', name: "index3", fields: [1, 2, 3]} + + + ] + }); + expect(window.$).toHaveBeenCalledWith("#collectionEditIndexTable"); + expect(jQueryDummy.append).toHaveBeenCalledWith( + 'def1primaryundefined' + + '' + + '' + + ''); + expect(jQueryDummy.append).toHaveBeenCalledWith( + 'def2edgeundefined' + + '' + + '' + + ''); + expect(jQueryDummy.append).toHaveBeenCalledWith('def3dummy' + + 'undefined1, 2, 3' + + ''); + + expect(arangoHelper.fixTooltips).toHaveBeenCalledWith("deleteIndex", "left"); + }); + + + it("getIndex with no result", function () { + jQueryDummy = { + append: function () { + } + }; + spyOn(jQueryDummy, "append"); + + spyOn(window, "$").andReturn(jQueryDummy); + + var arangoCollectionsDummy = { + getIndex: function () { + } + + }; + spyOn(arangoHelper, "fixTooltips"); + spyOn(window, "arangoCollections").andReturn(arangoCollectionsDummy); + spyOn(arangoCollectionsDummy, "getIndex").andReturn(undefined); + window.arangoCollectionsStore = new window.arangoCollections(); + $.each = function (list, callback) { + var callBackWraper = function (a, b) { + callback(b, a); + }; + list.forEach(callBackWraper); + }; + + view.collectionID = "coll"; + view.getIndex(); + + expect(arangoCollectionsDummy.getIndex).toHaveBeenCalledWith("coll", true); + expect(view.index).toEqual(undefined); + expect(window.$).not.toHaveBeenCalled(); + expect(jQueryDummy.append).not.toHaveBeenCalled(); + expect(arangoHelper.fixTooltips).not.toHaveBeenCalledWith(); + }); + + }); - - it("showSpinner", function() { - jQueryDummy = { - show : function() {} - } - spyOn(jQueryDummy, "show"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.showSpinner(); - expect(window.$).toHaveBeenCalledWith("#uploadIndicator"); - expect(jQueryDummy.show).toHaveBeenCalled(); - }); - - it("hideSpinner", function() { - jQueryDummy = { - hide : function() {} - } - spyOn(jQueryDummy, "hide"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.hideSpinner(); - expect(window.$).toHaveBeenCalledWith("#uploadIndicator"); - expect(jQueryDummy.hide).toHaveBeenCalled(); - }); - - - it("showImportModal", function() { - jQueryDummy = { - modal : function() {} - } - spyOn(jQueryDummy, "modal"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.showImportModal(); - expect(window.$).toHaveBeenCalledWith("#docImportModal"); - expect(jQueryDummy.modal).toHaveBeenCalledWith("show"); - }); - - - it("hideImportModal", function() { - jQueryDummy = { - modal : function() {} - } - spyOn(jQueryDummy, "modal"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.hideImportModal(); - expect(window.$).toHaveBeenCalledWith("#docImportModal"); - expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); - }); - - - it("returnPressedHandler call confirmDelete if keyCode == 13", function() { - jQueryDummy = { - attr : function() {return false;} - } - spyOn(jQueryDummy, "attr").andCallThrough(); - spyOn(window, "$").andReturn( - jQueryDummy - ); - spyOn(view, "confirmDelete").andCallFake(function () {}); - view.returnPressedHandler({keyCode : 13}); - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled"); - expect(view.confirmDelete).toHaveBeenCalled(); - }); - - it("returnPressedHandler does not call confirmDelete if keyCode !== 13", function() { - jQueryDummy = { - attr : function() {return false;} - } - spyOn(jQueryDummy, "attr"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - spyOn(view, "confirmDelete").andCallFake(function () {}); - view.returnPressedHandler({keyCode : 11}); - expect(jQueryDummy.attr).not.toHaveBeenCalled(); - expect(view.confirmDelete).not.toHaveBeenCalled(); - }); - - it("returnPressedHandler does not call confirmDelete if keyCode == 13 but" + - " confirmButton is disabled", function() { - jQueryDummy = { - attr : function() {return true;} - } - spyOn(jQueryDummy, "attr"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - spyOn(view, "confirmDelete").andCallFake(function () {}); - view.returnPressedHandler({keyCode : 13}); - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled"); - expect(view.confirmDelete).not.toHaveBeenCalled(); - }); - - it("toggleNewIndexView", function() { - jQueryDummy = { - toggle : function() {} - } - spyOn(jQueryDummy, "toggle"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - spyOn(view, "resetIndexForms").andCallFake(function () {}); - view.toggleNewIndexView(); - expect(window.$).toHaveBeenCalledWith("#indexEditView"); - expect(window.$).toHaveBeenCalledWith("#newIndexView"); - expect(jQueryDummy.toggle).toHaveBeenCalledWith("fast"); - expect(view.resetIndexForms).toHaveBeenCalled(); - }); - - - it("nop", function() { - var event = {stopPropagation : function () {}}; - spyOn(event, "stopPropagation"); - view.nop(event); - expect(event.stopPropagation).toHaveBeenCalled(); - }); - - it("listenKey with keyCode 13", function() { - spyOn(view, "addEdge"); - view.listenKey({keyCode : 13}); - expect(view.addEdge).toHaveBeenCalled(); - }); - - it("listenKey with keyCode != 13", function() { - spyOn(view, "addEdge"); - view.listenKey({keyCode : 12}); - expect(view.addEdge).not.toHaveBeenCalled(); - }); - - - it("resetView", function() { - jQueryDummy = { - val : function() {}, - css : function() {} - } - spyOn(jQueryDummy, "val"); - spyOn(jQueryDummy, "css"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - spyOn(view, "removeAllFilterItems").andCallFake(function () {}); - spyOn(view, "clearTable").andCallFake(function () {}); - var arangoDocStoreDummy = { - getDocuments : function() {} - }; - spyOn(arangoDocStoreDummy, "getDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - view.resetView(); - expect(window.$).toHaveBeenCalledWith("input"); - expect(window.$).toHaveBeenCalledWith("select"); - expect(window.$).toHaveBeenCalledWith("#documents_last"); - expect(window.$).toHaveBeenCalledWith("#documents_first"); - expect(jQueryDummy.val).toHaveBeenCalledWith(''); - expect(jQueryDummy.val).toHaveBeenCalledWith('=='); - expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "visible"); - expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "visible"); - expect(arangoDocStoreDummy.getDocuments).toHaveBeenCalledWith(view.collectionID, 1); - expect(view.removeAllFilterItems).toHaveBeenCalled(); - expect(view.clearTable).toHaveBeenCalled(); - expect(view.addDocumentSwitch).toEqual(true); - }); - - - it("start succesful Upload mit XHR ready state = 4, XHR status = 201 and parseable JSON", function() { - spyOn(view, "showSpinner"); - spyOn(view, "hideSpinner"); - spyOn(view, "hideImportModal"); - spyOn(view, "resetView"); - spyOn($, "ajax").andCallFake(function (opt) { - expect(opt.url).toEqual('/_api/import?type=auto&collection='+ - encodeURIComponent(view.colid)+ - '&createCollection=false'); - expect(opt.dataType).toEqual("json"); - expect(opt.contentType).toEqual("json"); - expect(opt.processData).toEqual(false); - expect(opt.data).toEqual(view.file); - expect(opt.async).toEqual(false); - expect(opt.type).toEqual("POST"); - opt.complete({readyState : 4, status : 201, responseText : '{"a" : 1}'}); - }); - - view.allowUpload = true; - - view.startUpload(); - expect(view.showSpinner).toHaveBeenCalled(); - expect(view.hideSpinner).toHaveBeenCalled(); - expect(view.hideImportModal).toHaveBeenCalled(); - expect(view.resetView).toHaveBeenCalled(); - }); - - it("start succesful Upload mit XHR ready state != 4", function() { - spyOn(view, "showSpinner"); - spyOn(view, "hideSpinner"); - spyOn(view, "hideImportModal"); - spyOn(view, "resetView"); - spyOn($, "ajax").andCallFake(function (opt) { - expect(opt.url).toEqual('/_api/import?type=auto&collection='+ - encodeURIComponent(view.colid)+ - '&createCollection=false'); - expect(opt.dataType).toEqual("json"); - expect(opt.contentType).toEqual("json"); - expect(opt.processData).toEqual(false); - expect(opt.data).toEqual(view.file); - expect(opt.async).toEqual(false); - expect(opt.type).toEqual("POST"); - opt.complete({readyState : 3, status : 201, responseText : '{"a" : 1}'}); - }); - - view.allowUpload = true; - spyOn(arangoHelper, "arangoError"); - view.startUpload(); - expect(view.showSpinner).toHaveBeenCalled(); - expect(view.hideSpinner).toHaveBeenCalled(); - expect(view.hideImportModal).not.toHaveBeenCalled(); - expect(view.resetView).not.toHaveBeenCalled(); - expect(arangoHelper.arangoError).toHaveBeenCalledWith("Upload error"); - }); - - it("start succesful Upload mit XHR ready state = 4, XHR status = 201 and not parseable JSON", function() { - spyOn(view, "showSpinner"); - spyOn(view, "hideSpinner"); - spyOn(view, "hideImportModal"); - spyOn(view, "resetView"); - spyOn($, "ajax").andCallFake(function (opt) { - expect(opt.url).toEqual('/_api/import?type=auto&collection='+ - encodeURIComponent(view.colid)+ - '&createCollection=false'); - expect(opt.dataType).toEqual("json"); - expect(opt.contentType).toEqual("json"); - expect(opt.processData).toEqual(false); - expect(opt.data).toEqual(view.file); - expect(opt.async).toEqual(false); - expect(opt.type).toEqual("POST"); - opt.complete({readyState : 4, status : 201, responseText : "blub"}); - }); - - view.allowUpload = true; - spyOn(arangoHelper, "arangoError"); - view.startUpload(); - expect(view.showSpinner).toHaveBeenCalled(); - expect(view.hideSpinner).toHaveBeenCalled(); - expect(view.hideImportModal).toHaveBeenCalled(); - expect(view.resetView).toHaveBeenCalled(); - expect(arangoHelper.arangoError).toHaveBeenCalledWith('Error: SyntaxError: Unable to parse JSON string'); - }); - - - it("uploadSetup", function() { - jQueryDummy = { - change : function(e) { - e({target : {files : ["BLUB"]}}); - } - } - spyOn(jQueryDummy, "change").andCallThrough(); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.uploadSetup(); - expect(window.$).toHaveBeenCalledWith("#importDocuments"); - expect(jQueryDummy.change).toHaveBeenCalledWith(jasmine.any(Function)); - expect(view.files).toEqual(["BLUB"]); - expect(view.file).toEqual("BLUB"); - expect(view.allowUpload).toEqual(true); - }); - - it("buildCollectionLink", function() { - expect(view.buildCollectionLink({get: function() {return "blub"}})).toEqual( - "collection/" + encodeURIComponent("blub") + '/documents/1' - ); - }); - - - it("prevCollection with no collectionContext.prev", function() { - jQueryDummy = { - parent : function(e) { - return jQueryDummy; - }, - addClass : function() { - - } - - } - spyOn(jQueryDummy, "parent").andCallThrough();; - spyOn(jQueryDummy, "addClass"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.collectionContext = {prev : null}; - view.prevCollection(); - expect(window.$).toHaveBeenCalledWith("#collectionPrev"); - expect(jQueryDummy.parent).toHaveBeenCalled(); - expect(jQueryDummy.addClass).toHaveBeenCalledWith("disabledPag"); - }); - - it("prevCollection with collectionContext.prev", function() { - jQueryDummy = { - parent : function(e) { - return jQueryDummy; - }, - removeClass : function() { - - } - - } - spyOn(jQueryDummy, "parent").andCallThrough();; - spyOn(jQueryDummy, "removeClass"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.collectionContext = {prev : 1}; - spyOn(window.App, "navigate"); - spyOn(view, "buildCollectionLink").andReturn(1); - view.prevCollection(); - expect(window.$).toHaveBeenCalledWith("#collectionPrev"); - expect(jQueryDummy.parent).toHaveBeenCalled(); - expect(view.buildCollectionLink).toHaveBeenCalledWith(1); - expect(window.App.navigate).toHaveBeenCalledWith(1, { - trigger: true - }); - expect(jQueryDummy.removeClass).toHaveBeenCalledWith("disabledPag"); - }); - - - it("nextCollection with no collectionContext.next", function() { - jQueryDummy = { - parent : function(e) { - return jQueryDummy; - }, - addClass : function() { - - } - - } - spyOn(jQueryDummy, "parent").andCallThrough();; - spyOn(jQueryDummy, "addClass"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.collectionContext = {next : null}; - view.nextCollection(); - expect(window.$).toHaveBeenCalledWith("#collectionNext"); - expect(jQueryDummy.parent).toHaveBeenCalled(); - expect(jQueryDummy.addClass).toHaveBeenCalledWith("disabledPag"); - }); - - it("nextCollection with collectionContext.next", function() { - jQueryDummy = { - parent : function(e) { - return jQueryDummy; - }, - removeClass : function() { - - } - - } - spyOn(jQueryDummy, "parent").andCallThrough();; - spyOn(jQueryDummy, "removeClass"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.collectionContext = {next : 1}; - spyOn(window.App, "navigate"); - spyOn(view, "buildCollectionLink").andReturn(1); - view.nextCollection(); - expect(window.$).toHaveBeenCalledWith("#collectionNext"); - expect(jQueryDummy.parent).toHaveBeenCalled(); - expect(view.buildCollectionLink).toHaveBeenCalledWith(1); - expect(window.App.navigate).toHaveBeenCalledWith(1, { - trigger: true - }); - expect(jQueryDummy.removeClass).toHaveBeenCalledWith("disabledPag"); - }); - - - it("filterCollection", function() { - jQueryDummy = { - removeClass : function() { - }, - toggleClass : function() { - }, - slideToggle : function() { - }, - hide : function() { - }, - focus : function() { - } - - } - spyOn(jQueryDummy, "removeClass"); - spyOn(jQueryDummy, "toggleClass"); - spyOn(jQueryDummy, "slideToggle"); - spyOn(jQueryDummy, "hide"); - spyOn(jQueryDummy, "focus"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.filters = [{0 : "bla"}, {1 : "blub"}]; - view.filterCollection(); - expect(window.$).toHaveBeenCalledWith("#indexCollection"); - expect(window.$).toHaveBeenCalledWith("#importCollection"); - expect(window.$).toHaveBeenCalledWith("#filterCollection"); - expect(window.$).toHaveBeenCalledWith("#filterHeader"); - expect(window.$).toHaveBeenCalledWith("#importHeader"); - expect(window.$).toHaveBeenCalledWith("#indexHeader"); - expect(window.$).toHaveBeenCalledWith("#attribute_name0"); - // next assertion seems strange but follows the strange implementation - expect(window.$).not.toHaveBeenCalledWith("#attribute_name1"); - expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); - expect(jQueryDummy.hide).toHaveBeenCalled(); - expect(jQueryDummy.focus).toHaveBeenCalled(); - }); - - it("importCollection", function() { - jQueryDummy = { - removeClass : function() { - }, - toggleClass : function() { - }, - slideToggle : function() { - }, - hide : function() { - } - - } - spyOn(jQueryDummy, "removeClass"); - spyOn(jQueryDummy, "toggleClass"); - spyOn(jQueryDummy, "slideToggle"); - spyOn(jQueryDummy, "hide"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.importCollection(); - - expect(window.$).toHaveBeenCalledWith("#filterCollection"); - expect(window.$).toHaveBeenCalledWith("#indexCollection"); - expect(window.$).toHaveBeenCalledWith("#importCollection"); - expect(window.$).toHaveBeenCalledWith("#filterHeader"); - expect(window.$).toHaveBeenCalledWith("#importHeader"); - expect(window.$).toHaveBeenCalledWith("#indexHeader"); - expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); - expect(jQueryDummy.hide).toHaveBeenCalled(); - }); - - it("indexCollection", function() { - jQueryDummy = { - removeClass : function() { - }, - toggleClass : function() { - }, - slideToggle : function() { - }, - hide : function() { - }, - show : function() { - } - - } - spyOn(jQueryDummy, "removeClass"); - spyOn(jQueryDummy, "toggleClass"); - spyOn(jQueryDummy, "slideToggle"); - spyOn(jQueryDummy, "hide"); - spyOn(jQueryDummy, "show"); - spyOn(window, "$").andReturn( - jQueryDummy - ); - view.indexCollection(); - expect(window.$).toHaveBeenCalledWith("#filterCollection"); - expect(window.$).toHaveBeenCalledWith("#importCollection"); - expect(window.$).toHaveBeenCalledWith("#indexCollection"); - expect(window.$).toHaveBeenCalledWith("#newIndexView"); - expect(window.$).toHaveBeenCalledWith("#indexEditView"); - expect(window.$).toHaveBeenCalledWith("#indexHeader"); - expect(window.$).toHaveBeenCalledWith("#importHeader"); - expect(window.$).toHaveBeenCalledWith("#filterHeader"); - expect(jQueryDummy.removeClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.toggleClass).toHaveBeenCalledWith('activated'); - expect(jQueryDummy.slideToggle).toHaveBeenCalledWith(200); - expect(jQueryDummy.hide).toHaveBeenCalled(); - expect(jQueryDummy.show).toHaveBeenCalled(); - }); - - - it("getFilterContent", function() { - - jQueryDummy = { - e : undefined, - val : function() { - var e = jQueryDummy.e; - if (e === '#attribute_value0') { - return '{"jsonval" : 1}'; - } else if (e === '#attribute_value1') { - return "stringval"; - } else if (e === '#attribute_name0') { - return 'name0'; - } else if (e === '#attribute_name1') { - return 'name1'; - } else if (e === '#operator0') { - return 'operator0'; - } else if (e === '#operator1') { - return 'operator1'; - } - } - }; - spyOn(jQueryDummy, "val").andCallThrough(); - spyOn(window, "$").andCallFake( - function (e) { - jQueryDummy.e = e; - return jQueryDummy; - } - ); - view.filters = [{0 : "bla"}, {1 : "blub"}]; - expect(view.getFilterContent()).toEqual([ - [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], - { param0 : {jsonval : 1}, param1 : "stringval"} - ]); - expect(window.$).toHaveBeenCalledWith("#attribute_value0"); - expect(window.$).toHaveBeenCalledWith("#attribute_value1"); - expect(window.$).toHaveBeenCalledWith("#attribute_name0"); - expect(window.$).toHaveBeenCalledWith("#attribute_name1"); - expect(window.$).toHaveBeenCalledWith("#operator0"); - expect(window.$).toHaveBeenCalledWith("#operator1"); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.val).toHaveBeenCalled(); - }); - - - it("sendFilter", function() { - - jQueryDummy = { - css : function() {} - - }; - spyOn(jQueryDummy, "css"); - spyOn(window, "$").andReturn(jQueryDummy); - spyOn(view, "getFilterContent").andReturn( - [ - [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], - { param0 : {jsonval : 1}, param1 : "stringval"} - ] - - ); - - var arangoDocStoreDummy = { - getFilteredDocuments : function() {} - }; - var documentsViewDummy = { - clearTable : function() {} - }; - spyOn(arangoDocStoreDummy, "getFilteredDocuments"); - spyOn(documentsViewDummy, "clearTable"); - spyOn(window, "arangoDocuments").andReturn(arangoDocStoreDummy); - spyOn(window, "DocumentsView").andReturn(documentsViewDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - window.documentsView = new window.DocumentsView(); - - - view.sendFilter(); - - expect(view.addDocumentSwitch).toEqual(false); - expect(documentsViewDummy.clearTable).toHaveBeenCalled(); - expect(arangoDocStoreDummy.getFilteredDocuments).toHaveBeenCalledWith( - view.colid, 1, - [" u.`name0`operator0@param0", " u.`name1`operator1@param1"], - { param0 : {jsonval : 1}, param1 : "stringval"} - ); - - - expect(window.$).toHaveBeenCalledWith("#documents_last"); - expect(window.$).toHaveBeenCalledWith("#documents_first"); - expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "hidden"); - expect(jQueryDummy.css).toHaveBeenCalledWith("visibility", "hidden"); - }); - - it("addFilterItem", function() { - - jQueryDummy = { - append : function() {} - - }; - spyOn(jQueryDummy, "append"); - spyOn(window, "$").andReturn(jQueryDummy); - - view.filterId = 1; - var num = 2; - view.addFilterItem(); - expect(window.$).toHaveBeenCalledWith("#filterHeader"); - expect(jQueryDummy.append).toHaveBeenCalledWith('
'+ - ''+ - ''+ - ''+ - ' ' + - '
'); - expect(view.filters[num]).toEqual(true); - - }); - - - it("filterValueKeydown with keyCode == 13", function() { - spyOn(view, "sendFilter"); - view.filterValueKeydown({keyCode : 13}); - expect(view.sendFilter).toHaveBeenCalled(); - }); - - it("filterValueKeydown with keyCode !== 13", function() { - spyOn(view, "sendFilter"); - view.filterValueKeydown({keyCode : 11}); - expect(view.sendFilter).not.toHaveBeenCalled(); - }); - - - it("removeFilterItem with keyCode !== 13", function() { - jQueryDummy = { - remove : function() {} - - }; - spyOn(jQueryDummy, "remove"); - spyOn(window, "$").andReturn(jQueryDummy); - view.filters[1] = "bla"; - - view.removeFilterItem({currentTarget : {id : "removeFilter1", parentElement : "#blub"}}); - expect(window.$).toHaveBeenCalledWith("#blub"); - expect(jQueryDummy.remove).toHaveBeenCalled(); - expect(view.filters[1]).toEqual(undefined); - }); - - it("removeAllFilterItems", function() { - jQueryDummy = { - children : function() {}, - parent : function() {} - - }; - spyOn(jQueryDummy, "children").andReturn([1, 2, 3]); - spyOn(jQueryDummy, "parent").andReturn({remove : function () {}}); - spyOn(window, "$").andReturn(jQueryDummy); - - view.removeAllFilterItems(); - expect(window.$).toHaveBeenCalledWith("#filterHeader"); - expect(window.$).toHaveBeenCalledWith("#removeFilter1"); - expect(window.$).toHaveBeenCalledWith("#removeFilter2"); - expect(window.$).toHaveBeenCalledWith("#removeFilter3"); - expect(jQueryDummy.children).toHaveBeenCalled(); - expect(jQueryDummy.parent).toHaveBeenCalled(); - - expect(view.filters).toEqual({ "0" : true }); - expect(view.filterId).toEqual(0); - }); - - it("addDocument without an error", function() { - var arangoDocStoreDummy = { - createTypeDocument : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn("newDoc"); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - spyOn(arangoHelper, "collectionApiType").andReturn("document"); - window.location.hash = "1/2"; - view.addDocument(); - - expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); - expect(arangoDocStoreDummy.createTypeDocument).toHaveBeenCalledWith("2"); - expect(window.location.hash).toEqual("#collection/" + "newDoc"); - - }); - - it("addDocument with an edge", function() { - var arangoDocStoreDummy = { - createTypeDocument : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn("newDoc"); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - jQueryDummy = { - modal : function() {} - - }; - spyOn(jQueryDummy, "modal"); - spyOn(arangoHelper, "fixTooltips"); - spyOn(window, "$").andReturn(jQueryDummy); - - spyOn(arangoHelper, "collectionApiType").andReturn("edge"); - window.location.hash = "1/2"; - view.addDocument(); - - expect(window.$).toHaveBeenCalledWith("#edgeCreateModal"); - expect(jQueryDummy.modal).toHaveBeenCalledWith('show'); - expect(arangoHelper.fixTooltips).toHaveBeenCalledWith(".modalTooltips", "left"); - expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); - expect(arangoDocStoreDummy.createTypeDocument).not.toHaveBeenCalled(); - expect(window.location.hash).toEqual("#1/2"); - - }); - - it("addDocument with an error", function() { - var arangoDocStoreDummy = { - createTypeDocument : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeDocument").andReturn(false); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - spyOn(arangoHelper, "collectionApiType").andReturn("document"); - spyOn(arangoHelper, "arangoError"); - window.location.hash = "1/2"; - view.addDocument(); - - expect(arangoHelper.collectionApiType).toHaveBeenCalledWith("2", true); - expect(arangoHelper.arangoError).toHaveBeenCalledWith('Creating document failed'); - expect(arangoDocStoreDummy.createTypeDocument).toHaveBeenCalledWith("2"); - expect(window.location.hash).toEqual("#1/2"); - - }); - - - it("addEdge with missing to ", function() { - jQueryDummy = { - e : undefined, - val : function() { - if (jQueryDummy.e === "#new-document-from") { - return ""; - }; - if (jQueryDummy.e === "#new-document-to") { - return "bla"; - } - - } - - }; - spyOn(jQueryDummy, "val").andCallThrough(); - spyOn(window, "$").andCallFake(function (e) { - jQueryDummy.e = e; - return jQueryDummy; - - }); - - var arangoDocStoreDummy = { - createTypeEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeEdge"); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - window.location.hash = "1/2"; - view.addEdge(); - expect(window.$).toHaveBeenCalledWith("#new-document-from"); - expect(window.$).toHaveBeenCalledWith("#new-document-to"); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(arangoDocStoreDummy.createTypeEdge).not.toHaveBeenCalled(); - - }); - - - it("addEdge with missing to ", function() { - jQueryDummy = { - e : undefined, - val : function() { - if (jQueryDummy.e === "#new-document-from") { - return "bla"; - }; - if (jQueryDummy.e === "#new-document-to") { - return ""; - } - - } - - }; - spyOn(jQueryDummy, "val").andCallThrough(); - spyOn(window, "$").andCallFake(function (e) { - jQueryDummy.e = e; - return jQueryDummy; - - }); - - var arangoDocStoreDummy = { - createTypeEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeEdge"); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - window.location.hash = "1/2"; - view.addEdge(); - expect(window.$).toHaveBeenCalledWith("#new-document-from"); - expect(window.$).toHaveBeenCalledWith("#new-document-to"); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(arangoDocStoreDummy.createTypeEdge).not.toHaveBeenCalled(); - - }); - - - - it("addEdge with success", function() { - jQueryDummy = { - e : undefined, - val : function() { - if (jQueryDummy.e === "#new-document-from") { - return "bla"; - }; - if (jQueryDummy.e === "#new-document-to") { - return "blub"; - } - }, - modal : function () { - - } - - - }; - spyOn(jQueryDummy, "val").andCallThrough(); - spyOn(jQueryDummy, "modal"); - spyOn(window, "$").andCallFake(function (e) { - jQueryDummy.e = e; - return jQueryDummy; - - }); - - var arangoDocStoreDummy = { - createTypeEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeEdge").andReturn("newEdge"); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - window.location.hash = "1/2"; - view.addEdge(); - expect(window.$).toHaveBeenCalledWith("#new-document-from"); - expect(window.$).toHaveBeenCalledWith("#new-document-to"); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(jQueryDummy.modal).toHaveBeenCalledWith('hide'); - expect(arangoDocStoreDummy.createTypeEdge).toHaveBeenCalledWith("2", "bla", "blub"); - expect(window.location.hash).toEqual("#collection/newEdge"); - - }); - - it("addEdge with error", function() { - jQueryDummy = { - e : undefined, - val : function() { - if (jQueryDummy.e === "#new-document-from") { - return "bla"; - }; - if (jQueryDummy.e === "#new-document-to") { - return "blub"; - } - }, - modal : function () { - - } - - - }; - spyOn(jQueryDummy, "val").andCallThrough(); - spyOn(jQueryDummy, "modal"); - spyOn(arangoHelper, "arangoError"); - spyOn(window, "$").andCallFake(function (e) { - jQueryDummy.e = e; - return jQueryDummy; - - }); - - var arangoDocStoreDummy = { - createTypeEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "createTypeEdge").andReturn(false); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - window.location.hash = "1/2"; - view.addEdge(); - expect(window.$).toHaveBeenCalledWith("#new-document-from"); - expect(window.$).toHaveBeenCalledWith("#new-document-to"); - expect(jQueryDummy.val).toHaveBeenCalled(); - expect(arangoHelper.arangoError).toHaveBeenCalledWith('Creating edge failed'); - expect(jQueryDummy.modal).not.toHaveBeenCalled(); - expect(arangoDocStoreDummy.createTypeEdge).toHaveBeenCalledWith("2", "bla", "blub"); - expect(window.location.hash).toEqual("#1/2"); - - }); - - it("first-last-next-prev document", function() { - var arangoDocumentsStoreDummy = { - getFirstDocuments : function() {}, - getLastDocuments : function() {}, - getPrevDocuments : function() {}, - getNextDocuments : function() {} - }; - spyOn(arangoDocumentsStoreDummy, "getFirstDocuments"); - spyOn(arangoDocumentsStoreDummy, "getLastDocuments"); - spyOn(arangoDocumentsStoreDummy, "getPrevDocuments"); - spyOn(arangoDocumentsStoreDummy, "getNextDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocumentsStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - - view.firstDocuments(); - expect(arangoDocumentsStoreDummy.getFirstDocuments).toHaveBeenCalled(); - view.lastDocuments(); - expect(arangoDocumentsStoreDummy.getLastDocuments).toHaveBeenCalled(); - view.prevDocuments(); - expect(arangoDocumentsStoreDummy.getPrevDocuments).toHaveBeenCalled(); - view.nextDocuments(); - expect(arangoDocumentsStoreDummy.getNextDocuments).toHaveBeenCalled(); - - - }); - - - it("remove", function() { - jQueryDummy = { - e : undefined, - prev : function() { - return jQueryDummy; - }, - attr : function () { - - }, - modal : function () { - - } - - - }; - spyOn(jQueryDummy, "prev").andCallThrough(); - spyOn(jQueryDummy, "attr"); - spyOn(jQueryDummy, "modal"); - spyOn(window, "$").andReturn(jQueryDummy); - - view.remove({currentTarget : {parentElement : "#thiselement"}}); - - expect(window.$).toHaveBeenCalledWith("#thiselement"); - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); - expect(jQueryDummy.prev).toHaveBeenCalled(); - expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", false); - expect(jQueryDummy.modal).toHaveBeenCalledWith("show"); - expect(view.alreadyClicked).toEqual(true); - expect(view.idelement).toEqual(jQueryDummy); - - }); - - - it("confirmDelete with check != source", function() { - jQueryDummy = { - attr : function () { - - } - }; - spyOn(jQueryDummy, "attr"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/4"; - spyOn(view, "reallyDelete"); - view.confirmDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", true); - expect(view.reallyDelete).toHaveBeenCalled(); - }); - - - it("confirmDelete with check = source", function() { - jQueryDummy = { - attr : function () { - - } - }; - spyOn(jQueryDummy, "attr"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/source"; - spyOn(view, "reallyDelete"); - view.confirmDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(jQueryDummy.attr).toHaveBeenCalledWith("disabled", true); - expect(view.reallyDelete).not.toHaveBeenCalled(); - }); - - - it("reallyDelete a document with error", function() { - jQueryDummy = { - closest : function () { - return jQueryDummy; - }, - get : function() { - - }, - next : function() { - return jQueryDummy; - }, - text : function() { - - } - }; - spyOn(jQueryDummy, "closest").andCallThrough(); - spyOn(jQueryDummy, "get"); - spyOn(jQueryDummy, "next").andCallThrough(); - spyOn(jQueryDummy, "text").andReturn("4"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/source"; - - view.type = "document"; - view.colid = "collection"; - - spyOn(arangoHelper, "arangoError"); - var arangoDocStoreDummy = { - deleteDocument : function() {} - }; - spyOn(arangoDocStoreDummy, "deleteDocument").andReturn(false); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - var arangoDocsStoreDummy = { - getDocuments : function() {} - }; - spyOn(arangoDocsStoreDummy, "getDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - view.target = "#confirmDeleteBtn"; - - view.reallyDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(arangoDocsStoreDummy.getDocuments).not.toHaveBeenCalled(); - expect(arangoHelper.arangoError).toHaveBeenCalledWith('Doc error'); - expect(arangoDocStoreDummy.deleteDocument).toHaveBeenCalledWith("collection", "4"); - }); - - - it("reallyDelete a edge with error", function() { - jQueryDummy = { - closest : function () { - return jQueryDummy; - }, - get : function() { - - }, - next : function() { - return jQueryDummy; - }, - text : function() { - - } - }; - spyOn(jQueryDummy, "closest").andCallThrough(); - spyOn(jQueryDummy, "get"); - spyOn(jQueryDummy, "next").andCallThrough(); - spyOn(jQueryDummy, "text").andReturn("4"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/source"; - - view.type = "edge"; - view.colid = "collection"; - - spyOn(arangoHelper, "arangoError"); - var arangoDocStoreDummy = { - deleteEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "deleteEdge").andReturn(false); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - var arangoDocsStoreDummy = { - getDocuments : function() {} - }; - spyOn(arangoDocsStoreDummy, "getDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - view.target = "#confirmDeleteBtn"; - - view.reallyDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(arangoHelper.arangoError).toHaveBeenCalledWith('Edge error'); - expect(arangoDocsStoreDummy.getDocuments).not.toHaveBeenCalled(); - expect(arangoDocStoreDummy.deleteEdge).toHaveBeenCalledWith("collection", "4"); - }); - - - it("reallyDelete a document with no error", function() { - jQueryDummy = { - closest : function () { - return jQueryDummy; - }, - get : function() { - - }, - next : function() { - return jQueryDummy; - }, - text : function() { - - }, - dataTable : function() { - return jQueryDummy; - }, - fnDeleteRow : function() { - - }, - fnGetPosition : function() { - - }, - fnClearTable : function() { - - }, - modal : function() { - - } - - }; - spyOn(jQueryDummy, "closest").andCallThrough(); - spyOn(jQueryDummy, "get").andReturn(1); - spyOn(jQueryDummy, "fnClearTable"); - spyOn(jQueryDummy, "modal"); - spyOn(jQueryDummy, "fnGetPosition").andReturn(3); - spyOn(jQueryDummy, "next").andCallThrough(); - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "fnDeleteRow").andCallThrough(); - spyOn(jQueryDummy, "text").andReturn("4"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/source"; - - view.type = "document"; - view.colid = "collection"; - - spyOn(arangoHelper, "arangoError"); - var arangoDocStoreDummy = { - deleteDocument : function() {} - }; - spyOn(arangoDocStoreDummy, "deleteDocument").andReturn(true); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - var arangoDocsStoreDummy = { - getDocuments : function() {} - }; - spyOn(arangoDocsStoreDummy, "getDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - view.target = "#confirmDeleteBtn"; - - view.reallyDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - expect(window.$).toHaveBeenCalledWith("#documentsTableID"); - expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); - - expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); - expect(jQueryDummy.dataTable).toHaveBeenCalled(); - expect(jQueryDummy.fnGetPosition).toHaveBeenCalledWith(1); - expect(jQueryDummy.fnDeleteRow).toHaveBeenCalledWith(3); - expect(jQueryDummy.fnClearTable).toHaveBeenCalledWith(); - expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); - - - expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); - expect(arangoHelper.arangoError).not.toHaveBeenCalledWith('Doc error'); - expect(arangoDocStoreDummy.deleteDocument).toHaveBeenCalledWith("collection", "4"); - }); - - - it("reallyDelete a edge with no error", function() { - jQueryDummy = { - closest : function () { - return jQueryDummy; - }, - get : function() { - - }, - next : function() { - return jQueryDummy; - }, - text : function() { - - }, - dataTable : function() { - return jQueryDummy; - }, - fnDeleteRow : function() { - - }, - fnGetPosition : function() { - - }, - fnClearTable : function() { - - }, - modal : function() { - - } - - }; - spyOn(jQueryDummy, "closest").andCallThrough(); - spyOn(jQueryDummy, "get").andReturn(1); - spyOn(jQueryDummy, "fnClearTable"); - spyOn(jQueryDummy, "modal"); - spyOn(jQueryDummy, "fnGetPosition").andReturn(3); - spyOn(jQueryDummy, "next").andCallThrough(); - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "fnDeleteRow").andCallThrough(); - spyOn(jQueryDummy, "text").andReturn("4"); - spyOn(window, "$").andReturn(jQueryDummy); - window.location.hash = "1/2/3/source"; - - view.type = "edge"; - view.colid = "collection"; - - spyOn(arangoHelper, "arangoError"); - var arangoDocStoreDummy = { - deleteEdge : function() {} - }; - spyOn(arangoDocStoreDummy, "deleteEdge").andReturn(true); - spyOn(window, "arangoDocument").andReturn(arangoDocStoreDummy); - window.arangoDocumentStore = new window.arangoDocument(); - - var arangoDocsStoreDummy = { - getDocuments : function() {} - }; - spyOn(arangoDocsStoreDummy, "getDocuments"); - spyOn(window, "arangoDocuments").andReturn(arangoDocsStoreDummy); - window.arangoDocumentsStore = new window.arangoDocuments(); - view.target = "#confirmDeleteBtn"; - - view.reallyDelete(); - - expect(window.$).toHaveBeenCalledWith("#confirmDeleteBtn"); - - - expect(window.$).toHaveBeenCalledWith("#documentsTableID"); - expect(window.$).toHaveBeenCalledWith("#docDeleteModal"); - - expect(jQueryDummy.modal).toHaveBeenCalledWith("hide"); - expect(jQueryDummy.dataTable).toHaveBeenCalled(); - expect(jQueryDummy.fnGetPosition).toHaveBeenCalledWith(1); - expect(jQueryDummy.fnDeleteRow).toHaveBeenCalledWith(3); - expect(jQueryDummy.fnClearTable).toHaveBeenCalledWith(); - expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); - - expect(arangoHelper.arangoError).not.toHaveBeenCalledWith('Edge error'); - expect(arangoDocsStoreDummy.getDocuments).toHaveBeenCalled(); - expect(arangoDocStoreDummy.deleteEdge).toHaveBeenCalledWith("collection", "4"); - }); - - - it("clicked when alreadyClicked", function() { - view.alreadyClicked = true; - expect(view.clicked("anything")).toEqual(0); - }); - - it("clicked when clicked event has no target", function() { - jQueryDummy = { - dataTable : function () { - return jQueryDummy; - }, - fnGetPosition : function () { - - } - - }; - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "fnGetPosition").andReturn(null); - spyOn(window, "$").andReturn(jQueryDummy); - view.alreadyClicked = false; - expect(view.clicked("anything")).toEqual(undefined); - }); - - it("clicked when clicked event has target but no valid checkData", function() { - jQueryDummy = { - dataTable : function () { - return jQueryDummy; - }, - fnGetPosition : function () { - - }, - fnGetData : function () { - - } - }; - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "fnGetPosition").andReturn(1); - spyOn(jQueryDummy, "fnGetData").andReturn([0, ""]); - spyOn(window, "$").andReturn(jQueryDummy); - spyOn(view, "addDocument"); - view.alreadyClicked = false; - expect(view.clicked("anything")).toEqual(undefined); - expect(view.addDocument).toHaveBeenCalled(); - }); - - it("clicked when clicked event has target and valid checkData", function() { - jQueryDummy = { - dataTable : function () { - return jQueryDummy; - }, - fnGetPosition : function () { - - }, - fnGetData : function () { - - }, - next : function () { - return jQueryDummy; - }, - text : function () { - - } - - }; - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "next").andCallThrough(); - spyOn(jQueryDummy, "text").andReturn(12); - spyOn(jQueryDummy, "fnGetPosition").andReturn(1); - spyOn(jQueryDummy, "fnGetData").andReturn([0, "true"]); - spyOn(window, "$").andReturn(jQueryDummy); - spyOn(view, "addDocument"); - view.alreadyClicked = false; - view.colid = "coll"; - expect(view.clicked({currentTarget : {firstChild : "blub"}})).toEqual(undefined); - expect(view.addDocument).not.toHaveBeenCalled(); - expect(window.$).toHaveBeenCalledWith("blub"); - expect(window.location.hash).toEqual("#collection/coll/12"); - }); - - it("initTable", function() { - jQueryDummy = { - dataTable : function () { - } - }; - spyOn(jQueryDummy, "dataTable"); - spyOn(window, "$").andReturn(jQueryDummy); - view.initTable(); - expect(jQueryDummy.dataTable).toHaveBeenCalledWith({ - "bSortClasses": false, - "bFilter": false, - "bPaginate":false, - "bRetrieve": true, - "bSortable": false, - "bSort": false, - "bLengthChange": false, - "bAutoWidth": false, - "iDisplayLength": -1, - "bJQueryUI": false, - "aoColumns": [ - { "sClass":"docsFirstCol","bSortable": false}, - { "sClass":"docsSecCol", "bSortable": false}, - { "bSortable": false, "sClass": "docsThirdCol"} - ], - "oLanguage": { "sEmptyTable": "Loading..."} - }); - }); - - it("clearTable", function() { - jQueryDummy = { - dataTable : function () { - return jQueryDummy; - }, - fnClearTable : function () { - } - }; - spyOn(jQueryDummy, "dataTable").andCallThrough(); - spyOn(jQueryDummy, "fnClearTable"); - spyOn(window, "$").andReturn(jQueryDummy); - view.table = "blub"; - view.clearTable(); - expect(window.$).toHaveBeenCalledWith("blub"); - expect(jQueryDummy.fnClearTable).toHaveBeenCalled(); - }); - /* - - drawTable: function() { - var self = this; - - *//* - if (this.addDocumentSwitch === true) { - $(self.table).dataTable().fnAddData( - [ - 'Add document', - '', - '' - ] - ); - }*//* - - if (window.arangoDocumentsStore.models.length === 0) { - $('.dataTables_empty').text('No documents'); - } - else { - - $.each(window.arangoDocumentsStore.models, function(key, value) { - - var tempObj = {}; - $.each(value.attributes.content, function(k, v) { - if (! (k === '_id' || k === '_rev' || k === '_key')) { - tempObj[k] = v; - } - }); - - $(self.table).dataTable().fnAddData( - [ - '
'
-                                      + self.cutByResolution(JSON.stringify(tempObj))
-                                      + '
', - - '
' - + value.attributes.key - + '
', - - '' - + '' - ] - ); - }); - - // we added some icons, so we need to fix their tooltips - arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "top"); - - $(".prettify").snippet("javascript", { - style: "nedit", - menu: false, - startText: false, - transparent: true, - showNum: false - }); - - } - this.totalPages = window.arangoDocumentsStore.totalPages; - this.currentPage = window.arangoDocumentsStore.currentPage; - this.documentsCount = window.arangoDocumentsStore.documentsCount; - }, - - - render: function() { - this.collectionContext = window.arangoCollectionsStore.getPosition(this.colid); - - $(this.el).html(this.template.render({})); - this.getIndex(); - this.initTable(); - this.breadcrumb(); - if (this.collectionContext.prev === null) { - $('#collectionPrev').parent().addClass('disabledPag'); - } - if (this.collectionContext.next === null) { - $('#collectionNext').parent().addClass('disabledPag'); - } - - this.uploadSetup(); - - $("[data-toggle=tooltip]").tooltip(); - - $('.modalImportTooltips').tooltip({ - placement: "left" - }); - - arangoHelper.fixTooltips(".icon_arangodb, .arangoicon", "top"); - - return this; - }, - showLoadingState: function () { - $('.dataTables_empty').text('Loading...'); - }, - renderPagination: function (totalPages, checkFilter) { - $('#documentsToolbarF').html(""); - var self = this; - - var currentPage; - if (checkFilter) { - currentPage = window.arangoDocumentsStore.currentFilterPage; - } - else { - currentPage = JSON.parse(this.pageid); - } - var target = $('#documentsToolbarF'), - options = { - left: 2, - right: 2, - page: currentPage, - lastPage: totalPages, - click: function(i) { - options.page = i; - if (checkFilter) { - var filterArray = self.getFilterContent(); - var filters = filterArray[0]; - var bindValues = filterArray[1]; - self.addDocumentSwitch = false; - - window.documentsView.clearTable(); - window.arangoDocumentsStore.getFilteredDocuments(self.colid, i, filters, bindValues); - - //Hide first/last pagination - $('#documents_last').css("visibility", "hidden"); - $('#documents_first').css("visibility", "hidden"); - } - else { - var windowLocationHash = '#collection/' + self.colid + '/documents/' + options.page; - window.location.hash = windowLocationHash; - } - } - }; - target.pagination(options); - $('#documentsToolbarF').prepend( - ''); - $('#documentsToolbarF').append( - ''); - var total = $('#totalDocuments'); - if (total.length > 0) { - total.html("Total: " + this.documentsCount + " documents"); - } else { - $('#documentsToolbarFL').append( - 'Total: ' + this.documentsCount + - ' document(s) ' - ); - } - }, - breadcrumb: function () { - this.collectionName = window.location.hash.split("/")[1]; - $('#transparentHeader').append( - '' - ); - }, - cutByResolution: function (string) { - if (string.length > 1024) { - return this.escaped(string.substr(0, 1024)) + '...'; - } - return this.escaped(string); - }, - escaped: function (value) { - return value.replace(/&/g, "&").replace(//g, ">") - .replace(/"/g, """).replace(/'/g, "'"); - }, - resetIndexForms: function () { - $('#indexHeader input').val('').prop("checked", false); - $('#newIndexType').val('Cap').prop('selected',true); - this.selectIndexType(); - }, - stringToArray: function (fieldString) { - var fields = []; - fieldString.split(',').forEach(function(field){ - field = field.replace(/(^\s+|\s+$)/g,''); - if (field !== '') { - fields.push(field); - } - }); - return fields; - }, - createIndex: function (e) { - //e.preventDefault(); - var self = this; - var collection = this.collectionName; - var indexType = $('#newIndexType').val(); - var result; - var postParameter = {}; - var fields; - var unique; - - switch(indexType) { - case 'Cap': - var size = parseInt($('#newCapSize').val(), 10) || 0; - var byteSize = parseInt($('#newCapByteSize').val(), 10) || 0; - postParameter = { - type: 'cap', - size: size, - byteSize: byteSize - }; - break; - case 'Geo': - //HANDLE ARRAY building - fields = $('#newGeoFields').val(); - var geoJson = self.checkboxToValue('#newGeoJson'); - var constraint = self.checkboxToValue('#newGeoConstraint'); - var ignoreNull = self.checkboxToValue('#newGeoIgnoreNull'); - postParameter = { - type: 'geo', - fields: self.stringToArray(fields), - geoJson: geoJson, - constraint: constraint, - ignoreNull: ignoreNull - }; - break; - case 'Hash': - fields = $('#newHashFields').val(); - unique = self.checkboxToValue('#newHashUnique'); - postParameter = { - type: 'hash', - fields: self.stringToArray(fields), - unique: unique - }; - break; - case 'Fulltext': - fields = ($('#newFulltextFields').val()); - var minLength = parseInt($('#newFulltextMinLength').val(), 10) || 0; - postParameter = { - type: 'fulltext', - fields: self.stringToArray(fields), - minLength: minLength - }; - break; - case 'Skiplist': - fields = $('#newSkiplistFields').val(); - unique = self.checkboxToValue('#newSkiplistUnique'); - postParameter = { - type: 'skiplist', - fields: self.stringToArray(fields), - unique: unique - }; - break; - } - result = window.arangoCollectionsStore.createIndex(collection, postParameter); - if (result === true) { - $('#collectionEditIndexTable tr').remove(); - self.getIndex(); - self.toggleNewIndexView(); - self.resetIndexForms(); - } - else { - if (result.responseText) { - var message = JSON.parse(result.responseText); - arangoHelper.arangoNotification("Document error", message.errorMessage); - } - else { - arangoHelper.arangoNotification("Document error", "Could not create index."); - } - } - }, - - prepDeleteIndex: function (e) { - this.lastTarget = e; - this.lastId = $(this.lastTarget.currentTarget). - parent(). - parent(). - first(). - children(). - first(). - text(); - $("#indexDeleteModal").modal('show'); - }, - deleteIndex: function () { - var result = window.arangoCollectionsStore.deleteIndex(this.collectionName, this.lastId); - if (result === true) { - $(this.lastTarget.currentTarget).parent().parent().remove(); - } - else { - arangoHelper.arangoError("Could not delete index"); - } - $("#indexDeleteModal").modal('hide'); - }, - selectIndexType: function () { - $('.newIndexClass').hide(); - var type = $('#newIndexType').val(); - $('#newIndexType'+type).show(); - }, - checkboxToValue: function (id) { - return $(id).prop('checked'); - }, - getIndex: function () { - this.index = window.arangoCollectionsStore.getIndex(this.collectionID, true); - var cssClass = 'collectionInfoTh modal-text'; - if (this.index) { - var fieldString = ''; - var actionString = ''; - - $.each(this.index.indexes, function(k,v) { - if (v.type === 'primary' || v.type === 'edge') { - actionString = ''; - } - else { - actionString = ''; - } - - if (v.fields !== undefined) { - fieldString = v.fields.join(", "); - } - - //cut index id - var position = v.id.indexOf('/'); - var indexId = v.id.substr(position+1, v.id.length); - - $('#collectionEditIndexTable').append( - ''+ - '' + indexId + ''+ - '' + v.type + ''+ - '' + v.unique + ''+ - '' + fieldString + ''+ - '' + actionString + ''+ - '' - ); - }); - - arangoHelper.fixTooltips("deleteIndex", "left"); - } - } - }); - }());*/ - }); - }()); diff --git a/lib/BasicsC/associative.c b/lib/BasicsC/associative.c index dbf6884cab..3bb98e19b0 100644 --- a/lib/BasicsC/associative.c +++ b/lib/BasicsC/associative.c @@ -48,7 +48,7 @@ /// @brief initial number of elements in the array //////////////////////////////////////////////////////////////////////////////// -#define INITIAL_SIZE (10) +#define INITIAL_SIZE (11) //////////////////////////////////////////////////////////////////////////////// /// @} @@ -1269,17 +1269,6 @@ int TRI_InitAssociativeSynced (TRI_associative_synced_t* array, array->_nrAlloc = INITIAL_SIZE; -#ifdef TRI_INTERNAL_STATS - array->_nrFinds = 0; - array->_nrAdds = 0; - array->_nrRems = 0; - array->_nrResizes = 0; - array->_nrProbesF = 0; - array->_nrProbesA = 0; - array->_nrProbesD = 0; - array->_nrProbesR = 0; -#endif - TRI_InitReadWriteLock(&array->_lock); return TRI_ERROR_NO_ERROR; @@ -1332,21 +1321,13 @@ void const* TRI_LookupByKeyAssociativeSynced (TRI_associative_synced_t* array, // compute the hash hash = array->hashKey(array, key); - i = hash % array->_nrAlloc; - -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrFinds++; -#endif // search the table TRI_ReadLockReadWriteLock(&array->_lock); + i = hash % array->_nrAlloc; while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesF++; -#endif } result = array->_table[i]; @@ -1369,21 +1350,13 @@ void const* TRI_LookupByElementAssociativeSynced (TRI_associative_synced_t* arra // compute the hash hash = array->hashElement(array, element); - i = hash % array->_nrAlloc; - -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrFinds++; -#endif // search the table TRI_ReadLockReadWriteLock(&array->_lock); + i = hash % array->_nrAlloc; while (array->_table[i] != NULL && ! array->isEqualElementElement(array, element, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesF++; -#endif } result = array->_table[i]; @@ -1399,40 +1372,38 @@ void const* TRI_LookupByElementAssociativeSynced (TRI_associative_synced_t* arra //////////////////////////////////////////////////////////////////////////////// void* TRI_InsertElementAssociativeSynced (TRI_associative_synced_t* array, - void* element) { + void* element, + bool overwrite) { uint64_t hash; uint64_t i; void* old; + // compute the hash + hash = array->hashElement(array, element); + + TRI_WriteLockReadWriteLock(&array->_lock); + // check for out-of-memory - if (array->_nrAlloc == array->_nrUsed) { + if (array->_nrAlloc == array->_nrUsed && ! overwrite) { + TRI_WriteUnlockReadWriteLock(&array->_lock); TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); return NULL; } - // compute the hash - hash = array->hashElement(array, element); i = hash % array->_nrAlloc; -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrAdds++; -#endif - // search the table - TRI_WriteLockReadWriteLock(&array->_lock); - while (array->_table[i] != NULL && ! array->isEqualElementElement(array, element, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesA++; -#endif } old = array->_table[i]; // if we found an element, return if (old != NULL) { + if (overwrite) { + array->_table[i] = element; + } TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } @@ -1456,40 +1427,38 @@ void* TRI_InsertElementAssociativeSynced (TRI_associative_synced_t* array, void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t* array, void const* key, - void* element) { + void* element, + bool overwrite) { uint64_t hash; uint64_t i; void* old; - // check for out-of-memory - if (array->_nrAlloc == array->_nrUsed) { - TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); - return NULL; - } - // compute the hash hash = array->hashKey(array, key); - i = hash % array->_nrAlloc; - -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrAdds++; -#endif // search the table TRI_WriteLockReadWriteLock(&array->_lock); + + // check for out-of-memory + if (array->_nrAlloc == array->_nrUsed && ! overwrite) { + TRI_WriteUnlockReadWriteLock(&array->_lock); + TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); + return NULL; + } + + i = hash % array->_nrAlloc; while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesA++; -#endif } old = array->_table[i]; // if we found an element, return if (old != NULL) { + if (overwrite) { + array->_table[i] = element; + } TRI_WriteUnlockReadWriteLock(&array->_lock); return old; } @@ -1519,21 +1488,13 @@ void* TRI_RemoveElementAssociativeSynced (TRI_associative_synced_t* array, void* old; hash = array->hashElement(array, element); + + TRI_WriteLockReadWriteLock(&array->_lock); i = hash % array->_nrAlloc; -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrRems++; -#endif - // search the table - TRI_WriteLockReadWriteLock(&array->_lock); - while (array->_table[i] != NULL && ! array->isEqualElementElement(array, element, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesD++; -#endif } // if we did not find such an item return 0 @@ -1579,21 +1540,13 @@ void* TRI_RemoveKeyAssociativeSynced (TRI_associative_synced_t* array, void* old; hash = array->hashKey(array, key); + + TRI_WriteLockReadWriteLock(&array->_lock); i = hash % array->_nrAlloc; -#ifdef TRI_INTERNAL_STATS - // update statistics - array->_nrRems++; -#endif - // search the table - TRI_WriteLockReadWriteLock(&array->_lock); - while (array->_table[i] != NULL && ! array->isEqualKeyElement(array, key, array->_table[i])) { i = TRI_IncModU64(i, array->_nrAlloc); -#ifdef TRI_INTERNAL_STATS - array->_nrProbesD++; -#endif } // if we did not find such an item return false diff --git a/lib/BasicsC/associative.h b/lib/BasicsC/associative.h index c774d6b2c3..f27014a479 100644 --- a/lib/BasicsC/associative.h +++ b/lib/BasicsC/associative.h @@ -419,18 +419,6 @@ typedef struct TRI_associative_synced_s { TRI_read_write_lock_t _lock; -#ifdef TRI_INTERNAL_STATS - uint64_t _nrFinds; // statistics: number of lookup calls - uint64_t _nrAdds; // statistics: number of insert calls - uint64_t _nrRems; // statistics: number of remove calls - uint64_t _nrResizes; // statistics: number of resizes - - uint64_t _nrProbesF; // statistics: number of misses while looking up - uint64_t _nrProbesA; // statistics: number of misses while inserting - uint64_t _nrProbesD; // statistics: number of misses while removing - uint64_t _nrProbesR; // statistics: number of misses while adding -#endif - TRI_memory_zone_t* _memoryZone; } TRI_associative_synced_t; @@ -494,31 +482,39 @@ void const* TRI_LookupByKeyAssociativeSynced (TRI_associative_synced_t*, void co /// @brief lookups an element given an element //////////////////////////////////////////////////////////////////////////////// -void const* TRI_LookupByElementAssociativeSynced (TRI_associative_synced_t*, void const* element); +void const* TRI_LookupByElementAssociativeSynced (TRI_associative_synced_t*, + void const*); //////////////////////////////////////////////////////////////////////////////// /// @brief adds an element to the array //////////////////////////////////////////////////////////////////////////////// -void* TRI_InsertElementAssociativeSynced (TRI_associative_synced_t*, void* element); +void* TRI_InsertElementAssociativeSynced (TRI_associative_synced_t*, + void*, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief adds an key/element to the array //////////////////////////////////////////////////////////////////////////////// -void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t*, void const* key, void* element); +void* TRI_InsertKeyAssociativeSynced (TRI_associative_synced_t*, + void const*, + void*, + bool); //////////////////////////////////////////////////////////////////////////////// /// @brief removes an element from the array //////////////////////////////////////////////////////////////////////////////// -void* TRI_RemoveElementAssociativeSynced (TRI_associative_synced_t*, void const* element); +void* TRI_RemoveElementAssociativeSynced (TRI_associative_synced_t*, + void const*); //////////////////////////////////////////////////////////////////////////////// /// @brief removes an key/element to the array //////////////////////////////////////////////////////////////////////////////// -void* TRI_RemoveKeyAssociativeSynced (TRI_associative_synced_t*, void const* key); +void* TRI_RemoveKeyAssociativeSynced (TRI_associative_synced_t*, + void const*); //////////////////////////////////////////////////////////////////////////////// /// @brief get the number of elements from the array diff --git a/lib/ShapedJson/json-shaper.cpp b/lib/ShapedJson/json-shaper.cpp index 9cfae6be3a..66c4d0edf0 100644 --- a/lib/ShapedJson/json-shaper.cpp +++ b/lib/ShapedJson/json-shaper.cpp @@ -285,10 +285,10 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper, TRI_Free(shaper->_memoryZone, aids); - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributePathsByName, name, result); + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributePathsByName, name, result, false); assert(f == NULL); - f = TRI_InsertKeyAssociativeSynced(&shaper->_attributePathsByPid, &result->_pid, result); + f = TRI_InsertKeyAssociativeSynced(&shaper->_attributePathsByPid, &result->_pid, result, false); assert(f == NULL); // return pid