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,54 @@
|
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
2
|
+
"http://www.w3.org/TR/html4/loose.dtd">
|
|
3
|
+
<html>
|
|
4
|
+
<head>
|
|
5
|
+
<title>Jasmine Spec Runner</title>
|
|
6
|
+
<script type="text/javascript" src="/assets/vendor.js"></script>
|
|
7
|
+
|
|
8
|
+
<!-- Load libraries -->
|
|
9
|
+
<link rel="stylesheet" type="text/css" href="/_specs/lib/jasmine.css">
|
|
10
|
+
<script type="text/javascript" src="/_specs/lib/jasmine.js"></script>
|
|
11
|
+
<script type="text/javascript" src="/_specs/lib/jasmine-html.js"></script>
|
|
12
|
+
<script type="text/javascript" src="/_specs/lib/angular-mocks.js"></script>
|
|
13
|
+
|
|
14
|
+
<!-- Load application files -->
|
|
15
|
+
<script type="text/javascript" src="/assets/app.js"></script>
|
|
16
|
+
|
|
17
|
+
<!-- Load specs -->
|
|
18
|
+
<script type="text/javascript" src="/assets/templates.js"></script>
|
|
19
|
+
<script type="text/javascript" src="/_specs/spec.js"></script>
|
|
20
|
+
|
|
21
|
+
<script type="text/javascript">
|
|
22
|
+
(function () {
|
|
23
|
+
var jasmineEnv = jasmine.getEnv();
|
|
24
|
+
jasmineEnv.updateInterval = 1000;
|
|
25
|
+
|
|
26
|
+
var trivialReporter = new jasmine.TrivialReporter();
|
|
27
|
+
|
|
28
|
+
jasmineEnv.addReporter(trivialReporter);
|
|
29
|
+
|
|
30
|
+
jasmineEnv.specFilter = function (spec) {
|
|
31
|
+
return trivialReporter.specFilter(spec);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
var currentWindowOnload = window.onload;
|
|
35
|
+
|
|
36
|
+
window.onload = function () {
|
|
37
|
+
if (currentWindowOnload) {
|
|
38
|
+
currentWindowOnload();
|
|
39
|
+
}
|
|
40
|
+
execJasmine();
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function execJasmine() {
|
|
44
|
+
jasmineEnv.execute();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
})();
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
</head>
|
|
51
|
+
|
|
52
|
+
<body>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe MongoBrowser::Models::Collection do
|
|
4
|
+
let(:mongo_db_name) { "first_database" }
|
|
5
|
+
let(:mongo_collection_name) { "first_collection" }
|
|
6
|
+
|
|
7
|
+
let(:server) { MongoBrowser::Models::Server.current }
|
|
8
|
+
|
|
9
|
+
let(:mongo_collection) do
|
|
10
|
+
server.connection[mongo_db_name]
|
|
11
|
+
.collection(mongo_collection_name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
let(:collection) { described_class.new(mongo_collection) }
|
|
15
|
+
subject { collection }
|
|
16
|
+
|
|
17
|
+
it "is initialized with Mongo::Collection" do
|
|
18
|
+
collection.mongo_collection.should == mongo_collection
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
its(:db_name) { should == mongo_db_name }
|
|
22
|
+
its(:name) { should == mongo_collection_name }
|
|
23
|
+
its(:size) { should == 2 }
|
|
24
|
+
|
|
25
|
+
describe "#stats" do
|
|
26
|
+
let(:stats) { collection.stats }
|
|
27
|
+
|
|
28
|
+
it "returns stats for the collection" do
|
|
29
|
+
expect(stats).not_to be_nil
|
|
30
|
+
expect(stats).to be_an_instance_of(BSON::OrderedHash)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#drop!" do
|
|
35
|
+
let(:database) { server.database(mongo_db_name) }
|
|
36
|
+
|
|
37
|
+
it "drops the collection" do
|
|
38
|
+
collection.drop!
|
|
39
|
+
expect(database.collection_names).not_to include(database.name)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "#documents_with_pagination" do
|
|
44
|
+
it "returns a collection of documents"
|
|
45
|
+
|
|
46
|
+
it "returns a pager"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "#find" do
|
|
50
|
+
let(:document) { collection.find(id) }
|
|
51
|
+
|
|
52
|
+
context "when a document exists in the collection" do
|
|
53
|
+
let(:mongo_document) { mongo_collection.find.first }
|
|
54
|
+
let(:id) { mongo_document["_id"].to_s }
|
|
55
|
+
|
|
56
|
+
it "returns a documents with the given id" do
|
|
57
|
+
expect(document).not_to be_nil
|
|
58
|
+
expect(document).to be_an_instance_of(MongoBrowser::Models::Document)
|
|
59
|
+
expect(document.id.to_s).to eq(id)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "when the document does not exist" do
|
|
64
|
+
let(:id) { "50b908f9dac5d53509000010" }
|
|
65
|
+
|
|
66
|
+
it "returns nil" do
|
|
67
|
+
expect(document).to be_nil
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe "#remove!" do
|
|
73
|
+
let(:document) { MongoBrowser::Models::Document.new(mongo_collection.find.first) }
|
|
74
|
+
|
|
75
|
+
it "removes a document from the collection" do
|
|
76
|
+
expect(collection.remove!(document)).to be_true
|
|
77
|
+
expect(collection.find(document.id)).to be_nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe MongoBrowser::Models::Database do
|
|
4
|
+
let(:connection) { MongoBrowser::Models::Server.current.connection }
|
|
5
|
+
let(:mongo_db_name) { "first_database" }
|
|
6
|
+
let(:mongo_db) { connection[mongo_db_name] }
|
|
7
|
+
|
|
8
|
+
let(:database) { described_class.new(mongo_db) }
|
|
9
|
+
subject { database }
|
|
10
|
+
|
|
11
|
+
it "is initialized with Mongo::DB" do
|
|
12
|
+
database.mongo_db.should == mongo_db
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
its(:id) { should == mongo_db_name }
|
|
16
|
+
its(:name) { should == mongo_db_name }
|
|
17
|
+
|
|
18
|
+
its(:size) { should be_an_instance_of(Fixnum) }
|
|
19
|
+
|
|
20
|
+
describe "#collection_names" do
|
|
21
|
+
subject { database.collection_names }
|
|
22
|
+
|
|
23
|
+
it { should be_an_instance_of(Array) }
|
|
24
|
+
it { should have(4).items }
|
|
25
|
+
it { should include("system.indexes") }
|
|
26
|
+
it { should include("first_collection") }
|
|
27
|
+
it { should include("second_collection") }
|
|
28
|
+
it { should include("third_collection") }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe "#collections" do
|
|
32
|
+
let(:collections) { database.collections }
|
|
33
|
+
subject { collections }
|
|
34
|
+
|
|
35
|
+
it { should be_an_instance_of(Array) }
|
|
36
|
+
it { should have(4).items }
|
|
37
|
+
|
|
38
|
+
it "contains Collections" do
|
|
39
|
+
collections.each do |db|
|
|
40
|
+
expect(db).to be_an_instance_of(MongoBrowser::Models::Collection)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe "#count" do
|
|
46
|
+
it "returns a number of collections" do
|
|
47
|
+
expect(database.count).to eq(database.collections.count)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "#stats" do
|
|
52
|
+
it "returns stats for the database" do
|
|
53
|
+
stats = database.stats
|
|
54
|
+
|
|
55
|
+
expect(stats).not_to be_nil
|
|
56
|
+
expect(stats).to be_an_instance_of(BSON::OrderedHash)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "#drop!" do
|
|
61
|
+
it "drops the database" do
|
|
62
|
+
database.drop!
|
|
63
|
+
expect(connection.database_names).not_to include(database.name)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#collection" do
|
|
68
|
+
it "returns a collection with the given name" do
|
|
69
|
+
collection = database.collection("first_collection")
|
|
70
|
+
|
|
71
|
+
expect(collection).to be_an_instance_of(MongoBrowser::Models::Collection)
|
|
72
|
+
expect(collection.name).to eq("first_collection")
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe MongoBrowser::Models::Document do
|
|
4
|
+
let(:mongo_db_name) { "first_database" }
|
|
5
|
+
let(:mongo_collection_name) { "first_collection" }
|
|
6
|
+
|
|
7
|
+
let(:server) { MongoBrowser::Models::Server.current }
|
|
8
|
+
let(:mongo_collection) { server.connection[mongo_db_name].collection(mongo_collection_name) }
|
|
9
|
+
let(:mongo_document) { mongo_collection.find.first }
|
|
10
|
+
|
|
11
|
+
let(:document) { described_class.new(mongo_document) }
|
|
12
|
+
subject { document }
|
|
13
|
+
|
|
14
|
+
its(:id) { should_not be_nil }
|
|
15
|
+
its(:data) { should_not be_nil }
|
|
16
|
+
its(:data) { should_not be_an_instance_of(Hash) }
|
|
17
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe MongoBrowser::Models::Pager do
|
|
4
|
+
let(:current_page) { 1 }
|
|
5
|
+
let(:size) { 25 }
|
|
6
|
+
|
|
7
|
+
let(:pager) { described_class.new(current_page, size) }
|
|
8
|
+
subject { pager }
|
|
9
|
+
|
|
10
|
+
before { pager.stub(:per_page).and_return(25) }
|
|
11
|
+
|
|
12
|
+
describe "#current_page" do
|
|
13
|
+
subject { pager.current_page }
|
|
14
|
+
|
|
15
|
+
[-2, -1, 0, 1].each do |number|
|
|
16
|
+
context "when the given page number is #{number}" do
|
|
17
|
+
let(:current_page) { number }
|
|
18
|
+
|
|
19
|
+
it("return the first page") { should == 1 }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "when the given page number exceed the total pages number" do
|
|
24
|
+
let(:current_page) { 3 }
|
|
25
|
+
let(:size) { 30 }
|
|
26
|
+
|
|
27
|
+
it("returns the last page number") { should == 2 }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "otherwise" do
|
|
31
|
+
let(:current_page) { 2 }
|
|
32
|
+
let(:size) { 26 }
|
|
33
|
+
|
|
34
|
+
it("returns the current page") { should == current_page }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "#offset" do
|
|
39
|
+
subject { pager.offset }
|
|
40
|
+
|
|
41
|
+
context "when current_page eq 1" do
|
|
42
|
+
it { should == 0 }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "otherwise" do
|
|
46
|
+
let(:current_page) { 2 }
|
|
47
|
+
let(:size) { 26 }
|
|
48
|
+
|
|
49
|
+
it("return a valid offset") { should == 25 }
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#total_pages" do
|
|
54
|
+
subject { pager.total_pages }
|
|
55
|
+
|
|
56
|
+
{ 1 => 1, 25 => 1, 26 => 2, 50 => 2, 51 => 3, 101 => 5 }.each do |size, expected|
|
|
57
|
+
context "when the size is #{size}" do
|
|
58
|
+
let(:size) { size }
|
|
59
|
+
|
|
60
|
+
it { should == expected }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe MongoBrowser::Models::Server do
|
|
4
|
+
describe ".current" do
|
|
5
|
+
it "instantiates an instance for the current (localhost) server" do
|
|
6
|
+
server = described_class.current
|
|
7
|
+
expect(server).to be_an_instance_of(described_class)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:server) { described_class.new(MongoBrowser.mongodb_host, MongoBrowser.mongodb_port) }
|
|
12
|
+
subject { server }
|
|
13
|
+
|
|
14
|
+
its(:host) { should == MongoBrowser.mongodb_host }
|
|
15
|
+
its(:port) { should == MongoBrowser.mongodb_port }
|
|
16
|
+
|
|
17
|
+
describe "#connection" do
|
|
18
|
+
it "returns a connection to the database" do
|
|
19
|
+
connection = server.connection
|
|
20
|
+
expect(connection).to be_an_instance_of(Mongo::Connection)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#database_names" do
|
|
25
|
+
subject { server.database_names }
|
|
26
|
+
|
|
27
|
+
it { should be_an_instance_of(Array) }
|
|
28
|
+
it { should include("first_database") }
|
|
29
|
+
it { should include("second_database") }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#databases" do
|
|
33
|
+
let(:databases) { server.databases }
|
|
34
|
+
subject { databases }
|
|
35
|
+
|
|
36
|
+
it { should be_an_instance_of(Array) }
|
|
37
|
+
|
|
38
|
+
it "contains Databases" do
|
|
39
|
+
databases.each do |db|
|
|
40
|
+
expect(db).to be_an_instance_of(MongoBrowser::Models::Database)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "first database" do
|
|
45
|
+
subject { databases.find { |db| db.name == "first_database" } }
|
|
46
|
+
|
|
47
|
+
it { should be_an_instance_of(MongoBrowser::Models::Database) }
|
|
48
|
+
its(:name) { should == "first_database" }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "second database" do
|
|
52
|
+
subject { databases.find { |db| db.name == "second_database" } }
|
|
53
|
+
|
|
54
|
+
it { should be_an_instance_of(MongoBrowser::Models::Database) }
|
|
55
|
+
its(:name) { should == "second_database" }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe "#database" do
|
|
59
|
+
let(:database) { server.database("first_database") }
|
|
60
|
+
|
|
61
|
+
it "returns a database with the given name" do
|
|
62
|
+
expect(database).to be_an_instance_of(MongoBrowser::Models::Database)
|
|
63
|
+
expect(database.name).to eq("first_database")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "#info" do
|
|
68
|
+
let(:info) { server.info }
|
|
69
|
+
|
|
70
|
+
it "returns an information about the current connection" do
|
|
71
|
+
expect(info).not_to be_nil
|
|
72
|
+
expect(info).to be_an_instance_of(BSON::OrderedHash)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -4,15 +4,6 @@ require "mongo_browser"
|
|
|
4
4
|
|
|
5
5
|
require "debugger"
|
|
6
6
|
require "rspec"
|
|
7
|
-
require "capybara"
|
|
8
|
-
require "capybara/rspec"
|
|
9
|
-
require "socket"
|
|
10
|
-
|
|
11
|
-
require "capybara/webkit"
|
|
12
|
-
Capybara.javascript_driver = :webkit
|
|
13
|
-
|
|
14
|
-
Capybara.ignore_hidden_elements = true
|
|
15
|
-
Capybara.app = MongoBrowser::Application
|
|
16
7
|
|
|
17
8
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
18
9
|
# from spec/support/ and its subdirectories.
|
|
@@ -25,22 +16,14 @@ RSpec.configure do |config|
|
|
|
25
16
|
config.include FeatureExampleGroup, type: :request
|
|
26
17
|
|
|
27
18
|
# Run test mongod instance and load database fixtures
|
|
28
|
-
config.before
|
|
19
|
+
config.before do
|
|
29
20
|
test_server.start! do |port|
|
|
30
|
-
MongoBrowser.mongodb_host = "
|
|
21
|
+
MongoBrowser.mongodb_host = "127.0.0.1"
|
|
31
22
|
MongoBrowser.mongodb_port = port
|
|
32
23
|
end
|
|
33
24
|
|
|
34
25
|
fixtures.load!
|
|
35
26
|
end
|
|
36
|
-
|
|
37
|
-
# Take a screenshot and html dump when the scenario has failed
|
|
38
|
-
config.after type: :request do
|
|
39
|
-
if example.exception
|
|
40
|
-
file_name = example.full_description.downcase.gsub(/\s/, "-")
|
|
41
|
-
capture_page(file_name)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
27
|
end
|
|
45
28
|
|
|
46
29
|
at_exit do
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
module FeatureExampleGroup
|
|
2
2
|
|
|
3
3
|
def fill_in_filter(value)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
JS
|
|
4
|
+
filter_input = find(%Q{form.filter input[type="text"]})
|
|
5
|
+
filter_input.set(value)
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
def confirm_dialog(message = 'Are you sure?')
|
|
@@ -17,6 +16,12 @@ module FeatureExampleGroup
|
|
|
17
16
|
page.should have_content(message)
|
|
18
17
|
click_link "OK"
|
|
19
18
|
end
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
wait_until { page.has_no_css?("div.bootbox.modal") }
|
|
22
|
+
rescue Capybara::TimeoutError
|
|
23
|
+
raise "Expected confirmation modal to be disposed."
|
|
24
|
+
end
|
|
20
25
|
end
|
|
21
26
|
|
|
22
27
|
def should_hide_the_table_and_display_a_notification
|
data/spec/support/fixtures.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "singleton"
|
|
2
|
+
|
|
1
3
|
class Fixtures
|
|
2
4
|
include Singleton
|
|
3
5
|
|
|
@@ -5,7 +7,6 @@ class Fixtures
|
|
|
5
7
|
def load!
|
|
6
8
|
cleanup!
|
|
7
9
|
|
|
8
|
-
data = JSON.parse(File.open(File.expand_path("spec/support/fixtures/databases.json"), "r").read)
|
|
9
10
|
data.each do |database_data|
|
|
10
11
|
database = connection.db(database_data["name"])
|
|
11
12
|
|
|
@@ -21,14 +22,30 @@ class Fixtures
|
|
|
21
22
|
|
|
22
23
|
# Delete all databases
|
|
23
24
|
def cleanup!
|
|
24
|
-
|
|
25
|
+
fixture_databases = data.map { |db| db["name"] }
|
|
26
|
+
|
|
27
|
+
# Drop all databases outside fixtures
|
|
28
|
+
other_databases = connection.database_names - fixture_databases
|
|
29
|
+
other_databases.each do |db_name|
|
|
25
30
|
connection.drop_database(db_name)
|
|
26
31
|
end
|
|
32
|
+
|
|
33
|
+
# Drop collections inside databases
|
|
34
|
+
fixture_databases.each do |db_name|
|
|
35
|
+
collection_names = connection[db_name].collection_names - ["system.indexes"]
|
|
36
|
+
collection_names.each do |collection_name|
|
|
37
|
+
connection[db_name][collection_name].drop
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def data
|
|
43
|
+
JSON.parse(File.open(File.expand_path("spec/support/fixtures/databases.json"), "r").read)
|
|
27
44
|
end
|
|
28
45
|
|
|
29
46
|
def connection
|
|
30
47
|
@connection ||= begin
|
|
31
|
-
Mongo::Connection.new(MongoBrowser::
|
|
48
|
+
Mongo::Connection.new(MongoBrowser::DEFAULT_MONGODB_HOST, MongoBrowser.mongodb_port)
|
|
32
49
|
end
|
|
33
50
|
end
|
|
34
51
|
end
|
data/spec/support/mongod.rb
CHANGED
|
@@ -1,38 +1,44 @@
|
|
|
1
|
+
require "singleton"
|
|
2
|
+
|
|
3
|
+
# Utility for run and manage test mongod instance.
|
|
1
4
|
class Mongod
|
|
2
5
|
include Singleton
|
|
3
6
|
|
|
4
7
|
MONGODB_DBPATH = "/tmp/mongo_browser/db"
|
|
8
|
+
# port for test mongod instance
|
|
9
|
+
MONGODB_PORT = 27018
|
|
5
10
|
|
|
6
|
-
attr_reader :port
|
|
7
11
|
attr_reader :pid
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
# Start test mongod instance
|
|
14
|
+
# * it cleans up the test server directory
|
|
15
|
+
# * starts a daemon
|
|
16
|
+
# * and wait until its fully responsive
|
|
13
17
|
def start!
|
|
14
18
|
return if running?
|
|
15
19
|
|
|
20
|
+
FileUtils.rm_rf(MONGODB_DBPATH) if Dir.exist?(MONGODB_DBPATH)
|
|
16
21
|
FileUtils.mkdir_p(MONGODB_DBPATH)
|
|
17
22
|
|
|
18
|
-
@pid = Mongod.start
|
|
23
|
+
@pid = Mongod.start
|
|
19
24
|
wait_until_responsive
|
|
20
25
|
|
|
21
|
-
yield
|
|
26
|
+
yield MONGODB_PORT if block_given?
|
|
22
27
|
end
|
|
23
28
|
|
|
29
|
+
# Kills test mongod instance
|
|
24
30
|
def shutdown!
|
|
31
|
+
puts "shutdown! test mongod instance"
|
|
25
32
|
return unless running?
|
|
26
33
|
|
|
27
34
|
Process.kill('HUP', pid)
|
|
28
|
-
FileUtils.rm_rf(MONGODB_DBPATH)
|
|
29
35
|
|
|
30
36
|
@pid = nil
|
|
31
37
|
end
|
|
32
38
|
|
|
33
39
|
# Returns true is mongodb server is ready to use
|
|
34
40
|
def responsive?
|
|
35
|
-
Mongo::Connection.new(MongoBrowser::
|
|
41
|
+
Mongo::Connection.new(MongoBrowser::DEFAULT_MONGODB_HOST, MONGODB_PORT)
|
|
36
42
|
true
|
|
37
43
|
rescue Mongo::ConnectionFailure
|
|
38
44
|
false
|
|
@@ -44,19 +50,29 @@ class Mongod
|
|
|
44
50
|
|
|
45
51
|
private
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
class << self
|
|
54
|
+
|
|
55
|
+
# Check whether port for test mongod is available,
|
|
56
|
+
def test_port_available?
|
|
57
|
+
begin
|
|
58
|
+
server = TCPServer.new(MongoBrowser::DEFAULT_MONGODB_HOST, MONGODB_PORT)
|
|
59
|
+
true
|
|
60
|
+
rescue
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
ensure
|
|
64
|
+
server.close if server
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Starts a core MongoDB test daemon.
|
|
68
|
+
def start
|
|
69
|
+
raise "port #{MONGODB_PORT} is not available" unless test_port_available?
|
|
53
70
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
command = "mongod --port #{port} --dbpath #{MONGODB_DBPATH} --nojournal"
|
|
57
|
-
log_file = File.open(File.expand_path("log/test_mongod.log"), "w")
|
|
71
|
+
command = "mongod --config #{File.expand_path("spec/support/mongodb.conf")}"
|
|
72
|
+
log_file = File.open(File.expand_path("log/test_mongod.log"), "w")
|
|
58
73
|
|
|
59
|
-
|
|
74
|
+
Process.spawn(command, out: log_file)
|
|
75
|
+
end
|
|
60
76
|
end
|
|
61
77
|
|
|
62
78
|
# Uses exponential back-off technique for waiting for the mongodb server
|
|
@@ -66,7 +82,7 @@ class Mongod
|
|
|
66
82
|
timeout = 10
|
|
67
83
|
|
|
68
84
|
until responsive?
|
|
69
|
-
raise "Could not start mongod" if Time.now - start_time >= timeout
|
|
85
|
+
raise "Could not start mongod after #{timeout} seconds" if Time.now - start_time >= timeout
|
|
70
86
|
|
|
71
87
|
sleep wait_time
|
|
72
88
|
wait_time *= 2
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# mongodb.conf
|
|
2
|
+
|
|
3
|
+
# Where to store the data.
|
|
4
|
+
|
|
5
|
+
# Note: if you run mongodb as a non-root user (recommended) you may
|
|
6
|
+
# need to create and set permissions for this directory manually,
|
|
7
|
+
# e.g., if the parent directory isn't mutable by the mongodb user.
|
|
8
|
+
dbpath=/tmp/mongo_browser/db
|
|
9
|
+
|
|
10
|
+
#where to log
|
|
11
|
+
logpath=/tmp/mongo_browser/db.log
|
|
12
|
+
|
|
13
|
+
logappend=true
|
|
14
|
+
|
|
15
|
+
port = 27018
|
|
16
|
+
|
|
17
|
+
# Disables write-ahead journaling
|
|
18
|
+
nojournal = true
|
|
19
|
+
|
|
20
|
+
# Turn on/off security. Off is currently the default
|
|
21
|
+
noauth = true
|
|
22
|
+
auth = true
|
|
23
|
+
|
|
24
|
+
# Verbose logging output.
|
|
25
|
+
verbose = true
|
|
26
|
+
|
|
27
|
+
# Inspect all client data for validity on receipt (useful for
|
|
28
|
+
# developing drivers)
|
|
29
|
+
objcheck = true
|
|
30
|
+
|
|
31
|
+
# Set oplogging level where n is
|
|
32
|
+
# 0=off (default)
|
|
33
|
+
# 1=W
|
|
34
|
+
# 2=R
|
|
35
|
+
# 3=both
|
|
36
|
+
# 7=W+some reads
|
|
37
|
+
diaglog = 3
|
|
38
|
+
|
|
39
|
+
# Disable the HTTP interface (Defaults to localhost:28017).
|
|
40
|
+
nohttpinterface = true
|
|
41
|
+
|
|
42
|
+
# Turns off server-side scripting. This will result in greatly limited
|
|
43
|
+
# functionality
|
|
44
|
+
noscripting = true
|
|
45
|
+
|
|
46
|
+
# Disable data file preallocation.
|
|
47
|
+
#noprealloc = true
|