landable 1.7.0

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 (310) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +15 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +56 -0
  7. data/Rakefile +22 -0
  8. data/app/controllers/concerns/landable/variables_concern.rb +38 -0
  9. data/app/controllers/landable/api/access_tokens_controller.rb +48 -0
  10. data/app/controllers/landable/api/assets_controller.rb +55 -0
  11. data/app/controllers/landable/api/categories_controller.rb +13 -0
  12. data/app/controllers/landable/api/directories_controller.rb +19 -0
  13. data/app/controllers/landable/api/page_revisions_controller.rb +38 -0
  14. data/app/controllers/landable/api/pages_controller.rb +96 -0
  15. data/app/controllers/landable/api/templates_controller.rb +33 -0
  16. data/app/controllers/landable/api/themes_controller.rb +57 -0
  17. data/app/controllers/landable/api_controller.rb +75 -0
  18. data/app/controllers/landable/application_controller.rb +4 -0
  19. data/app/controllers/landable/public/pages_controller.rb +25 -0
  20. data/app/controllers/landable/public/preview/page_revisions_controller.rb +16 -0
  21. data/app/controllers/landable/public/preview/pages_controller.rb +16 -0
  22. data/app/controllers/landable/public/sitemap_controller.rb +18 -0
  23. data/app/decorators/landable/null_page_decorator.rb +26 -0
  24. data/app/decorators/landable/page_decorator.rb +40 -0
  25. data/app/helpers/landable/application_helper.rb +13 -0
  26. data/app/helpers/landable/pages_helper.rb +20 -0
  27. data/app/models/concerns/landable/has_assets.rb +74 -0
  28. data/app/models/concerns/landable/table_name.rb +12 -0
  29. data/app/models/concerns/landable/traffic/table_name.rb +14 -0
  30. data/app/models/landable/access_token.rb +20 -0
  31. data/app/models/landable/asset.rb +63 -0
  32. data/app/models/landable/asset_search_engine.rb +20 -0
  33. data/app/models/landable/author.rb +12 -0
  34. data/app/models/landable/category.rb +27 -0
  35. data/app/models/landable/directory.rb +23 -0
  36. data/app/models/landable/page.rb +259 -0
  37. data/app/models/landable/page_revision.rb +74 -0
  38. data/app/models/landable/page_search_engine.rb +20 -0
  39. data/app/models/landable/search_engine.rb +39 -0
  40. data/app/models/landable/template.rb +24 -0
  41. data/app/models/landable/theme.rb +20 -0
  42. data/app/models/landable/traffic/access.rb +11 -0
  43. data/app/models/landable/traffic/ad_group.rb +11 -0
  44. data/app/models/landable/traffic/ad_type.rb +11 -0
  45. data/app/models/landable/traffic/attribution.rb +38 -0
  46. data/app/models/landable/traffic/bid_match_type.rb +11 -0
  47. data/app/models/landable/traffic/browser.rb +11 -0
  48. data/app/models/landable/traffic/campaign.rb +11 -0
  49. data/app/models/landable/traffic/city.rb +11 -0
  50. data/app/models/landable/traffic/content.rb +11 -0
  51. data/app/models/landable/traffic/cookie.rb +16 -0
  52. data/app/models/landable/traffic/country.rb +11 -0
  53. data/app/models/landable/traffic/creative.rb +11 -0
  54. data/app/models/landable/traffic/device.rb +11 -0
  55. data/app/models/landable/traffic/device_type.rb +11 -0
  56. data/app/models/landable/traffic/domain.rb +12 -0
  57. data/app/models/landable/traffic/event.rb +12 -0
  58. data/app/models/landable/traffic/event_type.rb +11 -0
  59. data/app/models/landable/traffic/experiment.rb +11 -0
  60. data/app/models/landable/traffic/http_method.rb +11 -0
  61. data/app/models/landable/traffic/ip_address.rb +11 -0
  62. data/app/models/landable/traffic/ip_lookup.rb +12 -0
  63. data/app/models/landable/traffic/keyword.rb +11 -0
  64. data/app/models/landable/traffic/location.rb +11 -0
  65. data/app/models/landable/traffic/match_type.rb +11 -0
  66. data/app/models/landable/traffic/medium.rb +11 -0
  67. data/app/models/landable/traffic/mime_type.rb +11 -0
  68. data/app/models/landable/traffic/network.rb +11 -0
  69. data/app/models/landable/traffic/owner.rb +10 -0
  70. data/app/models/landable/traffic/ownership.rb +10 -0
  71. data/app/models/landable/traffic/page_view.rb +24 -0
  72. data/app/models/landable/traffic/path.rb +13 -0
  73. data/app/models/landable/traffic/placement.rb +11 -0
  74. data/app/models/landable/traffic/platform.rb +11 -0
  75. data/app/models/landable/traffic/position.rb +11 -0
  76. data/app/models/landable/traffic/query_string.rb +12 -0
  77. data/app/models/landable/traffic/referer.rb +11 -0
  78. data/app/models/landable/traffic/region.rb +11 -0
  79. data/app/models/landable/traffic/search_term.rb +11 -0
  80. data/app/models/landable/traffic/source.rb +11 -0
  81. data/app/models/landable/traffic/target.rb +11 -0
  82. data/app/models/landable/traffic/user_agent.rb +28 -0
  83. data/app/models/landable/traffic/user_agent_type.rb +11 -0
  84. data/app/models/landable/traffic/visit.rb +15 -0
  85. data/app/models/landable/traffic/visitor.rb +13 -0
  86. data/app/responders/landable/api_responder.rb +76 -0
  87. data/app/responders/landable/page_render_responder.rb +15 -0
  88. data/app/serializers/landable/access_token_serializer.rb +6 -0
  89. data/app/serializers/landable/asset_serializer.rb +14 -0
  90. data/app/serializers/landable/author_serializer.rb +5 -0
  91. data/app/serializers/landable/category_serializer.rb +5 -0
  92. data/app/serializers/landable/directory_serializer.rb +8 -0
  93. data/app/serializers/landable/page_revision_serializer.rb +15 -0
  94. data/app/serializers/landable/page_serializer.rb +31 -0
  95. data/app/serializers/landable/template_serializer.rb +5 -0
  96. data/app/serializers/landable/theme_serializer.rb +7 -0
  97. data/app/services/landable/authentication_service.rb +44 -0
  98. data/app/services/landable/registration_service.rb +13 -0
  99. data/app/services/landable/render_service.rb +86 -0
  100. data/app/services/landable/tidy_service.rb +155 -0
  101. data/app/uploaders/landable/asset_uploader.rb +9 -0
  102. data/app/validators/path_validator.rb +12 -0
  103. data/app/validators/url_validator.rb +13 -0
  104. data/app/views/templates/preview.liquid +122 -0
  105. data/bin/rails +8 -0
  106. data/bin/redb +7 -0
  107. data/config.ru +7 -0
  108. data/config/cucumber.yml +5 -0
  109. data/config/routes.rb +62 -0
  110. data/db/migrate/20130510221424_create_landable_schema.rb +338 -0
  111. data/db/migrate/20130909182713_landable_pages__add_updated_by.rb +11 -0
  112. data/db/migrate/20130909182715_landable_page_revisions__break_out_snapshot.rb +72 -0
  113. data/db/migrate/20130909191153_landable_pages__add_lock_version.rb +5 -0
  114. data/db/migrate/20131002220041_file_based_themes.rb +12 -0
  115. data/db/migrate/20131008164204_create_head_tag_on_page.rb +19 -0
  116. data/db/migrate/20131008193544_drop_status_codes_model.rb +44 -0
  117. data/db/migrate/20131028145652_add_traffic_schema.rb +276 -0
  118. data/db/migrate/20131101213623_add_dnt_column_to_visits.rb +7 -0
  119. data/db/migrate/20131104224120_add_meta_on_events.rb +7 -0
  120. data/db/migrate/20131106185946_add_index_on_page_revisions_path.rb +6 -0
  121. data/db/migrate/20131106193021_page_revisisons__path_status_code_index.rb +9 -0
  122. data/db/migrate/20131108212501_traffic_owner_ids_are_serials.rb +20 -0
  123. data/db/migrate/20131121150902_add_attribution_id_to_unique_index.rb +10 -0
  124. data/db/migrate/20131216214027_drop_browser_screenshot_tables.rb +6 -0
  125. data/db/migrate/20140128170659_file_backed_templates.rb +8 -0
  126. data/db/migrate/20140205193757_fix_status_codes.rb +24 -0
  127. data/db/migrate/20140206211322_add_response_time_to_traffic_page_views.rb +7 -0
  128. data/db/migrate/20140220170324_add_slug_to_categories.rb +14 -0
  129. data/db/migrate/20140220174630_add_abstract_and_hero_asset_to_pages_and_page_revisions.rb +8 -0
  130. data/db/migrate/20140224205516_rename_traffic_schema.rb +40 -0
  131. data/db/pgtap/pgtap.sql +9034 -0
  132. data/db/test/landable.access_tokens.sql +13 -0
  133. data/db/test/landable.assets.sql +16 -0
  134. data/db/test/landable.authors.sql +22 -0
  135. data/db/test/landable.categories.sql +9 -0
  136. data/db/test/landable.page_revisions.sql +41 -0
  137. data/db/test/landable.pages.sql +19 -0
  138. data/db/test/landable.templates.sql +15 -0
  139. data/db/test/landable.themes.sql +25 -0
  140. data/doc/schema/access_token.json +22 -0
  141. data/doc/schema/asset.json +65 -0
  142. data/doc/schema/author.json +30 -0
  143. data/doc/schema/directory.json +24 -0
  144. data/doc/schema/page.json +95 -0
  145. data/doc/schema/page_revision.json +70 -0
  146. data/doc/schema/theme.json +37 -0
  147. data/doc/schema/uuid.json +6 -0
  148. data/features/api/access_tokens.feature +84 -0
  149. data/features/api/assets.feature +46 -0
  150. data/features/api/cors.feature +25 -0
  151. data/features/api/pages.feature +42 -0
  152. data/features/api/preview.feature +16 -0
  153. data/features/api/templates.feature +33 -0
  154. data/features/api/themes.feature +33 -0
  155. data/features/liquid/body.feature +35 -0
  156. data/features/liquid/drops/categories.feature +54 -0
  157. data/features/liquid/tags.feature +168 -0
  158. data/features/public/content_types.feature +17 -0
  159. data/features/public/publishing.feature +45 -0
  160. data/features/public/status_codes.feature +25 -0
  161. data/features/public/views.feature +17 -0
  162. data/features/step_definitions/asset_steps.rb +60 -0
  163. data/features/step_definitions/core_api_steps.rb +139 -0
  164. data/features/step_definitions/debug_steps.rb +3 -0
  165. data/features/step_definitions/factory_steps.rb +124 -0
  166. data/features/step_definitions/html_steps.rb +9 -0
  167. data/features/step_definitions/liquid_steps.rb +79 -0
  168. data/features/step_definitions/revision_steps.rb +5 -0
  169. data/features/step_definitions/theme_steps.rb +43 -0
  170. data/features/support/env.rb +66 -0
  171. data/features/support/usefulness.rb +13 -0
  172. data/landable.gemspec +54 -0
  173. data/lib/generators/landable/collection/collection_generator.rb +0 -0
  174. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%.less +0 -0
  175. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/mixins.less +0 -0
  176. data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/variables.less +0 -0
  177. data/lib/generators/landable/component/component_generator.rb +0 -0
  178. data/lib/generators/landable/component/templates/javascripts/landable/%file_name%.less +0 -0
  179. data/lib/generators/landable/component/templates/stylesheets/landable/%file_name%.less +0 -0
  180. data/lib/generators/landable/install_generator.rb +19 -0
  181. data/lib/generators/landable/landable_generator.rb +22 -0
  182. data/lib/generators/templates/landable.rb +34 -0
  183. data/lib/landable.rb +30 -0
  184. data/lib/landable/configuration.rb +115 -0
  185. data/lib/landable/core_ext/ipaddr.rb +18 -0
  186. data/lib/landable/engine.rb +69 -0
  187. data/lib/landable/error.rb +16 -0
  188. data/lib/landable/inflections.rb +4 -0
  189. data/lib/landable/layout.rb +60 -0
  190. data/lib/landable/liquid.rb +27 -0
  191. data/lib/landable/liquid/asset_tags.rb +76 -0
  192. data/lib/landable/liquid/drops.rb +46 -0
  193. data/lib/landable/liquid/filters.rb +11 -0
  194. data/lib/landable/liquid/tags.rb +91 -0
  195. data/lib/landable/migration.rb +40 -0
  196. data/lib/landable/mime_types.rb +15 -0
  197. data/lib/landable/partial.rb +46 -0
  198. data/lib/landable/seeds.rb +36 -0
  199. data/lib/landable/traffic.rb +34 -0
  200. data/lib/landable/traffic/crawl_tracker.rb +9 -0
  201. data/lib/landable/traffic/noop_tracker.rb +8 -0
  202. data/lib/landable/traffic/ping_tracker.rb +9 -0
  203. data/lib/landable/traffic/scan_tracker.rb +9 -0
  204. data/lib/landable/traffic/scrape_tracker.rb +9 -0
  205. data/lib/landable/traffic/tracker.rb +283 -0
  206. data/lib/landable/traffic/user_tracker.rb +65 -0
  207. data/lib/landable/version.rb +10 -0
  208. data/lib/tasks/landable/cucumber.rake +67 -0
  209. data/lib/tasks/landable/data.rake +166 -0
  210. data/lib/tasks/landable/pgtap.rake +26 -0
  211. data/lib/tasks/landable/rdoc.rake +11 -0
  212. data/lib/tasks/landable/seed.rake +16 -0
  213. data/lib/tasks/landable/spec.rake +15 -0
  214. data/script/cucumber +10 -0
  215. data/spec/concerns/landable/has_assets_spec.rb +75 -0
  216. data/spec/concerns/landable/table_name_spec.rb +15 -0
  217. data/spec/concerns/landable/traffic/table_name_spec.rb +16 -0
  218. data/spec/controllers/concerns/landable/variables_concern_spec.rb +66 -0
  219. data/spec/controllers/landable/api/assets_controller_spec.rb +24 -0
  220. data/spec/controllers/landable/api/categories_controller_spec.rb +45 -0
  221. data/spec/controllers/landable/api/directories_controller_spec.rb +56 -0
  222. data/spec/controllers/landable/api/page_revisions_controller_spec.rb +29 -0
  223. data/spec/controllers/landable/api/pages_controller_spec.rb +271 -0
  224. data/spec/controllers/landable/api_controller_spec.rb +189 -0
  225. data/spec/controllers/public/preview/page_revisions_controller_spec.rb +41 -0
  226. data/spec/controllers/public/preview/pages_controller_spec.rb +36 -0
  227. data/spec/controllers/public/sitemap_controller_spec.rb +25 -0
  228. data/spec/decorators/page_decorator_spec.rb +90 -0
  229. data/spec/dummy/README.rdoc +28 -0
  230. data/spec/dummy/Rakefile +6 -0
  231. data/spec/dummy/app/assets/images/foo.jpg +0 -0
  232. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  233. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  234. data/spec/dummy/app/controllers/application_controller.rb +10 -0
  235. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  236. data/spec/dummy/app/controllers/priority_controller.rb +7 -0
  237. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  238. data/spec/dummy/app/mailers/.keep +0 -0
  239. data/spec/dummy/app/models/.keep +0 -0
  240. data/spec/dummy/app/models/concerns/.keep +0 -0
  241. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  242. data/spec/dummy/app/views/layouts/priority.html.erb +18 -0
  243. data/spec/dummy/app/views/partials/_foobazz.html +1 -0
  244. data/spec/dummy/app/views/priority/show.html.erb +11 -0
  245. data/spec/dummy/bin/bundle +3 -0
  246. data/spec/dummy/bin/rails +4 -0
  247. data/spec/dummy/bin/rake +4 -0
  248. data/spec/dummy/config.ru +4 -0
  249. data/spec/dummy/config/application.rb +21 -0
  250. data/spec/dummy/config/boot.rb +5 -0
  251. data/spec/dummy/config/database.yml +60 -0
  252. data/spec/dummy/config/environment.rb +5 -0
  253. data/spec/dummy/config/environments/development.rb +29 -0
  254. data/spec/dummy/config/environments/production.rb +80 -0
  255. data/spec/dummy/config/environments/test.rb +42 -0
  256. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  257. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  258. data/spec/dummy/config/initializers/inflections.rb +16 -0
  259. data/spec/dummy/config/initializers/landable.rb +22 -0
  260. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  261. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  262. data/spec/dummy/config/initializers/session_store.rb +3 -0
  263. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  264. data/spec/dummy/config/locales/en.yml +23 -0
  265. data/spec/dummy/config/routes.rb +4 -0
  266. data/spec/dummy/db/structure.sql +3736 -0
  267. data/spec/dummy/lib/assets/.keep +0 -0
  268. data/spec/dummy/log/.keep +0 -0
  269. data/spec/dummy/public/404.html +58 -0
  270. data/spec/dummy/public/422.html +58 -0
  271. data/spec/dummy/public/500.html +57 -0
  272. data/spec/dummy/public/favicon.ico +0 -0
  273. data/spec/factories/asset.rb +29 -0
  274. data/spec/factories/authors.rb +12 -0
  275. data/spec/factories/category.rb +6 -0
  276. data/spec/factories/page_revision.rb +6 -0
  277. data/spec/factories/pages.rb +33 -0
  278. data/spec/factories/template.rb +13 -0
  279. data/spec/factories/theme.rb +14 -0
  280. data/spec/fixtures/assets/cthulhu.jpg +0 -0
  281. data/spec/fixtures/assets/panda.png +0 -0
  282. data/spec/fixtures/assets/sloth.png +0 -0
  283. data/spec/fixtures/assets/small.pdf +0 -0
  284. data/spec/helpers/pages_helper_spec.rb +35 -0
  285. data/spec/lib/landable/configuration_spec.rb +20 -0
  286. data/spec/lib/landable/layout_spec.rb +25 -0
  287. data/spec/lib/landable/liquid_spec.rb +24 -0
  288. data/spec/lib/landable/migration_spec.rb +51 -0
  289. data/spec/lib/landable/partial_spec.rb +84 -0
  290. data/spec/lib/landable/tracking_spec.rb +62 -0
  291. data/spec/lib/landable/traffic_spec.rb +45 -0
  292. data/spec/models/landable/access_token_spec.rb +13 -0
  293. data/spec/models/landable/asset_spec.rb +48 -0
  294. data/spec/models/landable/directory_spec.rb +36 -0
  295. data/spec/models/landable/page/errors_spec.rb +30 -0
  296. data/spec/models/landable/page_revision_spec.rb +75 -0
  297. data/spec/models/landable/page_spec.rb +377 -0
  298. data/spec/models/landable/template_spec.rb +47 -0
  299. data/spec/models/landable/theme_spec.rb +8 -0
  300. data/spec/responders/page_render_responder_spec.rb +43 -0
  301. data/spec/routing/public_page_route_spec.rb +36 -0
  302. data/spec/services/landable/authentication_service_spec.rb +61 -0
  303. data/spec/services/landable/render_service_spec.rb +103 -0
  304. data/spec/services/landable/tidy_service_spec.rb +157 -0
  305. data/spec/spec_helper.rb +38 -0
  306. data/spec/support/behaviors.rb +107 -0
  307. data/spec/support/carrier_wave.rb +17 -0
  308. data/spec/support/categories.yml +2 -0
  309. data/spec/support/helpers.rb +22 -0
  310. metadata +795 -0
