mongo_browser 0.2.0.rc2 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/.gitignore +3 -1
  2. data/.rspec +1 -1
  3. data/.travis.yml +6 -1
  4. data/CHANGELOG.md +15 -0
  5. data/{grunt.js → Gruntfile.js} +10 -8
  6. data/Procfile +1 -0
  7. data/README.md +44 -2
  8. data/Rakefile +1 -12
  9. data/app/assets/images/ajax-loader.gif +0 -0
  10. data/app/assets/javascripts/app/controllers/{breadcrumbs.js.coffee → breadcrumbs_controller.js.coffee} +4 -7
  11. data/app/assets/javascripts/app/controllers/collections/index_controller.js.coffee +38 -0
  12. data/app/assets/javascripts/app/controllers/collections/stats_controller.js.coffee +17 -0
  13. data/app/assets/javascripts/app/controllers/{databases.js.coffee → databases/index_controller.js.coffee} +11 -15
  14. data/app/assets/javascripts/app/controllers/databases/stats_controller.js.coffee +15 -0
  15. data/app/assets/javascripts/app/controllers/documents/index_controller.js.coffee +54 -0
  16. data/app/assets/javascripts/app/controllers/documents/show_controller.js.coffee +38 -0
  17. data/app/assets/javascripts/app/controllers/main_controller.js.coffee +15 -0
  18. data/app/assets/javascripts/app/controllers/servers/show_controller.js.coffee +17 -0
  19. data/app/assets/javascripts/app/directives.js.coffee +23 -0
  20. data/app/assets/javascripts/app/filters.js.coffee +14 -1
  21. data/app/assets/javascripts/app/modules/alerts.js.coffee +58 -0
  22. data/app/assets/javascripts/app/modules/pager.js.coffee +2 -2
  23. data/app/assets/javascripts/app/modules/spinner.js.coffee +29 -0
  24. data/app/assets/javascripts/app/modules/table_filter.js.coffee +4 -4
  25. data/app/assets/javascripts/app/resources.js.coffee +14 -8
  26. data/app/assets/javascripts/app/services.js.coffee +11 -33
  27. data/app/assets/javascripts/application.js.coffee +62 -34
  28. data/app/assets/javascripts/application.test.js.coffee +5 -0
  29. data/app/assets/javascripts/compiled_templates.js.coffee +1 -0
  30. data/app/assets/javascripts/vendor.js.coffee +0 -1
  31. data/app/assets/stylesheets/application.css.scss +36 -18
  32. data/{public/index.html → app/views/index.erb} +8 -8
  33. data/bin/mongo_browser +2 -13
  34. data/config.ru +3 -1
  35. data/lib/mongo_browser.rb +1 -0
  36. data/lib/mongo_browser/api.rb +11 -0
  37. data/lib/mongo_browser/api/collections.rb +34 -0
  38. data/lib/mongo_browser/api/databases.rb +32 -0
  39. data/lib/mongo_browser/api/documents.rb +37 -0
  40. data/lib/mongo_browser/api/mongo.rb +41 -0
  41. data/lib/mongo_browser/application.rb +8 -174
  42. data/lib/mongo_browser/application/development.rb +32 -0
  43. data/lib/mongo_browser/cli.rb +48 -0
  44. data/lib/mongo_browser/entities.rb +43 -0
  45. data/lib/mongo_browser/models/collection.rb +7 -12
  46. data/lib/mongo_browser/models/document.rb +5 -1
  47. data/lib/mongo_browser/models/pager.rb +22 -9
  48. data/lib/mongo_browser/version.rb +1 -1
  49. data/mongo_browser.gemspec +22 -15
  50. data/package.json +30 -0
  51. data/public/ng/templates/alerts.html +6 -0
  52. data/public/ng/templates/collections/index.html +39 -0
  53. data/public/ng/templates/collections/stats.html +18 -0
  54. data/public/ng/templates/databases/index.html +35 -0
  55. data/public/ng/templates/databases/stats.html +18 -0
  56. data/public/ng/templates/documents/index.html +40 -0
  57. data/public/ng/templates/documents/show.html +17 -0
  58. data/{app/assets → public/ng}/templates/pager.html +0 -0
  59. data/{app/assets/templates/server_info.html → public/ng/templates/server/show.html} +1 -1
  60. data/{app/assets → public/ng}/templates/table_filter.html +0 -0
  61. data/script/ci_all +5 -1
  62. data/script/ci_e2e +5 -2
  63. data/script/ci_javascripts +1 -1
  64. data/script/ci_rspec +1 -1
  65. data/spec/javascripts/app/controllers/{breadcrumbs_spec.js.coffee → breadcrumbs_controller_spec.js.coffee} +1 -1
  66. data/spec/javascripts/app/controllers/collections/index_controller_spec.js.coffee +95 -0
  67. data/spec/javascripts/app/controllers/collections/stats_controller_spec.js.coffee +34 -0
  68. data/spec/javascripts/app/controllers/databases/index_controller_spec.js.coffee +93 -0
  69. data/spec/javascripts/app/controllers/databases/stats_controller_spec.js.coffee +30 -0
  70. data/spec/javascripts/app/controllers/documents/index_controller_spec.js.coffee +108 -0
  71. data/spec/javascripts/app/controllers/documents/show_controller_spec.js.coffee +94 -0
  72. data/spec/javascripts/app/controllers/{main_spec.js.coffee → main_controller_spec.js.coffee} +2 -2
  73. data/spec/javascripts/app/controllers/{server_info_spec.js.coffee → server/show_controller_spec.js.coffee} +5 -6
  74. data/spec/javascripts/app/directives_spec.js.coffee +108 -24
  75. data/spec/javascripts/app/filters_spec.js.coffee +31 -5
  76. data/spec/javascripts/app/modules/alerts_spec.js.coffee +138 -0
  77. data/spec/javascripts/app/modules/dialogs_spec.js.coffee +1 -2
  78. data/spec/javascripts/app/modules/pager_spec.js.coffee +0 -1
  79. data/spec/javascripts/app/modules/spinner_spec.js.coffee +65 -0
  80. data/spec/javascripts/app/modules/table_filter_spec.js.coffee +9 -9
  81. data/spec/javascripts/app/resources_spec.js.coffee +99 -0
  82. data/spec/javascripts/app/services_spec.js.coffee +31 -71
  83. data/spec/javascripts/config/{testacular-e2e.conf.js → karma-e2e.conf.js} +1 -1
  84. data/spec/javascripts/config/{testacular.conf.js → karma.conf.js} +2 -3
  85. data/spec/javascripts/e2e/collection_stats_scenario.js.coffee +12 -0
  86. data/spec/javascripts/e2e/collections_scenario.js.coffee +59 -20
  87. data/spec/javascripts/e2e/database_stats_scenario.js.coffee +11 -0
  88. data/spec/javascripts/e2e/databases_scenario.js.coffee +37 -36
  89. data/spec/javascripts/e2e/document_show_scenario.js.coffee +31 -0
  90. data/spec/javascripts/e2e/documents_pagination_scenario.js.coffee +33 -0
  91. data/spec/javascripts/e2e/documents_scenario.js.coffee +43 -4
  92. data/spec/javascripts/e2e/server_info_scenario.js.coffee +8 -2
  93. data/spec/javascripts/helpers/mocks.js.coffee +2 -0
  94. data/spec/javascripts/helpers_e2e/dsl.js.coffee +20 -0
  95. data/spec/javascripts/lib/angular-mocks.js +64 -16
  96. data/spec/javascripts/lib/angular-scenario.js +724 -561
  97. data/spec/javascripts/runner.html +5 -5
  98. data/spec/lib/api/collections_spec.rb +62 -0
  99. data/spec/lib/api/databases_spec.rb +58 -0
  100. data/spec/lib/api/documents_spec.rb +135 -0
  101. data/spec/lib/api/mongo_spec.rb +27 -0
  102. data/spec/lib/cli_spec.rb +19 -0
  103. data/spec/lib/entities_spec.rb +39 -0
  104. data/spec/lib/models/collection_spec.rb +16 -10
  105. data/spec/lib/models/database_spec.rb +4 -4
  106. data/spec/lib/models/document_spec.rb +5 -5
  107. data/spec/lib/models/pager_spec.rb +20 -11
  108. data/spec/spec_helper.rb +7 -15
  109. data/spec/support/api_example_group.rb +45 -0
  110. data/spec/support/fixtures.rb +10 -6
  111. data/spec/support/matchers/expose.rb +18 -0
  112. data/vendor/assets/javascripts/angular/angular-bootstrap.js +1 -1
  113. data/vendor/assets/javascripts/angular/angular-resource.js +78 -56
  114. data/vendor/assets/javascripts/angular/angular-sanitize.js +3 -1
  115. data/vendor/assets/javascripts/angular/angular.js +720 -404
  116. metadata +323 -183
  117. data/app/assets/javascripts/app.js.coffee +0 -8
  118. data/app/assets/javascripts/app/controllers.js.coffee +0 -2
  119. data/app/assets/javascripts/app/controllers/alerts.js.coffee +0 -12
  120. data/app/assets/javascripts/app/controllers/collections.js.coffee +0 -40
  121. data/app/assets/javascripts/app/controllers/documents.js.coffee +0 -49
  122. data/app/assets/javascripts/app/controllers/main.js.coffee +0 -10
  123. data/app/assets/javascripts/app/controllers/server_info.js.coffee +0 -14
  124. data/app/assets/javascripts/templates.js.coffee +0 -1
  125. data/app/assets/javascripts/templates/.gitkeep +0 -0
  126. data/app/assets/templates/collections.html +0 -53
  127. data/app/assets/templates/databases.html +0 -32
  128. data/app/assets/templates/documents.html +0 -45
  129. data/config-e2e.ru +0 -20
  130. data/spec/features/collections_list_spec.rb +0 -64
  131. data/spec/features/documents_list_spec.rb +0 -139
  132. data/spec/features/server_info_spec.rb +0 -23
  133. data/spec/javascripts/app/controllers/alerts_spec.js.coffee +0 -36
  134. data/spec/javascripts/app/controllers/collections_spec.js.coffee +0 -78
  135. data/spec/javascripts/app/controllers/databases_spec.js.coffee +0 -55
  136. data/spec/javascripts/app/controllers/documents_spec.js.coffee +0 -62
  137. data/spec/javascripts/helpers_e2e/app_element.js.coffee +0 -6
  138. data/spec/support/feature_example_group.rb +0 -53
  139. data/spec/support/matchers/have_flash_message.rb +0 -16
  140. data/spec/support/mongod.rb +0 -91
  141. data/spec/support/mongodb.conf +0 -47
