prosperity 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/prosperity/application.js.coffee +5 -24
  3. data/app/assets/javascripts/prosperity/dashboards.js.coffee +17 -0
  4. data/app/assets/javascripts/prosperity/graph.js.coffee +89 -0
  5. data/app/assets/stylesheets/prosperity/application.css.scss +1 -1
  6. data/app/assets/stylesheets/prosperity/dashboards.css +4 -0
  7. data/app/assets/stylesheets/prosperity/graph.css +4 -0
  8. data/app/controllers/prosperity/application_controller.rb +30 -0
  9. data/app/controllers/prosperity/dashboard_graphs_controller.rb +24 -0
  10. data/app/controllers/prosperity/dashboards_controller.rb +33 -0
  11. data/app/controllers/prosperity/graphs_controller.rb +72 -0
  12. data/app/controllers/prosperity/metrics_controller.rb +57 -0
  13. data/app/helpers/prosperity/application_helper.rb +4 -0
  14. data/app/helpers/prosperity/dashboard_graphs_helper.rb +4 -0
  15. data/app/helpers/prosperity/dashboards_helper.rb +4 -0
  16. data/app/helpers/prosperity/graph_helper.rb +7 -0
  17. data/app/models/prosperity/dashboard.rb +8 -0
  18. data/app/models/prosperity/dashboard_graph.rb +6 -0
  19. data/app/models/prosperity/graph.rb +20 -0
  20. data/app/models/prosperity/graph_line.rb +8 -0
  21. data/app/views/layouts/prosperity/application.html.erb +56 -0
  22. data/app/views/prosperity/dashboards/edit.html.erb +24 -0
  23. data/app/views/prosperity/dashboards/index.html.erb +15 -0
  24. data/app/views/prosperity/dashboards/new.html.erb +8 -0
  25. data/app/views/prosperity/dashboards/show.html.erb +14 -0
  26. data/app/views/prosperity/graphs/edit.html.erb +41 -0
  27. data/app/views/prosperity/graphs/new.html.erb +15 -0
  28. data/app/views/prosperity/metrics/index.html.erb +8 -0
  29. data/app/views/prosperity/metrics/show.html.erb +23 -0
  30. data/app/views/prosperity/shared/_date_range.html.erb +9 -0
  31. data/config/routes.rb +12 -2
  32. data/db/migrate/20131127042251_dashboards.rb +34 -0
  33. data/lib/generators/metric/USAGE +8 -0
  34. data/lib/generators/metric/metric_generator.rb +7 -0
  35. data/lib/generators/metric/templates/metric.rb.erb +3 -0
  36. data/lib/prosperity/aggregate/aggregate_builder.rb +42 -0
  37. data/lib/prosperity/aggregate/average.rb +12 -0
  38. data/lib/prosperity/aggregate/base.rb +5 -0
  39. data/lib/prosperity/aggregate/count.rb +12 -0
  40. data/lib/prosperity/aggregate/maximum.rb +12 -0
  41. data/lib/prosperity/aggregate/minimum.rb +12 -0
  42. data/lib/prosperity/aggregate/sql.rb +12 -0
  43. data/lib/prosperity/aggregate/sum.rb +12 -0
  44. data/lib/prosperity/aggregate/with_column.rb +10 -0
  45. data/lib/prosperity/aggregate.rb +5 -0
  46. data/lib/prosperity/engine.rb +14 -0
  47. data/lib/prosperity/exception.rb +19 -1
  48. data/lib/prosperity/extractors/base.rb +33 -5
  49. data/lib/prosperity/extractors/change.rb +35 -0
  50. data/lib/prosperity/extractors/interval.rb +51 -0
  51. data/lib/prosperity/extractors/total.rb +23 -0
  52. data/lib/prosperity/helpers/time.rb +12 -0
  53. data/lib/prosperity/metric.rb +90 -5
  54. data/lib/prosperity/metric_finder.rb +10 -0
  55. data/lib/prosperity/metrics/option.rb +2 -0
  56. data/lib/prosperity/period.rb +4 -3
  57. data/lib/prosperity/periods.rb +13 -2
  58. data/lib/prosperity/version.rb +1 -1
  59. data/spec/controllers/prosperity/dashboard_graphs_controller_spec.rb +45 -0
  60. data/spec/controllers/prosperity/dashboards_controller_spec.rb +54 -0
  61. data/spec/controllers/prosperity/graphs_controller_spec.rb +145 -0
  62. data/spec/controllers/prosperity/metrics_controller_spec.rb +78 -0
  63. data/spec/dummy/app/models/user.rb +1 -0
  64. data/spec/dummy/app/prosperity/user_value_sum_metric.rb +4 -0
  65. data/spec/dummy/app/prosperity/user_value_sum_sql_metric.rb +4 -0
  66. data/spec/dummy/app/prosperity/users_metric.rb +8 -0
  67. data/spec/dummy/app/prosperity/users_sql_metric.rb +4 -0
  68. data/spec/dummy/config/database.yml +0 -8
  69. data/spec/dummy/config/routes.rb +1 -1
  70. data/spec/dummy/db/migrate/20140217005117_add_value_to_users.rb +5 -0
  71. data/spec/dummy/db/schema.rb +37 -1
  72. data/spec/dummy/db/seeds.rb +3 -1
  73. data/spec/dummy/log/development.log +76950 -0
  74. data/spec/dummy/log/test.log +111316 -0
  75. data/spec/dummy/tmp/cache/assets/development/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/07e8fb2db7d85e29590a6b05160ca825 +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/1533bcf4a8f5a745dfda80cebd88d217 +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/1643e7f9f85637df140a850af6674f10 +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/2733033a48e2e8a6fdd6e4ab371689ee +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  84. data/spec/dummy/tmp/cache/assets/development/sprockets/3e21790900d62ae3954585f08a1cb28a +0 -0
  85. data/spec/dummy/tmp/cache/assets/development/sprockets/3f76425644a701b85db3d385f077052d +0 -0
  86. data/spec/dummy/tmp/cache/assets/development/sprockets/448c1e44da04c20f27eaa31ad8c4391e +0 -0
  87. data/spec/dummy/tmp/cache/assets/development/sprockets/47df4fdca8a2ff6a43c18d7aa1ffd9c5 +0 -0
  88. data/spec/dummy/tmp/cache/assets/development/sprockets/566fbede2036fd06a20e7e52e30ddc7d +0 -0
  89. data/spec/dummy/tmp/cache/assets/development/sprockets/5f1aaf22720701db690538726e896a39 +0 -0
  90. data/spec/dummy/tmp/cache/assets/development/sprockets/647038c58f26163a9217646e1e5f09ae +0 -0
  91. data/spec/dummy/tmp/cache/assets/development/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  92. data/spec/dummy/tmp/cache/assets/development/sprockets/69f4b83d363269ee4122bbbaaa1325d1 +0 -0
  93. data/spec/dummy/tmp/cache/assets/development/sprockets/6e1aee34907ba1ccdbfca2deb18a5adb +0 -0
  94. data/spec/dummy/tmp/cache/assets/development/sprockets/72c0d4a0eeedae5e79ae49abb24f6d32 +0 -0
  95. data/spec/dummy/tmp/cache/assets/development/sprockets/828a046f0e7dc2dad0eecfe49d31e14d +0 -0
  96. data/spec/dummy/tmp/cache/assets/development/sprockets/91ae0bd43f98b4f1f111e0bdc178302c +0 -0
  97. data/spec/dummy/tmp/cache/assets/development/sprockets/97d99b466bedb69706f4815fa26b69f3 +0 -0
  98. data/spec/dummy/tmp/cache/assets/development/sprockets/990cf740a7968767a327f6186313badb +0 -0
  99. data/spec/dummy/tmp/cache/assets/development/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  100. data/spec/dummy/tmp/cache/assets/development/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  101. data/spec/dummy/tmp/cache/assets/development/sprockets/bb1f5ffb0ccbeec2c6499044b356f7c6 +0 -0
  102. data/spec/dummy/tmp/cache/assets/development/sprockets/bc83340720a76d8208112f6aecbff08e +0 -0
  103. data/spec/dummy/tmp/cache/assets/development/sprockets/be67cef79122a71f7432c2f984f1f258 +0 -0
  104. data/spec/dummy/tmp/cache/assets/development/sprockets/c83e71ece967e80f8df838874c130431 +0 -0
  105. data/spec/dummy/tmp/cache/assets/development/sprockets/cad26971ff72bbf5aa5f4e6a469389eb +0 -0
  106. data/spec/dummy/tmp/cache/assets/development/sprockets/d0d5517256edcd1f83b11a13c6ca040f +0 -0
  107. data/spec/dummy/tmp/cache/assets/development/sprockets/d0f0c5e105bfb1d6e5cd7295fbd1f65d +0 -0
  108. data/spec/dummy/tmp/cache/assets/development/sprockets/d3087f7df919b7f0d8142ee163db6c79 +0 -0
  109. data/spec/dummy/tmp/cache/assets/development/sprockets/decc27a1fa9ea32fe0dcc18619e32587 +0 -0
  110. data/spec/dummy/tmp/cache/assets/development/sprockets/df796f7ea525be06a82ebc3a4f97ffec +0 -0
  111. data/spec/dummy/tmp/cache/assets/development/sprockets/e02b5049cf477b43a72b4a00e2fceb46 +0 -0
  112. data/spec/dummy/tmp/cache/assets/development/sprockets/e2a9bdd87a2d19256837fce6544a122c +0 -0
  113. data/spec/dummy/tmp/cache/assets/development/sprockets/e378dcebf3c529db0d6e57d0c8dc3904 +0 -0
  114. data/spec/dummy/tmp/cache/assets/development/sprockets/ee3031bd54230ddf2addb5fa5718c86b +0 -0
  115. data/spec/dummy/tmp/cache/assets/development/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  116. data/spec/dummy/tmp/cache/assets/development/sprockets/f9bbf698d099ead559e5ba4a5a4c5538 +0 -0
  117. data/spec/dummy/tmp/cache/assets/development/sprockets/fb8d3825617fcc11dfa614a51effee0e +0 -0
  118. data/spec/dummy/tmp/cache/assets/test/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  119. data/spec/dummy/tmp/cache/assets/test/sprockets/07e8fb2db7d85e29590a6b05160ca825 +0 -0
  120. data/spec/dummy/tmp/cache/assets/test/sprockets/0a40fa5e0d6c0de40a8a698dcd697305 +0 -0
  121. data/spec/dummy/tmp/cache/assets/test/sprockets/1533bcf4a8f5a745dfda80cebd88d217 +0 -0
  122. data/spec/dummy/tmp/cache/assets/test/sprockets/1643e7f9f85637df140a850af6674f10 +0 -0
  123. data/spec/dummy/tmp/cache/assets/test/sprockets/177ca1f3e92db4f8a8f6e7ad9786ebfc +0 -0
  124. data/spec/dummy/tmp/cache/assets/test/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  125. data/spec/dummy/tmp/cache/assets/test/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  126. data/spec/dummy/tmp/cache/assets/test/sprockets/1cb94582c835e73b3fd3c276f9a7de56 +0 -0
  127. data/spec/dummy/tmp/cache/assets/test/sprockets/203047a4141cf08162077e7290421bbb +0 -0
  128. data/spec/dummy/tmp/cache/assets/test/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  129. data/spec/dummy/tmp/cache/assets/test/sprockets/2733033a48e2e8a6fdd6e4ab371689ee +0 -0
  130. data/spec/dummy/tmp/cache/assets/test/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  131. data/spec/dummy/tmp/cache/assets/test/sprockets/29a6c93aeb91d07a5533b3adba7697d0 +0 -0
  132. data/spec/dummy/tmp/cache/assets/test/sprockets/29ac2be474969468157245a7f8737fa4 +0 -0
  133. data/spec/dummy/tmp/cache/assets/test/sprockets/314e44d29ecc7449c9ca3b754329c245 +0 -0
  134. data/spec/dummy/tmp/cache/assets/test/sprockets/3162d1398d6940ee5e933b7ab4d2273d +0 -0
  135. data/spec/dummy/tmp/cache/assets/test/sprockets/3d80e2a5faaf2bd987d804c17aead745 +0 -0
  136. data/spec/dummy/tmp/cache/assets/test/sprockets/4155a156cc6ffb880b56dbc34346fbc0 +0 -0
  137. data/spec/dummy/tmp/cache/assets/test/sprockets/4166fe47cddf4ba18c53b843d69b4c5f +0 -0
  138. data/spec/dummy/tmp/cache/assets/test/sprockets/441f922b26aae90d40e319b6ed0a3bc8 +0 -0
  139. data/spec/dummy/tmp/cache/assets/test/sprockets/4432a4b71ce9551df8d4b3860f4b9be3 +0 -0
  140. data/spec/dummy/tmp/cache/assets/test/sprockets/448c1e44da04c20f27eaa31ad8c4391e +0 -0
  141. data/spec/dummy/tmp/cache/assets/test/sprockets/47df4fdca8a2ff6a43c18d7aa1ffd9c5 +0 -0
  142. data/spec/dummy/tmp/cache/assets/test/sprockets/5479c7b4fba9179d4d1dc59ae64964c1 +0 -0
  143. data/spec/dummy/tmp/cache/assets/test/sprockets/566fbede2036fd06a20e7e52e30ddc7d +0 -0
  144. data/spec/dummy/tmp/cache/assets/test/sprockets/5a3ab9afd151c265cf11c621c0ddbe00 +0 -0
  145. data/spec/dummy/tmp/cache/assets/test/sprockets/647038c58f26163a9217646e1e5f09ae +0 -0
  146. data/spec/dummy/tmp/cache/assets/test/sprockets/64e0150fafbd9aaa3822efa1abb0211d +0 -0
  147. data/spec/dummy/tmp/cache/assets/test/sprockets/65c2d908dbca1bc833ae0b552f6c27fa +0 -0
  148. data/spec/dummy/tmp/cache/assets/test/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  149. data/spec/dummy/tmp/cache/assets/test/sprockets/69f4b83d363269ee4122bbbaaa1325d1 +0 -0
  150. data/spec/dummy/tmp/cache/assets/test/sprockets/6e1aee34907ba1ccdbfca2deb18a5adb +0 -0
  151. data/spec/dummy/tmp/cache/assets/test/sprockets/726d3f6850549a59954f0bf5584cfd9f +0 -0
  152. data/spec/dummy/tmp/cache/assets/test/sprockets/7ab9ac7cc2529219a4c68fd7854d5c0f +0 -0
  153. data/spec/dummy/tmp/cache/assets/test/sprockets/7bac3aca131c870ad5b07d8ccdc86e06 +0 -0
  154. data/spec/dummy/tmp/cache/assets/test/sprockets/80392355fc6e00cf69b2cd46978ebcbe +0 -0
  155. data/spec/dummy/tmp/cache/assets/test/sprockets/874b42463fefbb0bce47775722ebb4ae +0 -0
  156. data/spec/dummy/tmp/cache/assets/test/sprockets/87ef8ddd2847d19f22a16d726b88b433 +0 -0
  157. data/spec/dummy/tmp/cache/assets/test/sprockets/91ae0bd43f98b4f1f111e0bdc178302c +0 -0
  158. data/spec/dummy/tmp/cache/assets/test/sprockets/97d99b466bedb69706f4815fa26b69f3 +0 -0
  159. data/spec/dummy/tmp/cache/assets/test/sprockets/990cf740a7968767a327f6186313badb +0 -0
  160. data/spec/dummy/tmp/cache/assets/test/sprockets/9a690664139b0393787d6454b4697183 +0 -0
  161. data/spec/dummy/tmp/cache/assets/test/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  162. data/spec/dummy/tmp/cache/assets/test/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  163. data/spec/dummy/tmp/cache/assets/test/sprockets/bc83340720a76d8208112f6aecbff08e +0 -0
  164. data/spec/dummy/tmp/cache/assets/test/sprockets/c29c465933e7e86d6f6224f5e78c5baf +0 -0
  165. data/spec/dummy/tmp/cache/assets/test/sprockets/c975834a35907ecd2d314bbd6844ee88 +0 -0
  166. data/spec/dummy/tmp/cache/assets/test/sprockets/cad26971ff72bbf5aa5f4e6a469389eb +0 -0
  167. data/spec/dummy/tmp/cache/assets/test/sprockets/cf4affc50c6303e717d6514380d1f417 +0 -0
  168. data/spec/dummy/tmp/cache/assets/test/sprockets/d0d5517256edcd1f83b11a13c6ca040f +0 -0
  169. data/spec/dummy/tmp/cache/assets/test/sprockets/d3087f7df919b7f0d8142ee163db6c79 +0 -0
  170. data/spec/dummy/tmp/cache/assets/test/sprockets/d8b357d5741711da2dd710af0e15d268 +0 -0
  171. data/spec/dummy/tmp/cache/assets/test/sprockets/decc27a1fa9ea32fe0dcc18619e32587 +0 -0
  172. data/spec/dummy/tmp/cache/assets/test/sprockets/df796f7ea525be06a82ebc3a4f97ffec +0 -0
  173. data/spec/dummy/tmp/cache/assets/test/sprockets/e22a1b318499e7f06ea9274e18ab004f +0 -0
  174. data/spec/dummy/tmp/cache/assets/test/sprockets/e298cc3a8203ab1fb6978a90254f8926 +0 -0
  175. data/spec/dummy/tmp/cache/assets/test/sprockets/e378dcebf3c529db0d6e57d0c8dc3904 +0 -0
  176. data/spec/dummy/tmp/cache/assets/test/sprockets/e868f358fe87542c483951a2d9f532b6 +0 -0
  177. data/spec/dummy/tmp/cache/assets/test/sprockets/e8a6adf580ebd1942f4aabe6738678c2 +0 -0
  178. data/spec/dummy/tmp/cache/assets/test/sprockets/ed71f99e0a9653296abd5d6f501dd898 +0 -0
  179. data/spec/dummy/tmp/cache/assets/test/sprockets/efe6f2d16d3a1819817efb8734daf8af +0 -0
  180. data/spec/dummy/tmp/cache/assets/test/sprockets/f03e99bdb4159ae3485ca2858716e19b +0 -0
  181. data/spec/dummy/tmp/cache/assets/test/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  182. data/spec/dummy/tmp/cache/assets/test/sprockets/f961f7434a28c0fe24bf4ffe6cba75fb +0 -0
  183. data/spec/dummy/tmp/cache/assets/test/sprockets/f9bbf698d099ead559e5ba4a5a4c5538 +0 -0
  184. data/spec/dummy/tmp/cache/assets/test/sprockets/fb8d3825617fcc11dfa614a51effee0e +0 -0
  185. data/spec/helpers/prosperity/dashboard_graphs_helper_spec.rb +6 -0
  186. data/spec/helpers/prosperity/dashboards_helper_spec.rb +6 -0
  187. data/spec/helpers/prosperity/{metrics_helper_spec.rb → graph_helper_spec.rb} +1 -1
  188. data/spec/lib/prosperity/aggregate/aggregate_builder_spec.rb +65 -0
  189. data/spec/lib/prosperity/aggregate/average_spec.rb +7 -0
  190. data/spec/lib/prosperity/aggregate/base_spec.rb +7 -0
  191. data/spec/lib/prosperity/aggregate/count_spec.rb +7 -0
  192. data/spec/lib/prosperity/aggregate/maximum_spec.rb +7 -0
  193. data/spec/lib/prosperity/aggregate/minimum_spec.rb +7 -0
  194. data/spec/lib/prosperity/aggregate/sql_spec.rb +7 -0
  195. data/spec/lib/prosperity/aggregate/sum_spec.rb +7 -0
  196. data/spec/lib/prosperity/aggregate/with_column_spec.rb +7 -0
  197. data/spec/lib/prosperity/aggregate_spec.rb +7 -0
  198. data/spec/lib/prosperity/extractors/base_spec.rb +27 -2
  199. data/spec/lib/prosperity/extractors/change_spec.rb +72 -0
  200. data/spec/lib/prosperity/extractors/interval_spec.rb +153 -0
  201. data/spec/lib/prosperity/extractors/total_spec.rb +79 -0
  202. data/spec/lib/prosperity/helpers/time_spec.rb +7 -0
  203. data/spec/lib/prosperity/metric_finder_spec.rb +7 -0
  204. data/spec/lib/prosperity/metric_spec.rb +126 -1
  205. data/spec/lib/prosperity/periods_spec.rb +14 -0
  206. data/spec/models/prosperity/dashboard_graph_spec.rb +6 -0
  207. data/spec/models/prosperity/dashboard_spec.rb +6 -0
  208. data/spec/models/prosperity/graph_line_spec.rb +6 -0
  209. data/spec/models/prosperity/graph_spec.rb +6 -0
  210. data/spec/spec_helper.rb +5 -2
  211. data/spec/support/shared/extractors.rb +64 -0
  212. data/spec/support/test_database.rb +1 -0
  213. data/vendor/assets/javascripts/highcharts.js +285 -0
  214. metadata +317 -62
  215. data/app/helpers/prosperity/metrics_helper.rb +0 -11
  216. data/app/views/layouts/prosperity/application.html.haml +0 -37
  217. data/app/views/prosperity/metrics/index.html.haml +0 -7
  218. data/db/migrate/20131026214127_test.rb +0 -4
  219. data/lib/prosperity/extractors/count.rb +0 -18
  220. data/lib/prosperity/extractors/group.rb +0 -23
  221. data/spec/lib/prosperity/extractors/count_spec.rb +0 -35
  222. data/spec/lib/prosperity/extractors/group_spec.rb +0 -34
  223. data/vendor/assets/javascripts/chart.js +0 -1426
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe DashboardGraphsController do
5
+ routes { Prosperity::Engine.routes }
6
+
7
+ let(:valid_graph_attributes) do
8
+ { title: "My Graph", period: "month" }
9
+ end
10
+
11
+ let!(:valid_dashboard_attributes) do
12
+ { title: "My Dashboard", default: false }
13
+ end
14
+
15
+ let(:graph) { Graph.create!(valid_graph_attributes) }
16
+ let(:dashboard) { Dashboard.create!(valid_dashboard_attributes) }
17
+ let(:dashboard_graph) { DashboardGraph.create! graph: graph, dashboard: dashboard }
18
+
19
+ describe "POST 'create'" do
20
+ it "associates a graph an a dashboard" do
21
+ expect do
22
+ post :create, dashboard_id: dashboard.id, graph_id: graph.id
23
+ end.to change(DashboardGraph, :count).by(1)
24
+ dg = DashboardGraph.last
25
+ dg.graph.should == graph
26
+ dg.dashboard.should == dashboard
27
+ end
28
+ end
29
+
30
+ describe "DELETE 'destroy'" do
31
+ it "deassociates a graph an a dashboard" do
32
+ dashboard_graph
33
+ expect do
34
+ delete :destroy, dashboard_id: dashboard.id, graph_id: graph.id
35
+ end.to change(DashboardGraph, :count).by(-1)
36
+ end
37
+
38
+ it "404 when not found" do
39
+ expect do
40
+ delete :destroy, dashboard_id: dashboard.id, graph_id: graph.id
41
+ end.to raise_exception(ActiveRecord::RecordNotFound)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe DashboardsController do
5
+ let!(:dashboard) { Dashboard.create! title: "My Dashboard", default: false }
6
+ routes { Prosperity::Engine.routes }
7
+
8
+ describe "GET 'index'" do
9
+ it "returns http success" do
10
+ get 'index'
11
+ response.should be_success
12
+ assigns(:dashboards).should be_present
13
+ end
14
+ end
15
+
16
+ describe "GET 'show'" do
17
+ it "returns http success" do
18
+ get 'show', id: dashboard.id
19
+ response.should be_success
20
+ assigns(:dashboard).should == dashboard
21
+ end
22
+ end
23
+
24
+ describe "GET 'edit'" do
25
+ it "returns http success" do
26
+ get 'edit', id: dashboard.id
27
+ response.should be_success
28
+ assigns(:dashboard).should == dashboard
29
+ end
30
+ end
31
+
32
+ describe "GET 'new'" do
33
+ it "returns http success" do
34
+ get 'new'
35
+ response.should be_success
36
+ end
37
+ end
38
+
39
+ describe "POST 'create'" do
40
+ it "creates a new dashboard" do
41
+ expect do
42
+ post 'create', dashboard: {title: 'test'}
43
+ end.to change(Dashboard, :count).by(1)
44
+ response.should redirect_to(action: :index)
45
+ end
46
+
47
+ it "should handle validation error" do
48
+ post 'create', dashboard: {title: ''}
49
+ response.status.should == 200
50
+ flash[:error].should be_present
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ module Prosperity
4
+ describe GraphsController do
5
+ routes { Prosperity::Engine.routes }
6
+
7
+ let(:valid_attributes) do
8
+ {
9
+ title: "My Graph",
10
+ period: "month",
11
+ }
12
+ end
13
+
14
+ let(:invalid_attributes) do
15
+ {graph: {}}
16
+ end
17
+
18
+ let(:json) { JSON.parse(response.body) }
19
+ let(:graph) { Graph.create!(valid_attributes) }
20
+ let(:valid_line_attributes) do
21
+ {
22
+ option: 'foo',
23
+ metric: 'bar',
24
+ extractor: 'count',
25
+ }
26
+ end
27
+
28
+ let(:graph_w_line) do
29
+ g = Graph.create!(valid_attributes)
30
+ g.graph_lines.create!(valid_line_attributes)
31
+ g
32
+ end
33
+
34
+ describe "GET 'new'" do
35
+ it "returns http success" do
36
+ get 'new'
37
+ response.should be_success
38
+ assigns(:graph).should be_a(Graph)
39
+ end
40
+ end
41
+
42
+ describe "GET 'edit'" do
43
+ it "returns http success" do
44
+ get 'edit', id: graph.id
45
+ response.should be_success
46
+ assigns(:graph).should == graph
47
+ end
48
+ end
49
+
50
+ describe "GET 'show'" do
51
+ it "renders the JSON representation of the graph" do
52
+ get :show, id: graph.id
53
+ response.should be_success
54
+ json['title'].should == graph.title
55
+ json['extractors'].should == []
56
+ end
57
+
58
+ it "returns one extractor per graph line" do
59
+ get :show, id: graph_w_line
60
+ response.should be_success
61
+ json['extractors'].count.should == 1
62
+ ext = json['extractors'].first
63
+ ext['key'].should == valid_line_attributes[:extractor]
64
+ ext['url'].should be_present
65
+ end
66
+ end
67
+
68
+ describe "POST create" do
69
+ it "should create a new graph with the correct attributes" do
70
+ expect do
71
+ post :create, graph: valid_attributes
72
+ end.to change(Graph, :count).by(1)
73
+ graph = assigns(:graph)
74
+ response.should redirect_to(edit_graph_path(graph))
75
+ end
76
+
77
+ it "handles invalid attributes" do
78
+ post :create, graph: invalid_attributes
79
+ response.should be_success
80
+ flash[:error].should be_present
81
+ end
82
+ end
83
+
84
+ describe "PUT update" do
85
+ let(:update_attrs) do
86
+ {
87
+ "graph_lines_attributes" => {
88
+ "0" => valid_line_attributes
89
+ }
90
+ }
91
+ end
92
+
93
+ it "Add the graph line" do
94
+ put :update, id: graph.id, graph: update_attrs
95
+ response.should be_redirect
96
+ graph.reload.graph_lines.size.should == 1
97
+ end
98
+
99
+ let(:line) { graph_w_line.graph_lines.first }
100
+ let(:update_line_attrs) do
101
+ {
102
+ "graph_lines_attributes" => {
103
+ "0" => {
104
+ id: line.id,
105
+ option: 'new_option',
106
+ extractor: 'interval'
107
+ }
108
+ }
109
+ }
110
+ end
111
+
112
+ it "updates an existing line" do
113
+ put :update, id: graph_w_line.id, graph: update_line_attrs
114
+ response.should be_redirect
115
+ line = graph_w_line.reload.graph_lines.first
116
+ line.option.should == 'new_option'
117
+ line.extractor.should == 'interval'
118
+ end
119
+
120
+ it "updates an existing line while ignoring blank ones" do
121
+ line = graph.graph_lines.create!(valid_line_attributes)
122
+
123
+ attrs = {
124
+ "graph_lines_attributes"=>{
125
+ "0"=>{
126
+ "option"=>"default",
127
+ "metric"=>"UsersMetric",
128
+ "extractor"=>"interval",
129
+ "id"=> line.id,
130
+ }, "1"=>{
131
+ "option"=>"default",
132
+ "metric"=>"",
133
+ "extractor"=>"change"
134
+ }
135
+ }
136
+ }
137
+
138
+ put :update, id: graph.id, graph: attrs
139
+ response.should be_redirect
140
+ line.reload.extractor.should == 'interval'
141
+ graph.reload.graph_lines.count.should == 1
142
+ end
143
+ end
144
+ end
145
+ end
@@ -3,6 +3,8 @@ require 'spec_helper'
3
3
  module Prosperity