@@ -0,0 +1,65 @@
1
+ module Landable
2
+ module Traffic
3
+ class UserTracker < Tracker
4
+ def track
5
+ load
6
+ cookie
7
+ record_visit
8
+ end
9
+
10
+ def load
11
+ hash = session[:landable] || {}
12
+
13
+ @cookie_id = cookies[:landable]
14
+
15
+ @visit_id = hash[KEYS[:visit_id]]
16
+ @last_visit_time = hash[KEYS[:visit_time]]
17
+ @visitor_id = hash[KEYS[:visitor_id]]
18
+ @visitor_hash = hash[KEYS[:visitor_hash]]
19
+ @attribution_hash = hash[KEYS[:attribution_hash]]
20
+ @referer_hash = hash[KEYS[:referer_hash]]
21
+ end
22
+
23
+ def record_page_view
24
+ PageView.create do |p|
25
+ p.http_method = request.method
26
+ p.mime_type = request.format.to_s
27
+ p.path = request.path
28
+ p.query_string = untracked_parameters.to_query
29
+ p.request_id = request.uuid
30
+
31
+ p.click_id = tracking_parameters["click_id"]
32
+
33
+ p.http_status = response.status
34
+
35
+ p.visit_id = @visit_id
36
+
37
+ p.response_time = ( Time.now - @start_time ) * 1000
38
+ end
39
+ end
40
+
41
+ def save
42
+ record_page_view
43
+
44
+ session[:landable] = {
45
+ KEYS[:visit_id] => @visit_id,
46
+ KEYS[:visit_time] => Time.current,
47
+ KEYS[:visitor_id] => @visitor_id,
48
+ KEYS[:visitor_hash] => visitor_hash,
49
+ KEYS[:attribution_hash] => attribution? ? attribution_hash : @attribution_hash,
50
+ KEYS[:referer_hash] => referer_changed? ? referer_hash : @referer_hash
51
+ }
52
+ end
53
+
54
+ def identify(identifier)
55
+ visit = Visit.find(@visit_id)
56
+ owner = Owner.where(owner: identifier).first_or_create
57
+
58
+ visit.owner = owner
59
+ visit.save!
60
+
61
+ Ownership.where(cookie_id: @cookie_id, owner: owner).first_or_create
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,10 @@
1
+ module Landable
2
+ module VERSION
3
+ MAJOR = 1
4
+ MINOR = 7
5
+ PATCH = 0
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
9
+ end
10
+ end
@@ -0,0 +1,67 @@
1
+ namespace :landable do
2
+ # IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
3
+ # It is recommended to regenerate this file in the future when you upgrade to a
4
+ # newer version of cucumber-rails. Consider adding your own code to a new file
5
+ # instead of editing this one. Cucumber will automatically load all features/**/*.rb
6
+ # files.
7
+
8
+
9
+ unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
10
+
11
+ vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
12
+ $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
13
+
14
+ begin
15
+ require 'cucumber/rake/task'
16
+
17
+ namespace :cucumber do
18
+ Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
19
+ t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
20
+ t.fork = true # You may get faster startup if you set this to false
21
+ t.profile = 'default'
22
+ end
23
+
24
+ Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
25
+ t.binary = vendored_cucumber_bin
26
+ t.fork = true # You may get faster startup if you set this to false
27
+ t.profile = 'wip'
28
+ end
29
+
30
+ Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
31
+ t.binary = vendored_cucumber_bin
32
+ t.fork = true # You may get faster startup if you set this to false
33
+ t.profile = 'rerun'
34
+ end
35
+
36
+ desc 'Run all features'
37
+ task :all => [:ok, :wip]
38
+
39
+ task :statsetup do
40
+ require 'rails/code_statistics'
41
+ ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
42
+ ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features')
43
+ end
44
+ end
45
+ desc 'Alias for cucumber:ok'
46
+ task :cucumber => 'cucumber:ok'
47
+
48
+ task :default => :cucumber
49
+
50
+ task :features => :cucumber do
51
+ STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
52
+ end
53
+
54
+ # In case we don't have ActiveRecord, append a no-op task that we can depend upon.
55
+ task 'db:test:prepare' do
56
+ end
57
+
58
+ task :stats => 'cucumber:statsetup'
59
+ rescue LoadError
60
+ desc 'cucumber rake task not available (cucumber not installed)'
61
+ task :cucumber do
62
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
63
+ end
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,166 @@
1
+ namespace :landable do
2
+ namespace :data do
3
+ desc "Clean & restore database from specified source"
4
+ task :restore => [ 'db:drop', 'db:create', 'db:migrate', 'dump_and_load' ]
5
+
6
+ desc 'Restore database from specified source'
7
+ task dump_and_load: :environment do
8
+ STDOUT.puts 'Enter Remote DB Host'
9
+ host = STDIN.gets.strip
10
+
11
+ STDOUT.puts 'Enter Remote Database'
12
+ database = STDIN.gets.strip
13
+
14
+ STDOUT.puts 'Enter Remote Username'
15
+ username = STDIN.gets.strip
16
+
17
+ `pg_dump -h #{host} -U #{username} --data-only --format plain --schema landable #{database} > landable_import.sql`
18
+ `psql #{Rails.configuration.database_configuration[Rails.env]["database"]} -f landable_import.sql`
19
+ `rm landable_import.sql`
20
+ end
21
+
22
+ desc "Migrates all to new schema"
23
+ task :move_schemas, :old_landable, :new_landable, :old_traffic, :new_traffic do |t, args|
24
+ @old_landable = "#{args[:old_landable]}"
25
+ @new_landable = "#{args[:new_landable]}"
26
+ @old_traffic = "#{args[:old_traffic]}"
27
+ @new_traffic = "#{args[:new_traffic]}"
28
+
29
+ Rake.application.invoke_task("landable:data:create_schemas")
30
+ Rake.application.invoke_task("landable:data:move_tables")
31
+ Rake.application.invoke_task("landable:data:move_sequences")
32
+ Rake.application.invoke_task("landable:data:move_triggers")
33
+ end
34
+
35
+ desc "Creates the new schemas"
36
+ task create_schemas: :environment do
37
+ create_schema("#{@new_landable}")
38
+ create_schema("#{@new_traffic}")
39
+ end
40
+
41
+ desc "Move tables to new db schema"
42
+ task move_tables: :environment do
43
+ move_objects("#{@old_landable}", "#{@new_landable}", 'r', 'TABLE')
44
+ move_objects("#{@old_traffic}", "#{@new_traffic}", 'r', 'TABLE')
45
+ end
46
+
47
+ desc "Move sequences to new db schema"
48
+ task move_sequences: :environment do
49
+ move_objects("#{@old_landable}", "#{@new_landable}", 'S', 'SEQUENCE')
50
+ move_objects("#{@old_traffic}", "#{@new_traffic}", 'S', 'SEQUENCE')
51
+ end
52
+
53
+ desc "Move triggers to new db schema"
54
+ task move_triggers: :environment do
55
+ create_new_triggers("#{@new_landable}")
56
+ drop_old_triggers("#{@old_landable}", "#{@new_landable}")
57
+ end
58
+
59
+ end
60
+
61
+ def create_schema(schema)
62
+ connection = ActiveRecord::Base.connection
63
+
64
+ sql = %{
65
+ CREATE SCHEMA #{schema};
66
+ }
67
+ puts "Creating #{schema} schema"
68
+ connection.execute sql
69
+ end
70
+
71
+ def move_objects(from_schema, to_schema, relkind, object_type)
72
+ connection = ActiveRecord::Base.connection
73
+
74
+ # move objects from public to new schema
75
+ objects = connection.select_all("
76
+ SELECT o.relname
77
+ FROM pg_class o
78
+ JOIN pg_namespace n
79
+ ON n.oid=o.relnamespace
80
+ AND n.nspname = '#{from_schema}'
81
+ AND o.relkind = '#{relkind}'
82
+ ORDER BY o.relname
83
+ ")
84
+
85
+ objects.each do |object|
86
+ sql = %{
87
+ ALTER #{object_type} #{from_schema}.#{object['relname']}
88
+ SET SCHEMA #{to_schema}
89
+ }
90
+ puts "Moving #{from_schema}.#{object['relname']} TO #{to_schema}"
91
+ connection.execute sql
92
+ end
93
+ end
94
+
95
+ def create_new_triggers(new_schema)
96
+ puts "#{new_schema}"
97
+ connection = ActiveRecord::Base.connection
98
+ sql = %{
99
+ CREATE FUNCTION #{new_schema}.pages_revision_ordinal()
100
+ RETURNS TRIGGER
101
+ AS
102
+ $TRIGGER$
103
+ BEGIN
104
+
105
+ IF NEW.ordinal IS NOT NULL THEN
106
+ RAISE EXCEPTION $$Must not supply ordinal value manually.$$;
107
+ END IF;
108
+
109
+ NEW.ordinal = (SELECT COALESCE(MAX(ordinal)+1,1)
110
+ FROM #{new_schema}.page_revisions
111
+ WHERE page_id = NEW.page_id);
112
+
113
+ RETURN NEW;
114
+
115
+ END
116
+ $TRIGGER$
117
+ LANGUAGE plpgsql;
118
+
119
+ CREATE TRIGGER #{new_schema}_page_revisions__bfr_insert
120
+ BEFORE INSERT ON #{new_schema}.page_revisions
121
+ FOR EACH ROW EXECUTE PROCEDURE #{new_schema}.pages_revision_ordinal();
122
+
123
+ CREATE FUNCTION #{new_schema}.tg_disallow()
124
+ RETURNS TRIGGER
125
+ AS
126
+ $TRIGGER$
127
+ BEGIN
128
+
129
+ IF TG_LEVEL <> 'STATEMENT' THEN
130
+ RAISE EXCEPTION $$You should use a statement-level trigger (trigger %, table %)$$, TG_NAME, TG_RELID::regclass;
131
+ END IF;
132
+
133
+ RAISE EXCEPTION $$%s are not allowed on table %$$, TG_OP, TG_RELNAME;
134
+
135
+ RETURN NULL;
136
+
137
+ END
138
+ $TRIGGER$
139
+ LANGUAGE plpgsql;
140
+
141
+ CREATE TRIGGER #{new_schema}_page_revisions__no_delete
142
+ BEFORE DELETE ON #{new_schema}.page_revisions
143
+ FOR EACH STATEMENT EXECUTE PROCEDURE #{new_schema}.tg_disallow();
144
+
145
+ CREATE TRIGGER #{new_schema}_page_revisions__no_update
146
+ BEFORE UPDATE OF notes, is_minor, page_id, author_id, created_at, ordinal ON #{new_schema}.page_revisions
147
+ FOR EACH STATEMENT EXECUTE PROCEDURE #{new_schema}.tg_disallow();
148
+ }
149
+ puts "Creating new triggers..."
150
+ connection.execute sql
151
+ end
152
+
153
+ def drop_old_triggers(old_schema, new_schema)
154
+ connection = ActiveRecord::Base.connection
155
+ sql = %{
156
+ DROP TRIGGER IF EXISTS #{old_schema}_page_revisions__bfr_insert ON #{new_schema}.page_revisions;
157
+ DROP TRIGGER IF EXISTS #{old_schema}_page_revisions__no_delete ON #{new_schema}.page_revisions;
158
+ DROP TRIGGER IF EXISTS #{old_schema}_page_revisions__no_update ON #{new_schema}.page_revisions;
159
+
160
+ DROP FUNCTION IF EXISTS #{old_schema}.pages_revision_ordinal();
161
+ DROP FUNCTION IF EXISTS #{old_schema}.tg_disallow();
162
+ }
163
+ puts "Dropping old triggers..."
164
+ connection.execute sql
165
+ end
166
+ end
@@ -0,0 +1,26 @@
1
+ namespace :landable do
2
+ namespace :pgtap do
3
+ def has_pgprove?
4
+ @@has_prove ||= Kernel.system('which pg_prove > /dev/null')
5
+ end
6
+
7
+ desc "Run PGTap unit tests"
8
+ task :run, [:test_file] => [ :environment ] do |t, args|
9
+ dbdir = "#{Rails.root}/../../db"
10
+
11
+ tests = args[:test_file] ? args[:test_file] : "*.sql"
12
+
13
+ if not has_pgprove?
14
+ puts "\nPGTap not installed. Skipping DB unit tests"
15
+ puts "Reference 'http://pgtap.org/documentation.html#installation' for installation instructions."
16
+ else
17
+ # Load pgtap functions into database. Will not complain if already loaded.
18
+ ActiveRecord::Base.connection.execute(IO.read("#{dbdir}/pgtap/pgtap.sql"))
19
+
20
+ sh "cd #{dbdir}/test && pg_prove -d #{ActiveRecord::Base.connection.current_database} #{tests}"
21
+ end
22
+ end
23
+ end
24
+
25
+ task :pgtap => 'pgtap:run'
26
+ end
@@ -0,0 +1,11 @@
1
+ require 'rdoc/task'
2
+
3
+ namespace :landable do
4
+ RDoc::Task.new(:rdoc) do |rdoc|
5
+ rdoc.rdoc_dir = 'rdoc'
6
+ rdoc.title = 'Landable'
7
+ rdoc.options << '--line-numbers'
8
+ rdoc.rdoc_files.include('README.rdoc')
9
+ rdoc.rdoc_files.include('lib/**/*.rb')
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ namespace :landable do
2
+ namespace :seed do
3
+ desc 'Seed extra data (starter themes)'
4
+ task :extras => :environment do
5
+ Landable::Seeds.seed(:extras)
6
+ end
7
+
8
+ desc 'Seed required data (categories)'
9
+ task :required => :environment do
10
+ Landable::Seeds.seed(:required)
11
+ end
12
+ end
13
+
14
+ desc 'Seed required and extra data'
15
+ task :seed => ['seed:required', 'seed:extras']
16
+ end
@@ -0,0 +1,15 @@
1
+ namespace :landable do
2
+ begin
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run specs'
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ rescue LoadError
10
+ desc 'Run specs (missing rspec)'
11
+ task :spec do
12
+ raise 'rspec not present'
13
+ end
14
+ end
15
+ end
data/script/cucumber ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
4
+ if vendored_cucumber_bin
5
+ load File.expand_path(vendored_cucumber_bin)
6
+ else
7
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
8
+ require 'cucumber'
9
+ load Cucumber::BINARY
10
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ module Landable
4
+ describe HasAssets do
5
+
6
+ before(:each) { create_list :asset, 4 }
7
+
8
+ let(:assets) { Landable::Asset.first(3) }
9
+ let(:subject) {
10
+ build :page, {
11
+ body: "
12
+ <div>{% img_tag #{assets[0].name} %}</div>
13
+ <div>{% asset_url #{assets[1].name} %}</div>
14
+ <div>{% asset_description #{assets[2].name} %}</div>
15
+ <div>{% img_tag #{assets[0].name} %}</div>
16
+ "
17
+ }
18
+ }
19
+
20
+ describe '#assets' do
21
+ it 'should return assets matching #asset_names' do
22
+ result = double()
23
+ subject.should_receive(:asset_names) { ['one', 'two', 'three'] }
24
+ Landable::Asset.should_receive(:where).with(name: ['one', 'two', 'three']) { result }
25
+ subject.assets.should == result
26
+ end
27
+ end
28
+
29
+ describe '#asset_names' do
30
+ it 'should pull asset names out of the body' do
31
+ subject.asset_names.sort.should == assets.map(&:name).uniq.sort
32
+ end
33
+ end
34
+
35
+ describe '#save_assets!' do
36
+ it 'should save the assets' do
37
+ assets_double = double()
38
+ subject.should_receive(:assets) { assets_double }
39
+ subject.should_receive(:assets=).with(assets_double)
40
+ subject.save_assets!
41
+ end
42
+
43
+ it 'should be called during save' do
44
+ subject.should_receive :save_assets!
45
+ subject.save!
46
+ end
47
+ end
48
+
49
+ describe '#assets_as_hash' do
50
+ it 'should return a hash of asset names to asset instances' do
51
+ subject.save!
52
+ subject.assets_as_hash.should == Hash[assets.map { |asset| [asset.name, asset] }]
53
+ end
54
+ end
55
+
56
+ describe 'body=' do
57
+ it 'should reset the asset_names cache, then set the body' do
58
+ subject.instance_eval { @asset_names = 'foo' }
59
+ subject.body = 'bar'
60
+ subject.body.should == 'bar'
61
+ subject.instance_eval { @asset_names }.should be_nil
62
+ subject.asset_names.should == []
63
+ end
64
+ end
65
+
66
+ describe '#assets_join_table_name' do
67
+ it 'should generate the correct join_table, and then apologize for doing so' do
68
+ Page.send(:assets_join_table_name).should == "#{Landable.configuration.database_schema_prefix}landable.page_assets"
69
+ PageRevision.send(:assets_join_table_name).should == "#{Landable.configuration.database_schema_prefix}landable.page_revision_assets"
70
+ Theme.send(:assets_join_table_name).should == "#{Landable.configuration.database_schema_prefix}landable.theme_assets"
71
+ end
72
+ end
73
+
74
+ end
75
+ end