@@ -0,0 +1,94 @@
1
+ describe "documents show controller", ->
2
+ beforeEach module("mb")
3
+ beforeEach module("mocks")
4
+
5
+ controller = null
6
+ $scope = null
7
+
8
+ $httpBackend = 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
+ $routeParams.id = "document_id"
17
+
18
+ $httpBackend = $injector.get("$httpBackend")
19
+ $httpBackend.whenGET("/api/databases/test_database/collections/test_collection/documents/document_id")
20
+ .respond(dbName: "test_database", collectionName: "test_collection", id: "document_id")
21
+
22
+ $scope = $rootScope.$new()
23
+ controller = $controller "documents.show",
24
+ $scope: $scope
25
+
26
+ $scope.$digest()
27
+ $httpBackend.flush()
28
+
29
+ afterEach ->
30
+ $httpBackend.verifyNoOutstandingExpectation()
31
+ $httpBackend.verifyNoOutstandingRequest()
32
+
33
+ describe "$scope", ->
34
+ it "assigns variables from $routeParams", ->
35
+ expect($scope.dbName).toEqual("test_database")
36
+ expect($scope.collectionName).toEqual("test_collection")
37
+
38
+ # TODO create a macro / shared examples
39
+ describe "$scope.isLoading", ->
40
+ it "returns true when the resouce it loading", ->
41
+ controller.loading = true
42
+ expect($scope.isLoading()).toBeTruthy()
43
+
44
+ it "otherwise returns false", ->
45
+ controller.loading = false
46
+ expect($scope.isLoading()).toBeFalsy()
47
+
48
+ describe "$scope.refresh", ->
49
+ alerts = null
50
+
51
+ beforeEach inject ($injector) ->
52
+ alerts = $injector.get("alerts")
53
+
54
+ it "displays a flash message", ->
55
+ # Given
56
+ spyOn(alerts, "info")
57
+
58
+ # When
59
+ $scope.refresh()
60
+ $httpBackend.flush()
61
+
62
+ # Then
63
+ expect(alerts.info).toHaveBeenCalledWith("Document was refreshed")
64
+
65
+ it "fetches a document from the database", ->
66
+ # Given
67
+ $httpBackend.whenGET("/api/databases/test_database/collections/test_collection/documents/document_id")
68
+ .respond({})
69
+
70
+ # When
71
+ $scope.refresh()
72
+ $httpBackend.flush()
73
+
74
+ # Then
75
+ $httpBackend.verifyNoOutstandingExpectation()
76
+ $httpBackend.verifyNoOutstandingRequest()
77
+
78
+ describe "controller", ->
79
+ describe "controller.handleNotFoundDocument", ->
80
+ $location = null
81
+
82
+ beforeEach inject ($injector) ->
83
+ $location = $injector.get("$location")
84
+ spyOn($location, "path")
85
+
86
+ describe "when the response status is 404", ->
87
+ it "redirects to the documents list page", ->
88
+ controller.handleNotFoundDocument(status: 404)
89
+ expect($location.path).toHaveBeenCalledWith("/databases/test_database/collections/test_collection/documents")
90
+
91
+ describe "when the rsponse status is not 404", ->
92
+ it "should not redirect", ->
93
+ controller.handleNotFoundDocument(status: 500)
94
+ expect($location.path).not.toHaveBeenCalled()
@@ -1,5 +1,5 @@
1
1
  describe "main", ->