4
4
  describe MetricsController do
5
5
  routes { Prosperity::Engine.routes }
6
+ let(:json) { JSON.parse(response.body) }
7
+ let(:metric) { UsersMetric.new }
6
8
 
7
9
  describe "GET index" do
8
10
  it "returns successfully" do
@@ -10,5 +12,81 @@ module Prosperity
10
12
  response.should be_success
11
13
  end
12
14
  end
15
+
16
+ describe "GET show" do
17
+ it "returns a metric" do
18
+ get :show, id: metric.id
19
+ response.should be_success
20
+ assigns(:metric).should be_a(Metric)
21
+ end
22
+
23
+ it "returns the metric as JSON" do
24
+ get :show, id: metric.id, format: 'json'
25
+ response.should be_success
26
+ json['id'].should == metric.id
27
+ json['title'].should == metric.title
28
+
29
+ options = json['options']
30
+ options.should be_an(Array)
31
+ options.size.should == metric.options.size
32
+ options.map{|o| o['key'] }.sort.should == metric.options.keys.sort
33
+
34
+ extractors = json['extractors']
35
+ extractors.should be_an(Array)
36
+ extractors.size.should == metric.options.size
37
+ end
38
+ end
39
+
40
+ describe "GET data" do
41
+ it "returns interval data by default" do
42
+ Extractors::Interval.any_instance.stub(to_a: [1,2,3])
43
+
44
+ get :data, id: metric.id, format: 'json'
45
+ response.should be_success
46
+ json['data'].should == [1,2,3]
47
+ end
48
+
49
+ it "lets you specify any extractor key" do
50
+ Extractors::Total.any_instance.stub(to_a: [1,2,3])
51
+
52
+ get :data, id: metric.id, extractor: 'total', format: 'json'
53
+ response.should be_success
54
+ json['data'].should == [1,2,3]
55
+ json['key'].should == 'total'
56
+ (DateTime.parse(json['start_time']).to_i - 3.months.ago.to_i).should be <= 1.hour
57
+ json['period_milliseconds'].should == 1.week.to_i * 1000
58
+ end
59
+
60
+ it "lets you specify the option parameter" do
61
+ Extractors::Interval.any_instance.stub(to_a: [1,2,3])
62
+ Extractors::Interval.should_receive(:new).with(anything,
63
+ 'with_1',
64
+ anything,
65
+ anything,
66
+ anything).and_call_original
67
+
68
+ get :data, id: metric.id, option: 'with_1', format: 'json'
69
+ response.should be_success
70
+ json['data'].should == [1,2,3]
71
+ end
72
+
73
+ it "lets you specify the period" do
74
+ get :data, id: metric.id, period: 'week', format: 'json'
75
+ response.should be_success
76
+ json['data'].size.should be >= 12
77
+ end
78
+
79
+ it "lets you specify the date range" do
80
+ get :data, id: metric.id, period: 'week', start_time: Time.now.beginning_of_day, end_time: Time.now.end_of_day, format: 'json'
81
+ response.should be_success
82
+ json['data'].size.should be >= 1
83
+ end
84
+
85
+ it "return 404 error code if specified metric does not exist" do
86
+ get :data, id: 'blah', format: 'json'
87
+ response.code.to_i.should == 404
88
+ json['error'].should be_present
89
+ end
90
+ end
13
91
  end
