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,83 @@
|
|
1
|
+
describe "services", ->
|
2
|
+
beforeEach module("mb.services")
|
3
|
+
|
4
|
+
describe "alerts", ->
|
5
|
+
it "is defined", inject (alerts) ->
|
6
|
+
expect(alerts).toBeDefined()
|
7
|
+
|
8
|
+
describe "#nextId", ->
|
9
|
+
it "return the next id for the new flash message", inject (alerts) ->
|
10
|
+
expect(alerts.nextId()).toEqual(1)
|
11
|
+
_(4).times -> alerts.nextId()
|
12
|
+
expect(alerts.nextId()).toEqual(6)
|
13
|
+
|
14
|
+
describe "#push", ->
|
15
|
+
beforeEach inject (alerts) ->
|
16
|
+
spyOn(alerts, "delayedDispose")
|
17
|
+
|
18
|
+
it "returns an id for the new flash message", inject (alerts) ->
|
19
|
+
expect(alerts.push("info", "Test..")).toEqual(1)
|
20
|
+
expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
|
21
|
+
|
22
|
+
expect(alerts.push("error", "Test error..")).toEqual(2)
|
23
|
+
expect(alerts.delayedDispose).toHaveBeenCalledWith(2)
|
24
|
+
|
25
|
+
describe "#info", ->
|
26
|
+
it "pushesh the given message", inject (alerts) ->
|
27
|
+
# Given
|
28
|
+
testMessage = "This is a test message!"
|
29
|
+
otherTestMessage = "This is a second test message!"
|
30
|
+
|
31
|
+
# When
|
32
|
+
alerts.info(testMessage)
|
33
|
+
expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
|
34
|
+
|
35
|
+
alerts.info(otherTestMessage)
|
36
|
+
expect(alerts.delayedDispose).toHaveBeenCalledWith(2)
|
37
|
+
|
38
|
+
# Then
|
39
|
+
expect(alerts.messages).toContain(id: 1, type: "info", text: testMessage)
|
40
|
+
expect(alerts.messages).toContain(id: 2, type: "info", text: otherTestMessage)
|
41
|
+
|
42
|
+
describe "#error", ->
|
43
|
+
it "pushesh the given message", inject (alerts) ->
|
44
|
+
# Given
|
45
|
+
testMessage = "This is a test message!"
|
46
|
+
|
47
|
+
# When
|
48
|
+
alerts.error(testMessage)
|
49
|
+
expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
|
50
|
+
|
51
|
+
# Then
|
52
|
+
expect(alerts.messages).toContain(id: 1, type: "error", text: testMessage)
|
53
|
+
|
54
|
+
describe "#dispose", ->
|
55
|
+
it "removes a message with the given id", inject (alerts) ->
|
56
|
+
# Given
|
57
|
+
alerts.info("First message")
|
58
|
+
alerts.info("Second message")
|
59
|
+
alerts.info("Third message")
|
60
|
+
alerts.error("Error message")
|
61
|
+
|
62
|
+
# When
|
63
|
+
alerts.dispose(2)
|
64
|
+
|
65
|
+
# Then
|
66
|
+
expect(alerts.messages).toContain(id: 1, type: "info", text: "First message")
|
67
|
+
expect(alerts.messages).not.toContain(id: 2, type: "info", text: "Second message")
|
68
|
+
expect(alerts.messages).toContain(id: 3, type: "info", text: "Third message")
|
69
|
+
expect(alerts.messages).toContain(id: 4, type: "error", text: "Error message")
|
70
|
+
|
71
|
+
describe "#delayedDispose", ->
|
72
|
+
it "removes a message after the given time", inject (alerts, $timeout) ->
|
73
|
+
# Given
|
74
|
+
alerts.info("First message")
|
75
|
+
|
76
|
+
# When
|
77
|
+
alerts.delayedDispose(1)
|
78
|
+
expect(alerts.messages).toContain(id: 1, type: "info", text: "First message")
|
79
|
+
|
80
|
+
$timeout.flush()
|
81
|
+
|
82
|
+
# Then
|
83
|
+
expect(alerts.messages).toEqual([])
|
@@ -0,0 +1,19 @@
|
|
1
|
+
basePath = "../../../";
|
2
|
+
|
3
|
+
files = [
|
4
|
+
ANGULAR_SCENARIO,
|
5
|
+
ANGULAR_SCENARIO_ADAPTER,
|
6
|
+
"spec/javascripts/helpers_e2e/**/*.js.coffee",
|
7
|
+
"spec/javascripts/e2e/**/*.js.coffee"
|
8
|
+
];
|
9
|
+
|
10
|
+
reporters = ["dots"];
|
11
|
+
browsers = ["PhantomJS"];
|
12
|
+
|
13
|
+
autoWatch = false;
|
14
|
+
singleRun = true;
|
15
|
+
|
16
|
+
urlRoot = '/__testacular/';
|
17
|
+
proxies = {
|
18
|
+
"/": "http://localhost:3001/"
|
19
|
+
};
|
@@ -0,0 +1,43 @@
|
|
1
|
+
basePath = "../../../";
|
2
|
+
|
3
|
+
files = [
|
4
|
+
JASMINE,
|
5
|
+
JASMINE_ADAPTER,
|
6
|
+
|
7
|
+
// Libraries
|
8
|
+
"vendor/assets/javascripts/jquery.js",
|
9
|
+
"vendor/assets/javascripts/angular/angular.js",
|
10
|
+
"vendor/assets/javascripts/angular/angular-resource.js",
|
11
|
+
"vendor/assets/javascripts/angular/angular-sanitize.js",
|
12
|
+
"vendor/assets/javascripts/angular/angular-bootstrap.js",
|
13
|
+
"vendor/assets/javascripts/*.js",
|
14
|
+
|
15
|
+
// The app
|
16
|
+
"app/assets/javascripts/app/controllers.js.coffee",
|
17
|
+
"app/assets/javascripts/app/**/*.js.coffee",
|
18
|
+
"app/assets/javascripts/application.js.coffee",
|
19
|
+
|
20
|
+
// Specs
|
21
|
+
"spec/javascripts/lib/angular-mocks.js",
|
22
|
+
|
23
|
+
"spec/javascripts/helpers/**/*.js.coffee",
|
24
|
+
"spec/javascripts/**/*_spec.js.coffee",
|
25
|
+
"spec/javascripts/**/*_spec.js.coffee",
|
26
|
+
|
27
|
+
// Templates
|
28
|
+
"app/assets/javascripts/templates/*.html.js"
|
29
|
+
];
|
30
|
+
|
31
|
+
preprocessors = {
|
32
|
+
"**/*.js.coffee": "coffee",
|
33
|
+
"**/*.html": "html2js"
|
34
|
+
};
|
35
|
+
|
36
|
+
// Test results reporter to use
|
37
|
+
// possible values: dots || progress
|
38
|
+
reporters = ["dots"];
|
39
|
+
|
40
|
+
browsers = ["PhantomJS"];
|
41
|
+
|
42
|
+
autoWatch = true;
|
43
|
+
singleRun = false;
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe "collections list page", ->
|
2
|
+
beforeEach ->
|
3
|
+
browser().navigateTo("/e2e/load_fixtures")
|
4
|
+
browser().navigateTo("/")
|
5
|
+
|
6
|
+
element("table.databases tbody tr a:contains('first_database')").click()
|
7
|
+
|
8
|
+
it "navigates to the valid url", ->
|
9
|
+
expect(browser().location().url()).toBe("/databases/first_database/collections")
|
10
|
+
|
11
|
+
it "displays a valid section title", ->
|
12
|
+
title = element("h2").text()
|
13
|
+
expect(title).toEqual("first_database collections")
|
14
|
+
|
15
|
+
it "displays available collections ordered by name", ->
|
16
|
+
expect(repeater("table.collections tbody tr").column("collection.name"))
|
17
|
+
.toEqual(["first_collection", "second_collection", "system.indexes", "third_collection"])
|
18
|
+
|
19
|
+
it "filters the collections list", ->
|
20
|
+
input("value").enter("")
|
21
|
+
expect(repeater("table.collections tbody tr").count()).toBe(4)
|
22
|
+
expect(repeater("table.collections tbody tr").column("collection.name"))
|
23
|
+
.toEqual(["first_collection", "second_collection", "system.indexes", "third_collection"])
|
24
|
+
|
25
|
+
input("value").enter("first")
|
26
|
+
expect(repeater("table.collections tbody tr").count()).toBe(1)
|
27
|
+
expect(repeater("table.collections tbody tr").column("collection.name"))
|
28
|
+
.toEqual(["first_collection"])
|
29
|
+
|
30
|
+
input("value").enter("second")
|
31
|
+
expect(repeater("table.collections tbody tr").count()).toBe(1)
|
32
|
+
expect(repeater("table.collections tbody tr").column("collection.name"))
|
33
|
+
.toEqual(["second_collection"])
|
34
|
+
|
35
|
+
input("value").enter("collection")
|
36
|
+
expect(repeater("table.collections tbody tr").count()).toBe(3)
|
37
|
+
expect(repeater("table.collections tbody tr").column("collection.name"))
|
38
|
+
.toEqual(["first_collection", "second_collection", "third_collection"])
|
39
|
+
|
40
|
+
input("value").enter("not existing")
|
41
|
+
expect(repeater("table.collections tbody tr").count()).toBe(0)
|
42
|
+
expect(element(".filter.alert:visible").text()).toMatch(/Nothing has been found./)
|
43
|
+
|
44
|
+
element("button:contains('Clear')").click()
|
45
|
+
expect(repeater("table.collections tbody tr").count()).toBe(4)
|
46
|
+
|
47
|
+
it "displays a tab with database stats", ->
|
48
|
+
element(".tabbable a:contains('Database stats')").click()
|
49
|
+
expect(repeater("table tbody tr").count()).toBeGreaterThan(0)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
describe "databases list page", ->
|
2
|
+
beforeEach ->
|
3
|
+
browser().navigateTo("/e2e/load_fixtures")
|
4
|
+
browser().navigateTo("/")
|
5
|
+
|
6
|
+
it "navigates to the valid url", ->
|
7
|
+
expect(browser().location().url()).toBe("/")
|
8
|
+
|
9
|
+
it "displays a valid section title", ->
|
10
|
+
title = element("h2").text()
|
11
|
+
expect(title).toEqual("localhost databases")
|
12
|
+
|
13
|
+
it "displays available databases ordered by name", ->
|
14
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
15
|
+
.toEqual(["first_database", "second_database", "third_database"])
|
16
|
+
|
17
|
+
describe "filtering by database name", ->
|
18
|
+
it "displays all databases when the filter is not provided", ->
|
19
|
+
input("value").enter("")
|
20
|
+
expect(repeater("table.databases tbody tr").count()).toBe(3)
|
21
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
22
|
+
.toEqual(["first_database", "second_database", "third_database"])
|
23
|
+
|
24
|
+
it "filters by database name", ->
|
25
|
+
input("value").enter("first")
|
26
|
+
expect(repeater("table.databases tbody tr").count()).toBe(1)
|
27
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
28
|
+
.toEqual(["first_database"])
|
29
|
+
|
30
|
+
input("value").enter("second")
|
31
|
+
expect(repeater("table.databases tbody tr").count()).toBe(1)
|
32
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
33
|
+
.toEqual(["second_database"])
|
34
|
+
|
35
|
+
input("value").enter("not existing")
|
36
|
+
expect(repeater("table.databases tbody tr").count()).toBe(0)
|
37
|
+
expect(element(".filter.alert:visible").text()).toMatch(/Nothing has been found./)
|
38
|
+
|
39
|
+
it "displays all records when the filter is cleared", ->
|
40
|
+
element("button:contains('Clear')").click()
|
41
|
+
expect(repeater("table.databases tbody tr").count()).toBe(3)
|
42
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
43
|
+
.toEqual(["first_database", "second_database", "third_database"])
|
44
|
+
|
45
|
+
describe "delete a database", ->
|
46
|
+
beforeEach ->
|
47
|
+
element("table.databases tbody tr:contains('third_database') td.actions a:contains('Delete')").click()
|
48
|
+
expect(element("div.modal .modal-body").text()).toContain("Deleting third_database. Are you sure?")
|
49
|
+
|
50
|
+
describe "when the dialog was disposed", ->
|
51
|
+
beforeEach ->
|
52
|
+
appElement "div.modal .modal-footer a:contains('Cancel')", ($element) ->
|
53
|
+
$element.click()
|
54
|
+
|
55
|
+
it "does nothig", ->
|
56
|
+
expect(repeater("table.databases tbody tr").count()).toBe(3)
|
57
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
58
|
+
.toEqual(["first_database", "second_database", "third_database"])
|
59
|
+
|
60
|
+
describe "when the dialog was confirmed", ->
|
61
|
+
beforeEach ->
|
62
|
+
appElement "div.bootbox a:contains('OK')", ($element) ->
|
63
|
+
$element.click()
|
64
|
+
|
65
|
+
# TODO figure out how to test it
|
66
|
+
xit "shows the alert", ->
|
67
|
+
expect(repeater("aside#alerts .alert").count()).toBe(1)
|
68
|
+
expect(repeater("aside#alerts .alert").column("message.text"))
|
69
|
+
.toContain("Database third_database has been deleted.")
|
70
|
+
|
71
|
+
it "deletes a database", ->
|
72
|
+
expect(repeater("table.databases tbody tr").count()).toBe(2)
|
73
|
+
expect(repeater("table.databases tbody tr").column("database.name"))
|
74
|
+
.toEqual(["first_database", "second_database"])
|
@@ -0,0 +1,18 @@
|
|
1
|
+
describe "documents list page", ->
|
2
|
+
beforeEach ->
|
3
|
+
browser().navigateTo("/e2e/load_fixtures")
|
4
|
+
browser().navigateTo("/")
|
5
|
+
|
6
|
+
element("table.databases tbody tr a:contains('first_database')").click()
|
7
|
+
element("table.collections tbody tr a:contains('first_collection')").click()
|
8
|
+
|
9
|
+
it "shows the documents page", ->
|
10
|
+
expect(browser().location().url())
|
11
|
+
.toBe("/databases/first_database/collections/first_collection/documents")
|
12
|
+
|
13
|
+
title = element("h2").text()
|
14
|
+
expect(title).toEqual("first_collection documents")
|
15
|
+
|
16
|
+
it "displays a tab with collection stats", ->
|
17
|
+
element(".tabbable a:contains('Collection stats')").click()
|
18
|
+
expect(repeater("table tbody tr").count()).toBeGreaterThan(0)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
describe "server info page", ->
|
2
|
+
beforeEach ->
|
3
|
+
browser().navigateTo("/")
|
4
|
+
element("a:contains('Server Info')").click()
|
5
|
+
|
6
|
+
it "displays details about the server", ->
|
7
|
+
expect(browser().location().url()).toBe("/server_info")
|
8
|
+
|
9
|
+
title = element("h2").text()
|
10
|
+
expect(title).toEqual("server info")
|
11
|
+
|
12
|
+
expect(repeater("table tbody tr").count()).toBeGreaterThan(0)
|