2
- beforeEach module("mb.controllers")
2
+ beforeEach module("mb")
3
3
 
4
4
  $scope = null
5
5
  $httpBackend = null
@@ -8,7 +8,7 @@ describe "main", ->
8
8
  $scope = $rootScope.$new()
9
9
 
10
10
  $httpBackend = $injector.get('$httpBackend')
11
- $httpBackend.when("GET", "/api/version.json").respond([])
11
+ $httpBackend.whenGET("/api/version").respond([])
12
12
 
13
13
  $controller "main",
14
14
  $scope: $scope
@@ -1,6 +1,5 @@
1
- describe "serverInfo", ->
2
- beforeEach module("mb.controllers")
3
- beforeEach module("mocks")
1
+ describe "servers show controller", ->
2
+ beforeEach module("mb")
4
3
 
5
4
  $scope = null
6
5
  $httpBackend = null
@@ -8,10 +7,10 @@ describe "serverInfo", ->
8
7
  beforeEach inject ($injector, $rootScope, $controller) ->
9
8
  $scope = $rootScope.$new()
10
9
 
11
- $httpBackend = $injector.get('$httpBackend')
12
- $httpBackend.when("GET", "/api/server_info.json").respond([])
10
+ $httpBackend = $injector.get("$httpBackend")
11
+ $httpBackend.whenGET("/api/server_info").respond([])
13
12
 