14
92
  end
@@ -1,2 +1,3 @@
1
1
  class User < ActiveRecord::Base
2
+ scope :with_1, -> { where("#{table_name}.name LIKE '%1%'") }
2
3
  end
@@ -0,0 +1,4 @@
1
+ class UserValueSumMetric < Prosperity::Metric
2
+ scope { User }
3
+ aggregate { sum(:value) }
4
+ end
@@ -0,0 +1,4 @@
1
+ class UserValueSumSqlMetric < Prosperity::Metric
2
+ sql "SELECT * FROM users"
3
+ aggregate { sum(:value) }
4
+ end
@@ -1,3 +1,11 @@
1
1
  class UsersMetric < Prosperity::Metric
2
2
  scope { User }
3
+
4
+ option('with_1') do |scope|
5
+ scope.with_1
6
+ end
7
+
8
+ option('no_results') do |scope|
9
+ scope.where("1 = 2")
10
+ end
3
11
  end
@@ -0,0 +1,4 @@
1
+ class UsersSqlMetric < Prosperity::Metric
2
+ sql "SELECT * FROM users"
3
+ end
4
+
@@ -1,8 +1,3 @@
1
- # SQLite version 3.x
2
- # gem install postgresql
3
- #
4
- # Ensure the SQLite 3 gem is defined in your Gemfile
5
- # gem 'postgresql'
6
1
  development:
7
2
  adapter: postgresql
8
3
  encoding: unicode
@@ -11,9 +6,6 @@ development:
11
6
  username: postgres
12
7
  password:
13
8
 
14
- # Warning: The database defined as "test" will be erased and
15
- # re-generated from your development database when you run "rake".
16
- # Do not set this db to the same as development or production.
17
9
  test:
18
10
  adapter: postgresql
19
11
  encoding: unicode
@@ -2,5 +2,5 @@ Rails.application.routes.draw do
2
2
  resources :users
3
3
  mount Prosperity::Engine => "/prosperity"
4
4
 
5
- root to: redirect("/prosperity")
5
+ root to: redirect("/prosperity/")
6
6
  end
@@ -0,0 +1,5 @@
1
+ class AddValueToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :value, :integer
4
+ end
5
+ end
@@ -11,16 +11,52 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20131026214807) do
14
+ ActiveRecord::Schema.define(version: 20140217005117) do
15
15
 
16
16
  # These are extensions that must be enabled in order to support this database
17
17
  enable_extension "plpgsql"
18
18
 
19
+ create_table "prosperity_dashboard_graphs", force: true do |t|
20
+ t.integer "graph_id", null: false
21
+ t.integer "dashboard_id", null: false
22
+ t.datetime "created_at"
23
+ t.datetime "updated_at"
24
+ end
25
+
26
+ add_index "prosperity_dashboard_graphs", ["dashboard_id"], name: "index_prosperity_dashboard_graphs_on_dashboard_id", using: :btree
27
+ add_index "prosperity_dashboard_graphs", ["graph_id", "dashboard_id"], name: "index_prosperity_dashboard_graphs_on_graph_id_and_dashboard_id", unique: true, using: :btree
28
+
29
+ create_table "prosperity_dashboards", force: true do |t|
30
+ t.string "title", null: false
31
+ t.boolean "default", null: false
32
+ t.datetime "created_at"
33
+ t.datetime "updated_at"
34
+ end
35
+
36
+ create_table "prosperity_graph_lines", force: true do |t|
37
+ t.integer "graph_id", null: false
38
+ t.string "option", null: false
39
+ t.string "metric", null: false
40
+ t.string "extractor", null: false
41
+ t.datetime "created_at"
42
+ t.datetime "updated_at"
43
+ end
44
+
45
+ add_index "prosperity_graph_lines", ["graph_id"], name: "index_prosperity_graph_lines_on_graph_id", using: :btree
46
+
47
+ create_table "prosperity_graphs", force: true do |t|
48
+ t.string "title", null: false
49
+ t.string "period", null: false
50
+ t.datetime "created_at"
51
+ t.datetime "updated_at"
52
+ end
53
+
19
54
  create_table "users", force: true do |t|
20
55
  t.string "email"
21
56
  t.string "name"
22
57
  t.datetime "created_at"
23
58
  t.datetime "updated_at"
59
+ t.integer "value"
24
60
  end
25
61
 
26
62
  end
@@ -3,5 +3,7 @@
3
3
  User.create name: "User #{i}",
4
4
  email: "user+#{i}@example.org",
5
5
  created_at: t,
6
- updated_at: t
6
+ updated_at: t,
7
+ value: (rand * 100).to_i
8
+
7
9
  end