mongo_browser 0.2.0.rc2 → 0.2.5

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.
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([])