14
- $controller "serverInfo",
13
+ $controller "servers.show",
15
14
  $scope: $scope
16
15
 
17
16
  $httpBackend.flush()
@@ -1,47 +1,103 @@
1
1
  describe "directives", ->
2
2
  beforeEach module("mb.directives")
3
3
 
4
- $scope = null
4
+ $rootScope = null
5
5
  element = null
6
6
 
7
7
  describe "osEsc", ->
8
- beforeEach inject ($compile, $rootScope) ->
9
- $scope = $rootScope.$new()
10
- $scope.bar = ->
8
+ beforeEach inject ($compile, _$rootScope_) ->
9
+ $rootScope = _$rootScope_
10
+ $rootScope.bar = ->
11
11
 
12
- element = $compile('<input type="text" on-esc="bar()" />')($scope)
13
- $scope.$digest()
12
+ element = angular.element """
13
+ <input type="text" on-esc="bar()" />
14
+ """
15
+ $compile(element)($rootScope)
16
+ $rootScope.$digest()
14
17
 
15
18
  it "calls the given function when the ESC was pressed", ->
16
- spyOn($scope, 'bar')
19
+ spyOn($rootScope, 'bar')
17
20
 
18
21
  event = jQuery.Event("keyup", keyCode: 27)
19
22
  element.trigger(event)
20
23
 
