mongo_browser 0.1.3 → 0.2.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/.travis.yml +3 -3
- data/README.md +1 -25
- data/Rakefile +0 -1
- data/app/assets/images/background.png +0 -0
- data/app/assets/javascripts/app/controllers/alerts.js.coffee +12 -0
- data/app/assets/javascripts/app/controllers/breadcrumbs.js.coffee +25 -0
- data/app/assets/javascripts/app/controllers/collections.js.coffee +40 -0
- data/app/assets/javascripts/app/controllers/databases.js.coffee +39 -0
- data/app/assets/javascripts/app/controllers/documents.js.coffee +49 -0
- data/app/assets/javascripts/app/controllers/main.js.coffee +10 -0
- data/app/assets/javascripts/app/controllers/server_info.js.coffee +14 -0
- data/app/assets/javascripts/app/controllers.js.coffee +2 -0
- data/app/assets/javascripts/app/directives.js.coffee +20 -0
- data/app/assets/javascripts/app/filters.js.coffee +48 -0
- data/app/assets/javascripts/app/modules/dialogs.js.coffee +29 -0
- data/app/assets/javascripts/app/modules/pager.js.coffee +87 -0
- data/app/assets/javascripts/app/modules/table_filter.js.coffee +27 -0
- data/app/assets/javascripts/app/resources.js.coffee +22 -0
- data/app/assets/javascripts/app/services.js.coffee +36 -0
- data/app/assets/javascripts/app.js.coffee +8 -0
- data/app/assets/javascripts/application.js.coffee +35 -6
- data/app/assets/javascripts/templates/.gitkeep +0 -0
- data/app/assets/javascripts/templates.js.coffee +1 -0
- data/app/assets/javascripts/vendor.js.coffee +5 -0
- data/app/assets/stylesheets/application.css.scss +46 -3
- data/app/assets/templates/collections.html +53 -0
- data/app/assets/templates/databases.html +32 -0
- data/app/assets/templates/documents.html +45 -0
- data/app/assets/templates/pager.html +13 -0
- data/app/{views/server_info.erb → assets/templates/server_info.html} +5 -7
- data/app/assets/templates/table_filter.html +10 -0
- data/bin/mongo_browser +8 -45
- data/config-e2e.ru +20 -0
- data/grunt.js +36 -0
- data/lib/mongo_browser/application.rb +143 -64
- data/lib/mongo_browser/middleware/sprockets_base.rb +11 -0
- data/lib/mongo_browser/middleware/sprockets_sinatra.rb +3 -7
- data/lib/mongo_browser/middleware/sprockets_specs.rb +18 -0
- data/lib/mongo_browser/models/collection.rb +67 -0
- data/lib/mongo_browser/models/database.rb +52 -0
- data/lib/mongo_browser/models/document.rb +17 -0
- data/lib/mongo_browser/models/pager.rb +30 -0
- data/lib/mongo_browser/models/server.rb +51 -0
- data/lib/mongo_browser/version.rb +1 -1
- data/lib/mongo_browser.rb +10 -5
- data/mongo_browser.gemspec +4 -11
- data/public/index.html +47 -0
- data/script/ci_all +21 -0
- data/script/ci_e2e +11 -0
- data/script/ci_javascripts +4 -0
- data/script/ci_rspec +3 -0
- data/spec/features/collections_list_spec.rb +6 -49
- data/spec/features/documents_list_spec.rb +15 -14
- data/spec/features/server_info_spec.rb +3 -3
- data/spec/javascripts/app/controllers/alerts_spec.js.coffee +36 -0
- data/spec/javascripts/app/controllers/breadcrumbs_spec.js.coffee +28 -0
- data/spec/javascripts/app/controllers/collections_spec.js.coffee +78 -0
- data/spec/javascripts/app/controllers/databases_spec.js.coffee +55 -0
- data/spec/javascripts/app/controllers/documents_spec.js.coffee +62 -0
- data/spec/javascripts/app/controllers/main_spec.js.coffee +20 -0
- data/spec/javascripts/app/controllers/server_info_spec.js.coffee +21 -0
- data/spec/javascripts/app/directives_spec.js.coffee +58 -0
- data/spec/javascripts/app/filters_spec.js.coffee +99 -0
- data/spec/javascripts/app/modules/dialogs_spec.js.coffee +51 -0
- data/spec/javascripts/app/modules/pager_spec.js.coffee +104 -0
- data/spec/javascripts/app/modules/table_filter_spec.js.coffee +76 -0
- data/spec/javascripts/app/services_spec.js.coffee +83 -0
- data/spec/javascripts/config/testacular-e2e.conf.js +19 -0
- data/spec/javascripts/config/testacular.conf.js +43 -0
- data/spec/javascripts/e2e/collections_scenario.js.coffee +49 -0
- data/spec/javascripts/e2e/databases_scenario.js.coffee +74 -0
- data/spec/javascripts/e2e/documents_scenario.js.coffee +18 -0
- data/spec/javascripts/e2e/server_info_scenario.js.coffee +12 -0
- data/spec/javascripts/helpers/matchers.js.coffee +5 -0
- data/spec/javascripts/helpers/mocks.js.coffee +7 -0
- data/spec/javascripts/helpers_e2e/app_element.js.coffee +6 -0
- data/spec/javascripts/lib/angular-mocks.js +1740 -0
- data/spec/javascripts/lib/angular-scenario.js +26147 -0
- data/spec/javascripts/lib/jasmine-html.js +681 -0
- data/spec/javascripts/lib/jasmine.css +82 -0
- data/spec/javascripts/lib/jasmine.js +2600 -0
- data/spec/javascripts/runner.html +54 -0
- data/spec/javascripts/runner_e2e.html +10 -0
- data/spec/javascripts/spec.js.coffee +2 -0
- data/spec/javascripts/spec_e2e.js.coffee +2 -0
- data/spec/lib/models/collection_spec.rb +80 -0
- data/spec/lib/models/database_spec.rb +75 -0
- data/spec/lib/models/document_spec.rb +17 -0
- data/spec/lib/models/pager_spec.rb +64 -0
- data/spec/lib/models/server_spec.rb +76 -0
- data/spec/lib/mongo_browser_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -19
- data/spec/support/feature_example_group.rb +8 -3
- data/spec/support/fixtures/databases.json +8 -0
- data/spec/support/fixtures.rb +20 -3
- data/spec/support/matchers/have_flash_message.rb +1 -1
- data/spec/support/mongod.rb +37 -21
- data/spec/support/mongodb.conf +47 -0
- data/vendor/assets/javascripts/angular/angular-bootstrap.js +166 -0
- data/vendor/assets/javascripts/angular/angular-resource.js +435 -0
- data/vendor/assets/javascripts/angular/angular-sanitize.js +535 -0
- data/vendor/assets/javascripts/angular/angular.js +14531 -0
- data/vendor/assets/javascripts/underscore.js +1200 -0
- metadata +136 -148
- data/app/assets/javascripts/app/table_filter.js.coffee +0 -50
- data/app/assets/javascripts/ujs.js.coffee +0 -23
- data/app/views/collections/index.erb +0 -59
- data/app/views/databases/index.erb +0 -29
- data/app/views/documents/index.erb +0 -61
- data/app/views/layout/_flash_messages.erb +0 -10
- data/app/views/layout/_navbar.erb +0 -22
- data/app/views/layout.erb +0 -20
- data/app/views/shared/_filter.erb +0 -14
- data/features/mongo_browser.feature +0 -18
- data/features/step_definitions/mongo_browser_steps.rb +0 -1
- data/features/support/env.rb +0 -18
- data/spec/features/databases_list_spec.rb +0 -65
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
describe "collections", ->
|
|
2
|
+
beforeEach module("mb.controllers")
|
|
3
|
+
beforeEach module("mb.dialogs")
|
|
4
|
+
beforeEach module("mocks")
|
|
5
|
+
|
|
6
|
+
$scope = null
|
|
7
|
+
$httpBackend = null
|
|
8
|
+
alerts = null
|
|
9
|
+
|
|
10
|
+
beforeEach inject ($injector, $rootScope, $controller) ->
|
|
11
|
+
alerts = $injector.get("alerts")
|
|
12
|
+
|
|
13
|
+
$routeParams = $injector.get("$routeParams")
|
|
14
|
+
$routeParams.dbName = "test_database"
|
|
15
|
+
|
|
16
|
+
$httpBackend = $injector.get("$httpBackend")
|
|
17
|
+
$httpBackend.when("GET", "/api/databases/test_database/collections.json")
|
|
18
|
+
.respond([])
|
|
19
|
+
$httpBackend.when("GET", "/api/databases/test_database/stats.json")
|
|
20
|
+
.respond({})
|
|
21
|
+
|
|
22
|
+
$scope = $rootScope.$new()
|
|
23
|
+
$controller "collections",
|
|
24
|
+
$scope: $scope
|
|
25
|
+
|
|
26
|
+
$httpBackend.flush()
|
|
27
|
+
|
|
28
|
+
afterEach ->
|
|
29
|
+
$httpBackend.verifyNoOutstandingExpectation()
|
|
30
|
+
$httpBackend.verifyNoOutstandingRequest()
|
|
31
|
+
|
|
32
|
+
describe "#isLoading", ->
|
|
33
|
+
it "returns true when the resouce it loading", ->
|
|
34
|
+
$scope.loading = true
|
|
35
|
+
expect($scope.isLoading()).toBeTruthy()
|
|
36
|
+
|
|
37
|
+
it "otherwise returns false", ->
|
|
38
|
+
$scope.loading = false
|
|
39
|
+
expect($scope.isLoading()).toBeFalsy()
|
|
40
|
+
|
|
41
|
+
# TODO refactor this spec
|
|
42
|
+
describe "#delete", ->
|
|
43
|
+
collection = null
|
|
44
|
+
|
|
45
|
+
beforeEach ->
|
|
46
|
+
collection = dbName: "test_database", name: "dummy-collection-id"
|
|
47
|
+
|
|
48
|
+
it "shows a confirmation dialog", inject (dialogsHandler) ->
|
|
49
|
+
spyOn(dialogsHandler, "confirm")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
$scope.delete(collection)
|
|
53
|
+
|
|
54
|
+
expect(dialogsHandler.confirm).toHaveBeenCalledWith \
|
|
55
|
+
"Deleting dummy-collection-id. Are you sure?",
|
|
56
|
+
jasmine.any(Function)
|
|
57
|
+
|
|
58
|
+
describe "when the dialog was confirmed", ->
|
|
59
|
+
beforeEach inject (dialogsHandler) ->
|
|
60
|
+
$httpBackend.when("DELETE", "/api/databases/test_database/collections.json?id=dummy-collection-id")
|
|
61
|
+
.respond([])
|
|
62
|
+
|
|
63
|
+
spyOn(alerts, "info")
|
|
64
|
+
$scope.delete(collection)
|
|
65
|
+
dialogsHandler.confirmed()
|
|
66
|
+
|
|
67
|
+
it "sends a delete request", ->
|
|
68
|
+
$httpBackend.flush()
|
|
69
|
+
|
|
70
|
+
it "displays a flash message", ->
|
|
71
|
+
$httpBackend.flush()
|
|
72
|
+
expect(alerts.info).toHaveBeenCalledWith("Collection dummy-collection-id has been deleted.")
|
|
73
|
+
|
|
74
|
+
describe "when the dialog was disposed", ->
|
|
75
|
+
it "does nothing", inject (dialogsHandler) ->
|
|
76
|
+
# When
|
|
77
|
+
$scope.delete(name: "dummy-collection-id")
|
|
78
|
+
dialogsHandler.disposed()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
describe "databases", ->
|
|
2
|
+
beforeEach module("mb.controllers")
|
|
3
|
+
beforeEach module("mb.dialogs")
|
|
4
|
+
beforeEach module("mocks")
|
|
5
|
+
|
|
6
|
+
$scope = null
|
|
7
|
+
$httpBackend = null
|
|
8
|
+
alerts = null
|
|
9
|
+
|
|
10
|
+
beforeEach inject ($injector, $rootScope, $controller) ->
|
|
11
|
+
alerts = $injector.get("alerts")
|
|
12
|
+
|
|
13
|
+
$httpBackend = $injector.get("$httpBackend")
|
|
14
|
+
$httpBackend.when("GET", "/api/databases.json").respond([])
|
|
15
|
+
|
|
16
|
+
$scope = $rootScope.$new()
|
|
17
|
+
$controller "databases",
|
|
18
|
+
$scope: $scope
|
|
19
|
+
|
|
20
|
+
$httpBackend.flush()
|
|
21
|
+
|
|
22
|
+
afterEach ->
|
|
23
|
+
$httpBackend.verifyNoOutstandingExpectation()
|
|
24
|
+
$httpBackend.verifyNoOutstandingRequest()
|
|
25
|
+
|
|
26
|
+
# TODO rewrite this spec
|
|
27
|
+
describe "#delete", ->
|
|
28
|
+
it "shows a confirmation dialog", inject (dialogsHandler) ->
|
|
29
|
+
spyOn(dialogsHandler, "confirm")
|
|
30
|
+
$scope.delete(name: "test_database_name")
|
|
31
|
+
expect(dialogsHandler.confirm).toHaveBeenCalledWith \
|
|
32
|
+
"Deleting test_database_name. Are you sure?",
|
|
33
|
+
jasmine.any(Function)
|
|
34
|
+
|
|
35
|
+
describe "when the dialog was confirmed", ->
|
|
36
|
+
beforeEach inject (dialogsHandler) ->
|
|
37
|
+
$httpBackend.when("DELETE", "/api/databases.json?id=test_database_name")
|
|
38
|
+
.respond([])
|
|
39
|
+
|
|
40
|
+
spyOn(alerts, "info")
|
|
41
|
+
$scope.delete(name: "test_database_name")
|
|
42
|
+
dialogsHandler.confirmed()
|
|
43
|
+
|
|
44
|
+
it "sends a delete request", ->
|
|
45
|
+
$httpBackend.flush()
|
|
46
|
+
|
|
47
|
+
it "displays a flash message", ->
|
|
48
|
+
$httpBackend.flush()
|
|
49
|
+
expect(alerts.info).toHaveBeenCalledWith("Database test_database_name has been deleted.")
|
|
50
|
+
|
|
51
|
+
describe "when the dialog was disposed", ->
|
|
52
|
+
it "does nothing", inject (dialogsHandler) ->
|
|
53
|
+
# When
|
|
54
|
+
$scope.delete(name: "test_database_name")
|
|
55
|
+
dialogsHandler.disposed()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
describe "documents", ->
|
|
2
|
+
beforeEach module("mb.controllers")
|
|
3
|
+
beforeEach module("mb.dialogs")
|
|
4
|
+
beforeEach module("mocks")
|
|
5
|
+
|
|
6
|
+
$scope = null
|
|
7
|
+
$httpBackend = null
|
|
8
|
+
alerts = null
|
|
9
|
+
|
|
10
|
+
beforeEach inject ($injector, $rootScope, $controller) ->
|
|
11
|
+
alerts = $injector.get("alerts")
|
|
12
|
+
|
|
13
|
+
$routeParams = $injector.get("$routeParams")
|
|
14
|
+
$routeParams.dbName = "test_database"
|
|
15
|
+
$routeParams.collectionName = "test_collection"
|
|
16
|
+
|
|
17
|
+
$httpBackend = $injector.get('$httpBackend')
|
|
18
|
+
$httpBackend.when("GET", "/api/databases/test_database/collections/test_collection/documents.json?page=1")
|
|
19
|
+
.respond([])
|
|
20
|
+
$httpBackend.when("GET", "/api/databases/test_database/collections/test_collection/stats.json")
|
|
21
|
+
.respond({})
|
|
22
|
+
|
|
23
|
+
$scope = $rootScope.$new()
|
|
24
|
+
$controller "documents",
|
|
25
|
+
$scope: $scope
|
|
26
|
+
|
|
27
|
+
$httpBackend.flush()
|
|
28
|
+
|
|
29
|
+
afterEach ->
|
|
30
|
+
$httpBackend.verifyNoOutstandingExpectation()
|
|
31
|
+
$httpBackend.verifyNoOutstandingRequest()
|
|
32
|
+
|
|
33
|
+
# TODO rewrite this spec
|
|
34
|
+
describe "#delete", ->
|
|
35
|
+
it "shows a confirmation dialog", inject (dialogsHandler) ->
|
|
36
|
+
spyOn(dialogsHandler, "confirm")
|
|
37
|
+
$scope.delete(id: "dummy-document-id")
|
|
38
|
+
expect(dialogsHandler.confirm).toHaveBeenCalledWith \
|
|
39
|
+
"Are you sure?",
|
|
40
|
+
jasmine.any(Function)
|
|
41
|
+
|
|
42
|
+
describe "when the dialog was confirmed", ->
|
|
43
|
+
beforeEach inject (dialogsHandler) ->
|
|
44
|
+
$httpBackend.when("DELETE", "/api/databases/test_database/collections/test_collection/documents.json?id=dummy-document-id")
|
|
45
|
+
.respond([])
|
|
46
|
+
|
|
47
|
+
spyOn(alerts, "info")
|
|
48
|
+
$scope.delete(id: "dummy-document-id")
|
|
49
|
+
dialogsHandler.confirmed()
|
|
50
|
+
|
|
51
|
+
it "sends a delete request", ->
|
|
52
|
+
$httpBackend.flush()
|
|
53
|
+
|
|
54
|
+
it "displays a flash message", ->
|
|
55
|
+
$httpBackend.flush()
|
|
56
|
+
expect(alerts.info).toHaveBeenCalledWith("Document dummy-document-id has been deleted.")
|
|
57
|
+
|
|
58
|
+
describe "when the dialog was disposed", ->
|
|
59
|
+
it "does nothing", inject (dialogsHandler) ->
|
|
60
|
+
# When
|
|
61
|
+
$scope.delete(id: "dummy-document-id")
|
|
62
|
+
dialogsHandler.disposed()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
describe "main", ->
|
|
2
|
+
beforeEach module("mb.controllers")
|
|
3
|
+
|
|
4
|
+
$scope = null
|
|
5
|
+
$httpBackend = null
|
|
6
|
+
|
|
7
|
+
beforeEach inject ($injector, $rootScope, $controller) ->
|
|
8
|
+
$scope = $rootScope.$new()
|
|
9
|
+
|
|
10
|
+
$httpBackend = $injector.get('$httpBackend')
|
|
11
|
+
$httpBackend.when("GET", "/api/version.json").respond([])
|
|
12
|
+
|
|
13
|
+
$controller "main",
|
|
14
|
+
$scope: $scope
|
|
15
|
+
|
|
16
|
+
$httpBackend.flush()
|
|
17
|
+
|
|
18
|
+
it "fetches the app version", ->
|
|
19
|
+
$httpBackend.verifyNoOutstandingExpectation()
|
|
20
|
+
$httpBackend.verifyNoOutstandingRequest()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
describe "serverInfo", ->
|
|
2
|
+
beforeEach module("mb.controllers")
|
|
3
|
+
beforeEach module("mocks")
|
|
4
|
+
|
|
5
|
+
$scope = null
|
|
6
|
+
$httpBackend = null
|
|
7
|
+
|
|
8
|
+
beforeEach inject ($injector, $rootScope, $controller) ->
|
|
9
|
+
$scope = $rootScope.$new()
|
|
10
|
+
|
|
11
|
+
$httpBackend = $injector.get('$httpBackend')
|
|
12
|
+
$httpBackend.when("GET", "/api/server_info.json").respond([])
|
|
13
|
+
|
|
14
|
+
$controller "serverInfo",
|
|
15
|
+
$scope: $scope
|
|
16
|
+
|
|
17
|
+
$httpBackend.flush()
|
|
18
|
+
|
|
19
|
+
it "fetches information about the server", ->
|
|
20
|
+
$httpBackend.verifyNoOutstandingExpectation()
|
|
21
|
+
$httpBackend.verifyNoOutstandingRequest()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
describe "directives", ->
|
|
2
|
+
beforeEach module("mb.directives")
|
|
3
|
+
|
|
4
|
+
$scope = null
|
|
5
|
+
element = null
|
|
6
|
+
|
|
7
|
+
describe "osEsc", ->
|
|
8
|
+
beforeEach inject ($compile, $rootScope) ->
|
|
9
|
+
$scope = $rootScope.$new()
|
|
10
|
+
$scope.bar = ->
|
|
11
|
+
|
|
12
|
+
element = $compile('<input type="text" on-esc="bar()" />')($scope)
|
|
13
|
+
$scope.$digest()
|
|
14
|
+
|
|
15
|
+
it "calls the given function when the ESC was pressed", ->
|
|
16
|
+
spyOn($scope, 'bar')
|
|
17
|
+
|
|
18
|
+
event = jQuery.Event("keyup", keyCode: 27)
|
|
19
|
+
element.trigger(event)
|
|
20
|
+
|
|
21
|
+
expect($scope.bar).toHaveBeenCalled()
|
|
22
|
+
|
|
23
|
+
it "does nothing on other keys", ->
|
|
24
|
+
spyOn($scope, 'bar')
|
|
25
|
+
|
|
26
|
+
event = jQuery.Event("keyup", keyCode: 13)
|
|
27
|
+
element.trigger(event)
|
|
28
|
+
|
|
29
|
+
expect($scope.bar).not.toHaveBeenCalled()
|
|
30
|
+
|
|
31
|
+
describe "deleteButton", ->
|
|
32
|
+
beforeEach inject ($compile, $rootScope) ->
|
|
33
|
+
$scope = $rootScope.$new()
|
|
34
|
+
$scope.bar = ->
|
|
35
|
+
|
|
36
|
+
template = """
|
|
37
|
+
<div>
|
|
38
|
+
<delete-button ng-click="bar()" />
|
|
39
|
+
</div>
|
|
40
|
+
"""
|
|
41
|
+
element = $compile(template)($scope)
|
|
42
|
+
$scope.$digest()
|
|
43
|
+
|
|
44
|
+
it "renders bar button", ->
|
|
45
|
+
button = element.find("a")
|
|
46
|
+
|
|
47
|
+
expect(button.length).toBe(1)
|
|
48
|
+
expect(button.hasClass("btn")).toBeTruthy()
|
|
49
|
+
expect(button.hasClass("btn-danger")).toBeTruthy()
|
|
50
|
+
expect(button.text()).toContain("Delete")
|
|
51
|
+
|
|
52
|
+
it "ng-click", ->
|
|
53
|
+
spyOn($scope, 'bar')
|
|
54
|
+
|
|
55
|
+
button = element.find("button")
|
|
56
|
+
button.click()
|
|
57
|
+
|
|
58
|
+
expect($scope.bar).not.toHaveBeenCalled()
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
describe "filters", ->
|
|
2
|
+
beforeEach module("mb.filters")
|
|
3
|
+
|
|
4
|
+
describe "humanSize", ->
|
|
5
|
+
filter = null
|
|
6
|
+
|
|
7
|
+
beforeEach inject (humanSizeFilter) ->
|
|
8
|
+
filter = humanSizeFilter
|
|
9
|
+
|
|
10
|
+
it "formats bytes", ->
|
|
11
|
+
expect(filter(1)).toEqual("1 Bytes")
|
|
12
|
+
expect(filter(1000)).toEqual("1000 Bytes")
|
|
13
|
+
expect(filter(1023)).toEqual("1023 Bytes")
|
|
14
|
+
|
|
15
|
+
it "formats kilobytes", ->
|
|
16
|
+
expect(filter(1024)).toEqual("1 KB")
|
|
17
|
+
|
|
18
|
+
it "formats megabytes", ->
|
|
19
|
+
megabyte = 1024 * 1024
|
|
20
|
+
|
|
21
|
+
expect(filter(megabyte)).toEqual("1 MB")
|
|
22
|
+
expect(filter(250 * megabyte)).toEqual("250 MB")
|
|
23
|
+
|
|
24
|
+
it "formats gigabytes", ->
|
|
25
|
+
gigabyte = 1024 * 1024 * 1024
|
|
26
|
+
|
|
27
|
+
expect(filter(gigabyte)).toEqual("1 GB")
|
|
28
|
+
expect(filter(2.6 * gigabyte)).toEqual("3 GB")
|
|
29
|
+
|
|
30
|
+
describe "jsonDocument", ->
|
|
31
|
+
filter = null
|
|
32
|
+
|
|
33
|
+
beforeEach inject (jsonDocumentFilter) ->
|
|
34
|
+
filter = jsonDocumentFilter
|
|
35
|
+
|
|
36
|
+
it "can highlight strings", ->
|
|
37
|
+
o = { foo: "bar" }
|
|
38
|
+
|
|
39
|
+
expect(filter(o)).toContain('<span class="key">foo:</span>')
|
|
40
|
+
expect(filter(o)).toContain('<span class="string">"bar"</span>')
|
|
41
|
+
|
|
42
|
+
it "can highlight numbers", ->
|
|
43
|
+
o = { bar: 123.99 }
|
|
44
|
+
|
|
45
|
+
expect(filter(o)).toContain('<span class="key">bar:</span>')
|
|
46
|
+
expect(filter(o)).toContain('<span class="number">123.99</span>')
|
|
47
|
+
|
|
48
|
+
it "can highlight booleans", ->
|
|
49
|
+
o = { foo: false }
|
|
50
|
+
|
|
51
|
+
expect(filter(o)).toContain('<span class="key">foo:</span>')
|
|
52
|
+
expect(filter(o)).toContain('<span class="boolean">false</span>')
|
|
53
|
+
|
|
54
|
+
it "can highlight nulls", ->
|
|
55
|
+
o = { foo: null }
|
|
56
|
+
|
|
57
|
+
expect(filter(o)).toContain('<span class="key">foo:</span>')
|
|
58
|
+
expect(filter(o)).toContain('<span class="null">null</span>')
|
|
59
|
+
|
|
60
|
+
it "can format ObjectId", ->
|
|
61
|
+
o = {
|
|
62
|
+
_id: { $oid: "50bfc4b6dac5d5630800017a" },
|
|
63
|
+
foo: "something",
|
|
64
|
+
comapany_id: { $oid: "50bfc4b6dac5d56308000119" }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
expect(filter(o)).toContain('<span class="key">_id:</span>')
|
|
68
|
+
expect(filter(o)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d5630800017a"</span>)')
|
|
69
|
+
|
|
70
|
+
expect(filter(o)).toContain('<span class="key">comapany_id:</span>')
|
|
71
|
+
expect(filter(o)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d56308000119"</span>)')
|
|
72
|
+
|
|
73
|
+
# url helpers
|
|
74
|
+
|
|
75
|
+
describe "#collectionsPath", ->
|
|
76
|
+
filter = null
|
|
77
|
+
|
|
78
|
+
beforeEach inject (collectionsPathFilter) ->
|
|
79
|
+
filter = collectionsPathFilter
|
|
80
|
+
|
|
81
|
+
it "without parameters generates an url with placeholders", ->
|
|
82
|
+
expect(filter()).toEqual("/databases/:dbName/collections")
|
|
83
|
+
|
|
84
|
+
it "generates an url for the given database collections", ->
|
|
85
|
+
database = { name: "foo_bar" }
|
|
86
|
+
expect(filter(database)).toEqual("/databases/foo_bar/collections")
|
|
87
|
+
|
|
88
|
+
describe "#documentsPath", ->
|
|
89
|
+
filter = null
|
|
90
|
+
|
|
91
|
+
beforeEach inject (documentsPathFilter) ->
|
|
92
|
+
filter = documentsPathFilter
|
|
93
|
+
|
|
94
|
+
it "without parameters generates an url with placeholders", ->
|
|
95
|
+
expect(filter()).toEqual("/databases/:dbName/collections/:collectionName/documents")
|
|
96
|
+
|
|
97
|
+
it "generates na url for the given collection documents", ->
|
|
98
|
+
collection = { dbName: "foo", name: "bars" }
|
|
99
|
+
expect(filter(collection)).toEqual("/databases/foo/collections/bars/documents")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
describe "mb.dialogs", ->
|
|
2
|
+
beforeEach module("mb.dialogs")
|
|
3
|
+
|
|
4
|
+
describe "dialogsHandler", ->
|
|
5
|
+
beforeEach inject ($window) ->
|
|
6
|
+
$window.bootbox = "dummy bootbox"
|
|
7
|
+
|
|
8
|
+
it "by default is set to bootbox", inject (dialogsHandler) ->
|
|
9
|
+
expect(dialogsHandler).toEqual("dummy bootbox")
|
|
10
|
+
|
|
11
|
+
describe "confirmationDialog", ->
|
|
12
|
+
beforeEach module("mocks")
|
|
13
|
+
|
|
14
|
+
it "is defined", inject (confirmationDialog) ->
|
|
15
|
+
expect(confirmationDialog).toBeDefined()
|
|
16
|
+
|
|
17
|
+
it "calls the handler", inject (confirmationDialog, dialogsHandler) ->
|
|
18
|
+
# Given
|
|
19
|
+
spyOn(dialogsHandler, "confirm")
|
|
20
|
+
|
|
21
|
+
# When
|
|
22
|
+
confirmationDialog(message: "This is a test message")
|
|
23
|
+
|
|
24
|
+
# Then
|
|
25
|
+
expect(dialogsHandler.confirm).toHaveBeenCalledWith \
|
|
26
|
+
"This is a test message",
|
|
27
|
+
jasmine.any(Function)
|
|
28
|
+
|
|
29
|
+
describe "when the dialog was confirmed", ->
|
|
30
|
+
it "calls the given #onOk callback", inject (confirmationDialog, dialogsHandler) ->
|
|
31
|
+
# Given
|
|
32
|
+
onOk = jasmine.createSpy("#onOk callback")
|
|
33
|
+
confirmationDialog(onOk: onOk)
|
|
34
|
+
|
|
35
|
+
# When
|
|
36
|
+
dialogsHandler.confirmed()
|
|
37
|
+
|
|
38
|
+
# Then
|
|
39
|
+
expect(onOk).toHaveBeenCalled()
|
|
40
|
+
|
|
41
|
+
describe "when the dialog was disposed", ->
|
|
42
|
+
it "calls the given #onOk callback", inject (confirmationDialog, dialogsHandler) ->
|
|
43
|
+
# Given
|
|
44
|
+
onCancel= jasmine.createSpy("#onCancel callback")
|
|
45
|
+
confirmationDialog(onCancel: onCancel)
|
|
46
|
+
|
|
47
|
+
# When
|
|
48
|
+
dialogsHandler.disposed()
|
|
49
|
+
|
|
50
|
+
# Then
|
|
51
|
+
expect(onCancel).toHaveBeenCalled()
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
describe "mb.pager", ->
|
|
2
|
+
beforeEach module("mb.pager")
|
|
3
|
+
|
|
4
|
+
describe "pager service", ->
|
|
5
|
+
it "is defined", inject (pager) ->
|
|
6
|
+
expect(pager).toBeDefined()
|
|
7
|
+
|
|
8
|
+
it "can be instantiated", inject (pager) ->
|
|
9
|
+
p = pager(totalPages: 99, outerWindow: 0)
|
|
10
|
+
|
|
11
|
+
expect(p.page).toEqual(1)
|
|
12
|
+
expect(p.totalPages).toEqual(99)
|
|
13
|
+
expect(p.innerWindow).toEqual(4)
|
|
14
|
+
expect(p.outerWindow).toEqual(0)
|
|
15
|
+
|
|
16
|
+
describe "windowedPageNumbers", ->
|
|
17
|
+
|
|
18
|
+
it "calculates windowed visible links", inject (pager) ->
|
|
19
|
+
prepare = pager(page: 6, totalPages: 11, innerWindow: 1, outerWindow: 1)
|
|
20
|
+
expect(prepare.windowedPageNumbers()).toEqual [1, 2, null, 5, 6, 7, null, 10, 11]
|
|
21
|
+
|
|
22
|
+
it "eliminates small gaps", inject (pager) ->
|
|
23
|
+
prepare = pager(page: 6, totalPages: 11, innerWindow: 2, outerWindow: 1)
|
|
24
|
+
# pages 4 and 8 appear instead of the gap
|
|
25
|
+
expect(prepare.windowedPageNumbers()).toEqual [1..11]
|
|
26
|
+
|
|
27
|
+
it "supports having no windows at all", inject (pager) ->
|
|
28
|
+
prepare = pager(page: 4, totalPages: 7, innerWindow: 0, outerWindow: 0)
|
|
29
|
+
expect(prepare.windowedPageNumbers()).toEqual [1, null, 4, null, 7]
|
|
30
|
+
|
|
31
|
+
it "adjusts upper limit if lower is out of bounds", inject (pager) ->
|
|
32
|
+
prepare = pager(page: 1, totalPages: 10, innerWindow: 2, outerWindow: 1)
|
|
33
|
+
expect(prepare.windowedPageNumbers()).toEqual [1, 2, 3, 4, 5, null, 9, 10]
|
|
34
|
+
|
|
35
|
+
it "adjusts lower limit if upper is out of bounds", inject (pager) ->
|
|
36
|
+
prepare = pager(page: 10, totalPages: 10, innerWindow: 2, outerWindow: 1)
|
|
37
|
+
expect(prepare.windowedPageNumbers()).toEqual [1, 2, null, 6, 7, 8, 9, 10]
|
|
38
|
+
|
|
39
|
+
describe "pager controller", ->
|
|
40
|
+
$scope = null
|
|
41
|
+
|
|
42
|
+
beforeEach inject ($rootScope, $controller) ->
|
|
43
|
+
$scope = $rootScope.$new()
|
|
44
|
+
$controller("pager", $scope: $scope)
|
|
45
|
+
|
|
46
|
+
$scope.page = 2
|
|
47
|
+
$scope.totalPages = 10
|
|
48
|
+
|
|
49
|
+
describe "#setPage", ->
|
|
50
|
+
it "sets the current page", ->
|
|
51
|
+
$scope.setPage(3)
|
|
52
|
+
expect($scope.page).toBe(3)
|
|
53
|
+
|
|
54
|
+
describe "when the new page number is < 1", ->
|
|
55
|
+
it "sets to the first page", ->
|
|
56
|
+
for newPage in [1, 0, -1]
|
|
57
|
+
$scope.setPage(newPage)
|
|
58
|
+
expect($scope.page).toBe(1)
|
|
59
|
+
|
|
60
|
+
describe "when the new page is > totalPages", ->
|
|
61
|
+
it "sets to the last page", ->
|
|
62
|
+
for newPage in [10, 11, 12]
|
|
63
|
+
$scope.setPage(newPage)
|
|
64
|
+
expect($scope.page).toBe(10)
|
|
65
|
+
|
|
66
|
+
describe "#next", ->
|
|
67
|
+
it "sets to the next page", ->
|
|
68
|
+
$scope.page = 9
|
|
69
|
+
$scope.next()
|
|
70
|
+
expect($scope.page).toBe(10)
|
|
71
|
+
|
|
72
|
+
describe "when the current page is the last page", ->
|
|
73
|
+
it "sets does nothig", ->
|
|
74
|
+
$scope.page = 9
|
|
75
|
+
$scope.next()
|
|
76
|
+
expect($scope.page).toBe(10)
|
|
77
|
+
|
|
78
|
+
describe "#hasNext", ->
|
|
79
|
+
it "return true when there is a next page", ->
|
|
80
|
+
$scope.page = 9
|
|
81
|
+
expect($scope.hasNext()).toBeTruthy()
|
|
82
|
+
|
|
83
|
+
$scope.page = 10
|
|
84
|
+
expect($scope.hasNext()).toBeFalsy()
|
|
85
|
+
|
|
86
|
+
describe "#prev", ->
|
|
87
|
+
it "sets to the prev page", ->
|
|
88
|
+
$scope.page = 9
|
|
89
|
+
$scope.prev()
|
|
90
|
+
expect($scope.page).toBe(8)
|
|
91
|
+
|
|
92
|
+
describe "when the current page is the last first", ->
|
|
93
|
+
it "sets does nothig", ->
|
|
94
|
+
$scope.page = 1
|
|
95
|
+
$scope.prev()
|
|
96
|
+
expect($scope.page).toBe(1)
|
|
97
|
+
|
|
98
|
+
describe "#hasPrev", ->
|
|
99
|
+
it "return true when there is a previous page", ->
|
|
100
|
+
$scope.page = 9
|
|
101
|
+
expect($scope.hasPrev()).toBeTruthy()
|
|
102
|
+
|
|
103
|
+
$scope.page = 1
|
|
104
|
+
expect($scope.hasPrev()).toBeFalsy()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
describe "mb.tableFilter", ->
|
|
2
|
+
beforeEach module("mb.tableFilter")
|
|
3
|
+
|
|
4
|
+
describe "tableFilter controller", ->
|
|
5
|
+
$scope = null
|
|
6
|
+
|
|
7
|
+
beforeEach inject ($controller, $rootScope) ->
|
|
8
|
+
$scope = $rootScope.$new()
|
|
9
|
+
$controller("tableFilter", $scope: $scope)
|
|
10
|
+
|
|
11
|
+
describe "#isEmpty", ->
|
|
12
|
+
it "returns true when the value is empty", ->
|
|
13
|
+
for value in [null, undefined, ""]
|
|
14
|
+
$scope.value = value
|
|
15
|
+
expect($scope.isEmpty()).toBeTruthy()
|
|
16
|
+
|
|
17
|
+
it "returs false when the value is not empty", ->
|
|
18
|
+
$scope.value = "foo"
|
|
19
|
+
expect($scope.isEmpty()).toBeFalsy()
|
|
20
|
+
|
|
21
|
+
describe "#clear", ->
|
|
22
|
+
it "clears the filter value", ->
|
|
23
|
+
$scope.value = "foo"
|
|
24
|
+
$scope.clear()
|
|
25
|
+
|
|
26
|
+
expect($scope.value).toEqual("")
|
|
27
|
+
|
|
28
|
+
describe "tableFilter", ->
|
|
29
|
+
$scope = null
|
|
30
|
+
element = null
|
|
31
|
+
|
|
32
|
+
beforeEach module("app/assets/templates/table_filter.html")
|
|
33
|
+
|
|
34
|
+
beforeEach inject ($rootScope, $compile) ->
|
|
35
|
+
$scope = $rootScope
|
|
36
|
+
|
|
37
|
+
tpl = """
|
|
38
|
+
<div>
|
|
39
|
+
<table-filter value="filterValue" placeholder="Enter database name"></table-filter>
|
|
40
|
+
</div>
|
|
41
|
+
"""
|
|
42
|
+
element = $compile(tpl)($scope)
|
|
43
|
+
$scope.$digest()
|
|
44
|
+
|
|
45
|
+
it "sets the valid placeholder", ->
|
|
46
|
+
input = element.find("input[type='text']")
|
|
47
|
+
expect(input.attr('placeholder')).toEqual("Enter database name")
|
|
48
|
+
|
|
49
|
+
it "binds the filter value", ->
|
|
50
|
+
$scope.$apply -> $scope.filterValue = "Test filter value"
|
|
51
|
+
|
|
52
|
+
input = element.find("input[type='text']")
|
|
53
|
+
expect(input.val()).toEqual("Test filter value")
|
|
54
|
+
|
|
55
|
+
describe "the clear button", ->
|
|
56
|
+
button = null
|
|
57
|
+
|
|
58
|
+
beforeEach ->
|
|
59
|
+
button = element.find("button")
|
|
60
|
+
|
|
61
|
+
it "is initially disabled", ->
|
|
62
|
+
expect(button).toHaveCssClass("disabled")
|
|
63
|
+
|
|
64
|
+
describe "when value is not empty", ->
|
|
65
|
+
beforeEach ->
|
|
66
|
+
$scope.$apply -> $scope.filterValue = "some value"
|
|
67
|
+
|
|
68
|
+
it "is enabled", ->
|
|
69
|
+
expect(button).not.toHaveCssClass("disabled")
|
|
70
|
+
|
|
71
|
+
describe "when the value is empty", ->
|
|
72
|
+
beforeEach ->
|
|
73
|
+
$scope.$apply -> $scope.filterValue = ""
|
|
74
|
+
|
|
75
|
+
it "is disabled", ->
|
|
76
|
+
expect(button).toHaveCssClass("disabled")
|