mongo_browser 0.1.3 → 0.2.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- 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")
|