21
- expect($scope.bar).toHaveBeenCalled()
24
+ expect($rootScope.bar).toHaveBeenCalled()
22
25
 
23
26
  it "does nothing on other keys", ->
24
- spyOn($scope, 'bar')
27
+ spyOn($rootScope, 'bar')
25
28
 
26
29
  event = jQuery.Event("keyup", keyCode: 13)
27
30
  element.trigger(event)
28
31
 
29
- expect($scope.bar).not.toHaveBeenCalled()
32
+ expect($rootScope.bar).not.toHaveBeenCalled()
30
33
 
31
- describe "deleteButton", ->
32
- beforeEach inject ($compile, $rootScope) ->
33
- $scope = $rootScope.$new()
34
- $scope.bar = ->
34
+ describe "showButton", ->
35
+ renderedButton = null
36
+
37
+ # TODO use this trick in other places
38
+ compileTemplate = (template, callback = ->) ->
39
+ beforeEach inject ($compile, $rootScope) ->
40
+ element = angular.element(template)
41
+
42
+ $compile(element)($rootScope)
43
+ $rootScope.$digest()
44
+
45
+ callback(element)
46
+
47
+ describe "when a custom label is not provided", ->
48
+ template = """
49
+ <div>
50
+ <show-button path="/foo/bar/biz" />
51
+ </div>
52
+ """
53
+
54
+ compileTemplate template, (element) ->
55
+ renderedButton = element.find("a")
56
+
57
+ it "renders the button", ->
58
+ expect(renderedButton.length).toBe(1)
59
+ expect(renderedButton.hasClass("btn")).toBeTruthy()
60
+ expect(renderedButton.hasClass("btn-success")).toBeTruthy()
61
+
62
+ it "renders the path", ->
63
+ expect(renderedButton.attr("href")).toEqual("/foo/bar/biz")
35
64
 
65
+ it "renders the custom label", ->
66
+ expect(renderedButton.text()).toContain("Show")
67
+
68
+ describe "when a custom label is provided", ->
36
69
  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", ->
70
+ <div>
71
+ <show-button label="Display me the foo" path="/foo/bar" />
72
+ </div>
73
+ """
74
+
75
+ compileTemplate template, (element) ->
76
+ renderedButton = element.find("a")
77
+
78
+ it "renders the button", ->
79
+ expect(renderedButton.length).toBe(1)
80
+ expect(renderedButton.hasClass("btn")).toBeTruthy()
81
+ expect(renderedButton.hasClass("btn-success")).toBeTruthy()
82
+ expect(renderedButton.attr("href")).toEqual("/foo/bar")
83
+
84
+ it "renders the custom label", ->
85
+ expect(renderedButton.text()).toContain("Display me the foo")
86
+
87
+ describe "deleteButton", ->
88
+ beforeEach inject ($compile, $rootScope) ->
89
+ $rootScope = $rootScope
90
+ $rootScope.bar = ->
91
+
92
+ element = angular.element """
93
+ <div>
94
+ <delete-button ng-click="bar()" />
95
+ </div>
96
+ """
97
+ $compile(element)($rootScope)
98
+ $rootScope.$digest()
99
+
100
+ it "renders delete button", ->
45
101
  button = element.find("a")
46
102
 
47
103
  expect(button.length).toBe(1)
@@ -50,9 +106,37 @@ describe "directives", ->
50
106
  expect(button.text()).toContain("Delete")
51
107
 
52
108
  it "ng-click", ->
53
- spyOn($scope, 'bar')
109
+ spyOn($rootScope, 'bar')
54
110
 
55
111
  button = element.find("button")
56
112
  button.click()
57
113
 
58
- expect($scope.bar).not.toHaveBeenCalled()
114
+ expect($rootScope.bar).not.toHaveBeenCalled()
115
+
116
+ describe "refreshButton", ->
117
+ beforeEach inject ($compile) ->
118
+ $rootScope.refresh = ->
119
+
120
+ element = angular.element """
121
+ <div>
122
+ <refresh-button ng-click="refresh()" />
123
+ </div>
124
+ """
125
+ $compile(element)($rootScope)
126
+ $rootScope.$digest()
127
+
128
+ it "renders delete button", ->
129
+ button = element.find("a")
130
+
131
+ expect(button.length).toBe(1)
132
+ expect(button.hasClass("btn")).toBeTruthy()
133
+ expect(button.text()).toContain("Refresh")
134
+
135
+ describe "ng-click on the button", ->
136
+ it "calls #refresh() method", ->
137
+ spyOn($rootScope, "refresh")
138
+
139
+ button = element.find("a")
140
+ button.click()
141
+
142
+ expect($rootScope.refresh).toHaveBeenCalled()
@@ -58,17 +58,17 @@ describe "filters", ->
58
58
  expect(filter(o)).toContain('<span class="null">null</span>')
59
59
 
60
60
  it "can format ObjectId", ->
61
- o = {
61
+ document = {
62
62
  _id: { $oid: "50bfc4b6dac5d5630800017a" },
63
63
  foo: "something",
64
64
  comapany_id: { $oid: "50bfc4b6dac5d56308000119" }
65
65
  }
66
66
 
67
- expect(filter(o)).toContain('<span class="key">_id:</span>')
68
- expect(filter(o)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d5630800017a"</span>)')
67
+ expect(filter(document)).toContain('<span class="key">_id:</span>')
68
+ expect(filter(document)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d5630800017a"</span>)')
69
69
 
70
- expect(filter(o)).toContain('<span class="key">comapany_id:</span>')
71
- expect(filter(o)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d56308000119"</span>)')
70
+ expect(filter(document)).toContain('<span class="key">comapany_id:</span>')
71
+ expect(filter(document)).toContain('ObjectId(<span class="string">"50bfc4b6dac5d56308000119"</span>)')
72
72
 
73
73
  # url helpers
74
74
 
@@ -97,3 +97,29 @@ describe "filters", ->
97
97
  it "generates na url for the given collection documents", ->
98
98
  collection = { dbName: "foo", name: "bars" }
99
99
  expect(filter(collection)).toEqual("/databases/foo/collections/bars/documents")
100
+
101
+ describe "#documentPath", ->
102
+ filter = null
103
+
104
+ beforeEach inject (documentPathFilter) ->
105
+ filter = documentPathFilter
106
+
107
+ it "without parameters generates an url with placeholders", ->
108
+ expect(filter()).toEqual("/databases/:dbName/collections/:collectionName/documents/:id")
109
+
110
+ it "generates na url for the given collection documents", ->
111
+ document = { dbName: "foo", collectionName: "bars", id: "documentId" }
112
+ expect(filter(document)).toEqual("/databases/foo/collections/bars/documents/documentId")
113
+
114
+ describe "documentPrettyTime", ->
115
+ filter = null
116
+
117
+ beforeEach inject (documentPrettyTimeFilter) ->
118
+ filter = documentPrettyTimeFilter
119
+
120
+ it "extracts time from document id", ->
121
+ expect(filter(id: "50c33814dac5d5c9310001bd"))
122
+ .toEqual("Sat, 08 Dec 2012 12:52:36 GMT")
123
+
124
+ expect(filter(id: "50d7134ddac5d501aa000003"))
125
+ .toEqual("Sun, 23 Dec 2012 14:21:01 GMT")
@@ -0,0 +1,138 @@
1
+ describe "mb.alerts", ->
2
+ beforeEach module("mb.alerts")
3
+ beforeEach module("mocks")
4
+
5
+ describe "controller", ->
6
+ $scope = null
7
+ alerts = null
8
+
9
+ beforeEach inject ($injector, $rootScope, $controller) ->
10
+ $scope = $rootScope.$new()
11
+
12
+ alerts = $injector.get("alerts")
13
+
14
+ $controller "alerts",
15
+ $scope: $scope,
16
+ alerts: alerts
17
+
18
+ it "assings flash messages", ->
19
+ expect($scope.alertMessages).toBeDefined()
20
+ expect($scope.alertMessages).toEqual([])
21
+
22
+ alerts.info("Test message.")
23
+ expect($scope.alertMessages).toContain(id: 1, type: "info", text: "Test message.")
24
+
25
+ describe "#disposeAlert", ->
26
+ it "disposes an alert at the given index", ->
27
+ # Given
28
+ alerts.info("Information..")
29
+ alerts.error("Error..")
30
+ spyOn(alerts, "dispose").andCallThrough()
31
+
32
+ # When
33
+ $scope.disposeAlert(2)
34
+
35
+ # Then
36
+ expect(alerts.dispose).toHaveBeenCalledWith(2)
37
+ expect($scope.alertMessages).toContain(id: 1, type: "info", text: "Information..")
38
+ expect($scope.alertMessages).not.toContain(id: 2, type: "error", text: "Error..")
39
+
40
+ describe "directive", ->
41
+ $scope = null
42
+ element = null
43
+
44
+ beforeEach module("public/ng/templates/alerts.html")
45
+
46
+ beforeEach inject ($rootScope, $compile) ->
47
+ $scope = $rootScope
48
+
49
+ element = angular.element "<alerts></alerts>"
50
+ $compile(element)($scope)
51
+ $scope.$digest()
52
+
53
+ it "renders alerts", ->
54
+ $scope.$apply -> $scope.alertMessages = [
55
+ type: "info", text: "Test message"
56
+ ]
57
+ expect(element.find(".alert-info").length).toEqual(1)
58
+
59
+ describe "service", ->
60
+ it "is defined", inject (alerts) ->
61
+ expect(alerts).toBeDefined()
62
+
63
+ describe "#nextId", ->
64
+ it "return the next id for the new flash message", inject (alerts) ->
65
+ expect(alerts.nextId()).toEqual(1)
66
+ _(4).times -> alerts.nextId()
67
+ expect(alerts.nextId()).toEqual(6)
68
+
69
+ describe "#push", ->
70
+ beforeEach inject (alerts) ->
71
+ spyOn(alerts, "delayedDispose")
72
+
73
+ it "returns an id for the new flash message", inject (alerts) ->
74
+ expect(alerts.push("info", "Test..")).toEqual(1)
75
+ expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
76
+
77
+ expect(alerts.push("error", "Test error..")).toEqual(2)
78
+ expect(alerts.delayedDispose).toHaveBeenCalledWith(2)
79
+
80
+ describe "#info", ->
81
+ it "pushesh the given message", inject (alerts) ->
82
+ # Given
83
+ testMessage = "This is a test message!"
84
+ otherTestMessage = "This is a second test message!"
85
+
86
+ # When
87
+ alerts.info(testMessage)
88
+ expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
89
+
90
+ alerts.info(otherTestMessage)
91
+ expect(alerts.delayedDispose).toHaveBeenCalledWith(2)
92
+
93
+ # Then
94
+ expect(alerts.messages).toContain(id: 1, type: "info", text: testMessage)
95
+ expect(alerts.messages).toContain(id: 2, type: "info", text: otherTestMessage)
96
+
97
+ describe "#error", ->
98
+ it "pushesh the given message", inject (alerts) ->
99
+ # Given
100
+ testMessage = "This is a test message!"
101
+
102
+ # When
103
+ alerts.error(testMessage)
104
+ expect(alerts.delayedDispose).toHaveBeenCalledWith(1)
105
+
106
+ # Then
107
+ expect(alerts.messages).toContain(id: 1, type: "error", text: testMessage)
108
+
109
+ describe "#dispose", ->
110
+ it "removes a message with the given id", inject (alerts) ->
111
+ # Given
112
+ alerts.info("First message")
113
+ alerts.info("Second message")
114
+ alerts.info("Third message")
115
+ alerts.error("Error message")
116
+
117
+ # When
118
+ alerts.dispose(2)
119
+
120
+ # Then
121
+ expect(alerts.messages).toContain(id: 1, type: "info", text: "First message")
122
+ expect(alerts.messages).not.toContain(id: 2, type: "info", text: "Second message")
123
+ expect(alerts.messages).toContain(id: 3, type: "info", text: "Third message")
124
+ expect(alerts.messages).toContain(id: 4, type: "error", text: "Error message")
125
+
126
+ describe "#delayedDispose", ->
127
+ it "removes a message after the given time", inject (alerts, $timeout) ->
128
+ # Given
129
+ alerts.info("First message")
130
+
131
+ # When
132
+ alerts.delayedDispose(1)
133
+ expect(alerts.messages).toContain(id: 1, type: "info", text: "First message")
134
+
135
+ $timeout.flush()
136
+
137
+ # Then
138
+ expect(alerts.messages).toEqual([])