answers-core 0.0.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 (293) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +6 -0
  3. data/answers-core.gemspec +30 -0
  4. data/app/assets/fonts/answers/League_Gothic-webfont.eot +0 -0
  5. data/app/assets/fonts/answers/League_Gothic-webfont.svg +230 -0
  6. data/app/assets/fonts/answers/League_Gothic-webfont.ttf +0 -0
  7. data/app/assets/fonts/answers/League_Gothic-webfont.woff +0 -0
  8. data/app/assets/images/OaklandCityTree.png +0 -0
  9. data/app/assets/images/background_image.jpg +0 -0
  10. data/app/assets/images/background_pattern.png +0 -0
  11. data/app/assets/images/beta.png +0 -0
  12. data/app/assets/images/bg_transparent.png +0 -0
  13. data/app/assets/images/border.png +0 -0
  14. data/app/assets/images/brigade.png +0 -0
  15. data/app/assets/images/cfa.png +0 -0
  16. data/app/assets/images/cfa_logo.png +0 -0
  17. data/app/assets/images/cfa_logo_footer.png +0 -0
  18. data/app/assets/images/favicon.ico +0 -0
  19. data/app/assets/images/forest.jpeg +0 -0
  20. data/app/assets/images/getting_started_btn.png +0 -0
  21. data/app/assets/images/govuk.png +0 -0
  22. data/app/assets/images/openoaklandlogo.png +0 -0
  23. data/app/assets/images/quick_answers_icon.png +0 -0
  24. data/app/assets/images/quick_answers_icon_small.png +0 -0
  25. data/app/assets/images/searchIcon.png +0 -0
  26. data/app/assets/images/wmd-buttons.png +0 -0
  27. data/app/assets/images/yellow_bg.png +0 -0
  28. data/app/assets/javascripts/answers.js +19 -0
  29. data/app/assets/javascripts/answers/Markdown.Extra.js +304 -0
  30. data/app/assets/javascripts/answers/active_admin.js +62 -0
  31. data/app/assets/javascripts/answers/pagedown/LICENSE.txt +32 -0
  32. data/app/assets/javascripts/answers/pagedown/Markdown.Converter.js +1332 -0
  33. data/app/assets/javascripts/answers/pagedown/Markdown.Editor.js +2212 -0
  34. data/app/assets/javascripts/answers/pagedown/Markdown.Sanitizer.js +108 -0
  35. data/app/assets/javascripts/answers/pagedown/README.txt +0 -0
  36. data/app/assets/javascripts/answers/pagedown/demo/browser/demo.css +120 -0
  37. data/app/assets/javascripts/answers/pagedown/demo/browser/demo.html +83 -0
  38. data/app/assets/javascripts/answers/pagedown/demo/node/demo.js +44 -0
  39. data/app/assets/javascripts/answers/pagedown/local/Markdown.local.fr.js +43 -0
  40. data/app/assets/javascripts/answers/pagedown/node-pagedown.js +2 -0
  41. data/app/assets/javascripts/answers/pagedown/package.json +12 -0
  42. data/app/assets/javascripts/answers/pagedown/resources/wmd-buttons.psd +0 -0
  43. data/app/assets/javascripts/answers/pagedown/wmd-buttons.png +0 -0
  44. data/app/assets/javascripts/answers/skip_nav.js +8 -0
  45. data/app/assets/stylesheets/answers/active_admin.css.scss +17 -0
  46. data/app/assets/stylesheets/answers/active_admin_custom.css.scss +35 -0
  47. data/app/assets/stylesheets/answers/formatting.css +82 -0
  48. data/app/assets/stylesheets/answers/mobile.css +149 -0
  49. data/app/assets/stylesheets/answers/tags.css.scss +3 -0
  50. data/app/assets/stylesheets/answers/theme.css +916 -0
  51. data/app/controllers/answers/answers_controller.rb +26 -0
  52. data/app/controllers/answers/api/v1/answers_controller.rb +38 -0
  53. data/app/controllers/answers/api/v1/api_controller.rb +13 -0
  54. data/app/controllers/answers/api/v1/questions_controller.rb +39 -0
  55. data/app/controllers/answers/api/v1/taggings_controller.rb +46 -0
  56. data/app/controllers/answers/api/v1/tags_controller.rb +38 -0
  57. data/app/controllers/answers/application_controller.rb +27 -0
  58. data/app/controllers/answers/home_controller.rb +17 -0
  59. data/app/controllers/answers/questions_controller.rb +33 -0
  60. data/app/controllers/answers/search_controller.rb +22 -0
  61. data/app/controllers/answers/tags_controller.rb +36 -0
  62. data/app/helpers/answers/tags_helper.rb +7 -0
  63. data/app/models/.gitkeep +0 -0
  64. data/app/models/answers/ability.rb +28 -0
  65. data/app/models/answers/administrator.rb +5 -0
  66. data/app/models/answers/answer.rb +6 -0
  67. data/app/models/answers/api/v1/api_user.rb +5 -0
  68. data/app/models/answers/question.rb +31 -0
  69. data/app/models/answers/user.rb +30 -0
  70. data/app/views/answers/admin/contacts/_article.html.erb +0 -0
  71. data/app/views/answers/admin/dashboard/_dashboard.html.erb +5 -0
  72. data/app/views/answers/admin/guide_steps/_form.html.erb +17 -0
  73. data/app/views/answers/api/v1/answers/_answer.json.jbuilder +2 -0
  74. data/app/views/answers/api/v1/answers/index.json.jbuilder +1 -0
  75. data/app/views/answers/api/v1/answers/show.json.jbuilder +1 -0
  76. data/app/views/answers/api/v1/questions/_question.json.jbuilder +2 -0
  77. data/app/views/answers/api/v1/questions/index.json.jbuilder +1 -0
  78. data/app/views/answers/api/v1/questions/show.json.jbuilder +1 -0
  79. data/app/views/answers/api/v1/taggings/_tagging.json.jbuilder +3 -0
  80. data/app/views/answers/api/v1/taggings/index.json.jbuilder +1 -0
  81. data/app/views/answers/api/v1/taggings/show.json.jbuilder +1 -0
  82. data/app/views/answers/api/v1/tags/_tag.json.jbuilder +2 -0
  83. data/app/views/answers/api/v1/tags/index.json.jbuilder +1 -0
  84. data/app/views/answers/api/v1/tags/show.json.jbuilder +1 -0
  85. data/app/views/answers/devise/confirmations/new.html.erb +12 -0
  86. data/app/views/answers/devise/mailer/confirmation_instructions.html.erb +5 -0
  87. data/app/views/answers/devise/mailer/reset_password_instructions.html.erb +8 -0
  88. data/app/views/answers/devise/mailer/unlock_instructions.html.erb +7 -0
  89. data/app/views/answers/devise/passwords/edit.html.erb +24 -0
  90. data/app/views/answers/devise/passwords/new.html.erb +20 -0
  91. data/app/views/answers/devise/registrations/edit.html.erb +25 -0
  92. data/app/views/answers/devise/registrations/new.html.erb +18 -0
  93. data/app/views/answers/devise/sessions/new.html.erb +25 -0
  94. data/app/views/answers/devise/shared/_links.erb +25 -0
  95. data/app/views/answers/devise/unlocks/new.html.erb +12 -0
  96. data/app/views/answers/home/_article.html.erb +3 -0
  97. data/app/views/answers/home/_category.html.erb +8 -0
  98. data/app/views/answers/home/about.html.erb +72 -0
  99. data/app/views/answers/home/index.html.erb +44 -0
  100. data/app/views/answers/questions/index.html.erb +21 -0
  101. data/app/views/answers/questions/show.html.erb +31 -0
  102. data/app/views/answers/search/index.html.erb +32 -0
  103. data/app/views/answers/shared/_articles_sidebar.html.erb +22 -0
  104. data/app/views/answers/shared/_autocomplete.html.erb +8 -0
  105. data/app/views/answers/shared/_categories_sidebar.html.erb +12 -0
  106. data/app/views/answers/shared/_search_form.html.erb +4 -0
  107. data/app/views/answers/shared/admin/_administration.html.erb +38 -0
  108. data/app/views/answers/shared/admin/_article_actions.html.erb +86 -0
  109. data/app/views/answers/shared/admin/_article_content.html.erb +27 -0
  110. data/app/views/answers/shared/admin/_article_details.html.erb +11 -0
  111. data/app/views/answers/shared/admin/_article_form.html.erb +20 -0
  112. data/app/views/answers/shared/admin/_author_pic.html.erb +0 -0
  113. data/app/views/answers/tags/index.html.erb +34 -0
  114. data/app/views/answers/tags/show.html.erb +31 -0
  115. data/app/views/layouts/answers/application.html.erb +97 -0
  116. data/config.ru +5 -0
  117. data/config/initializers/active_admin.rb +245 -0
  118. data/config/initializers/devise.rb +228 -0
  119. data/config/locales/devise.en.yml +57 -0
  120. data/config/locales/en.yml +129 -0
  121. data/config/routes.rb +22 -0
  122. data/config/secrets.yml +68 -0
  123. data/db/migrate/20140911060606_answers_up.rb +79 -0
  124. data/lib/answers-core.rb +1 -0
  125. data/lib/answers.rb +175 -0
  126. data/lib/answers/admin/answer.rb +29 -0
  127. data/lib/answers/admin/dashboard.rb +75 -0
  128. data/lib/answers/admin/question.rb +57 -0
  129. data/lib/answers/admin/tag.rb +12 -0
  130. data/lib/answers/admin/users.rb +65 -0
  131. data/lib/answers/core.rb +25 -0
  132. data/lib/answers/core/configuration.rb +90 -0
  133. data/lib/answers/core/engine.rb +116 -0
  134. data/lib/answers/engine.rb +62 -0
  135. data/lib/answers/errors.rb +13 -0
  136. data/lib/answers/plugin.rb +75 -0
  137. data/lib/answers/plugins.rb +73 -0
  138. data/lib/answers/version.rb +16 -0
  139. data/lib/api_client.rb +20 -0
  140. data/lib/assets/.gitkeep +0 -0
  141. data/lib/assets/eng_stop.csv +1 -0
  142. data/lib/generators/answers/clash_keywords.yml +3 -0
  143. data/lib/generators/answers/cms/cms_generator.rb +314 -0
  144. data/lib/generators/answers/cms/templates/.gitignore +91 -0
  145. data/lib/generators/answers/cms/templates/app/decorators/controllers/answers/.keep +0 -0
  146. data/lib/generators/answers/cms/templates/app/decorators/models/answers/.keep +0 -0
  147. data/lib/generators/answers/cms/templates/app/views/sitemap/index.xml.builder +15 -0
  148. data/lib/generators/answers/cms/templates/config/database.yml.mysql +20 -0
  149. data/lib/generators/answers/cms/templates/config/database.yml.postgresql +58 -0
  150. data/lib/generators/answers/cms/templates/config/database.yml.sqlite3 +18 -0
  151. data/lib/generators/answers/core/core_generator.rb +10 -0
  152. data/lib/generators/answers/core/templates/config/initializers/answers/core.rb.erb +35 -0
  153. data/lib/generators/answers/dummy/dummy_generator.rb +86 -0
  154. data/lib/generators/answers/dummy/templates/rails/Rakefile +7 -0
  155. data/lib/generators/answers/dummy/templates/rails/application.js +3 -0
  156. data/lib/generators/answers/dummy/templates/rails/application.rb.erb +12 -0
  157. data/lib/generators/answers/dummy/templates/rails/boot.rb.erb +6 -0
  158. data/lib/generators/answers/dummy/templates/rails/database.yml +34 -0
  159. data/lib/generators/answers/dummy/templates/rails/routes.rb +3 -0
  160. data/lib/generators/answers/engine/USAGE +24 -0
  161. data/lib/generators/answers/engine/engine_generator.rb +44 -0
  162. data/lib/generators/answers/engine/templates/.gitignore +2 -0
  163. data/lib/generators/answers/engine/templates/Gemfile +42 -0
  164. data/lib/generators/answers/engine/templates/Rakefile +19 -0
  165. data/lib/generators/answers/engine/templates/answers-extension_plural_name.gemspec +19 -0
  166. data/lib/generators/answers/engine/templates/app/controllers/answers/namespace/admin/plural_name_controller.rb.erb +14 -0
  167. data/lib/generators/answers/engine/templates/app/controllers/answers/namespace/plural_name_controller.rb.erb +34 -0
  168. data/lib/generators/answers/engine/templates/app/models/answers/namespace/singular_name.rb.erb +37 -0
  169. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_actions.html.erb +25 -0
  170. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_form.html.erb +65 -0
  171. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_plural_name.html.erb +2 -0
  172. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_records.html.erb +16 -0
  173. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_singular_name.html.erb +33 -0
  174. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/_sortable_list.html.erb +5 -0
  175. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/edit.html.erb +1 -0
  176. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/index.html.erb +7 -0
  177. data/lib/generators/answers/engine/templates/app/views/answers/namespace/admin/plural_name/new.html.erb +1 -0
  178. data/lib/generators/answers/engine/templates/app/views/answers/namespace/plural_name/index.html.erb +11 -0
  179. data/lib/generators/answers/engine/templates/app/views/answers/namespace/plural_name/show.html.erb +39 -0
  180. data/lib/generators/answers/engine/templates/config/locales/cs.yml +28 -0
  181. data/lib/generators/answers/engine/templates/config/locales/en.yml +28 -0
  182. data/lib/generators/answers/engine/templates/config/locales/es.yml +29 -0
  183. data/lib/generators/answers/engine/templates/config/locales/fr.yml +28 -0
  184. data/lib/generators/answers/engine/templates/config/locales/it.yml +28 -0
  185. data/lib/generators/answers/engine/templates/config/locales/nb.yml +28 -0
  186. data/lib/generators/answers/engine/templates/config/locales/nl.yml +28 -0
  187. data/lib/generators/answers/engine/templates/config/locales/sk.yml +28 -0
  188. data/lib/generators/answers/engine/templates/config/locales/tr.yml +28 -0
  189. data/lib/generators/answers/engine/templates/config/locales/zh-CN.yml +30 -0
  190. data/lib/generators/answers/engine/templates/config/routes.rb.erb +19 -0
  191. data/lib/generators/answers/engine/templates/db/migrate/1_create_namespace_plural_name.rb.erb +39 -0
  192. data/lib/generators/answers/engine/templates/db/seeds.rb.erb +21 -0
  193. data/lib/generators/answers/engine/templates/lib/answers-extension_plural_name.rb.erb +1 -0
  194. data/lib/generators/answers/engine/templates/lib/answers/plural_name.rb.erb +21 -0
  195. data/lib/generators/answers/engine/templates/lib/answers/plural_name/engine.rb.erb +23 -0
  196. data/lib/generators/answers/engine/templates/lib/generators/answers/extension_plural_name_generator.rb.erb +19 -0
  197. data/lib/generators/answers/engine/templates/lib/tasks/answers/extension_plural_name.rake +13 -0
  198. data/lib/generators/answers/engine/templates/readme.md +10 -0
  199. data/lib/generators/answers/engine/templates/script/rails +10 -0
  200. data/lib/generators/answers/engine/templates/spec/features/answers/namespace/admin/plural_name_spec.rb.erb +200 -0
  201. data/lib/generators/answers/engine/templates/spec/models/answers/namespace/singular_name_spec.rb.erb +20 -0
  202. data/lib/generators/answers/engine/templates/spec/spec_helper.rb +31 -0
  203. data/lib/generators/answers/engine/templates/spec/support/factories/answers/plural_name.rb.erb +7 -0
  204. data/lib/generators/answers/engine/templates/tasks/rspec.rake +6 -0
  205. data/lib/generators/answers/engine/templates/tasks/testing.rake +8 -0
  206. data/lib/generators/answers/generator.rb +292 -0
  207. data/lib/markdownifier.rb +11 -0
  208. data/log/.gitkeep +0 -0
  209. data/log/development.log +12870 -0
  210. data/log/newrelic_agent.log +1339 -0
  211. data/log/test.log +233181 -0
  212. data/public/404.html +25 -0
  213. data/public/422.html +25 -0
  214. data/public/500.html +24 -0
  215. data/public/favicon.ico +0 -0
  216. data/public/robots.txt +5 -0
  217. data/script/delayed_job +5 -0
  218. data/spec/controllers/answers_controller_spec.rb +55 -0
  219. data/spec/controllers/api/v1/answers_controller_spec.rb +144 -0
  220. data/spec/controllers/api/v1/questions_controller_spec.rb +144 -0
  221. data/spec/controllers/api/v1/taggings_controller_spec.rb +126 -0
  222. data/spec/controllers/api/v1/tags_controller_spec.rb +126 -0
  223. data/spec/controllers/home_controller_spec.rb +60 -0
  224. data/spec/controllers/questions_controller_spec.rb +55 -0
  225. data/spec/controllers/tags_controller_spec.rb +42 -0
  226. data/spec/factories/answers.rb +10 -0
  227. data/spec/factories/questions.rb +8 -0
  228. data/spec/factories/tags.rb +8 -0
  229. data/spec/factories/user.rb +32 -0
  230. data/spec/features/admin_dashboard_spec.rb +53 -0
  231. data/spec/features/admin_user_spec.rb +61 -0
  232. data/spec/features/searches_spec.rb +101 -0
  233. data/spec/fixtures/Article/_before_validation/sets_access_count_if_nil.yml +223 -0
  234. data/spec/fixtures/Article/_delete_orphaned_keywords/updating_an_article/destroys_orphaned_keywords_associated.yml +223 -0
  235. data/spec/fixtures/Article/_delete_orphaned_keywords/when_deleting_an_article/destroys_all_keywords_associated.yml +223 -0
  236. data/spec/fixtures/Article/_find_by_friendly_id/when_an_article_does_not_exist/does_not_raise_an_exception.yml +223 -0
  237. data/spec/fixtures/Article/_find_by_friendly_id/when_an_article_exists/returns_the_corresponding_article.yml +223 -0
  238. data/spec/fixtures/Article/_find_by_type/excludes_articles_not_matching_specified_type.yml +223 -0
  239. data/spec/fixtures/Article/_find_by_type/returns_articles_matching_type.yml +223 -0
  240. data/spec/fixtures/Article/_hits/before_an_article_has_been_viewed/has_zero_hits.yml +223 -0
  241. data/spec/fixtures/Article/_hits/returns_number_of_views/has_seven_views.yml +223 -0
  242. data/spec/fixtures/Article/_indexable_/returns_false_if_article_is_not_published.yml +223 -0
  243. data/spec/fixtures/Article/_indexable_/returns_true_if_article_is_published.yml +223 -0
  244. data/spec/fixtures/Article/_legacy_/returns_true_if_render_markdown_is_false.yml +223 -0
  245. data/spec/fixtures/Article/_qm_after_create/creates_wordcounts_for_relevant_keywords.yml +223 -0
  246. data/spec/fixtures/Article/_record_hit/viewing_an_article/increases_hit_by_one.yml +223 -0
  247. data/spec/fixtures/Article/_related/has_no_related_articles/.yml +223 -0
  248. data/spec/fixtures/Article/_related/has_related_articles/.yml +223 -0
  249. data/spec/fixtures/Article/_remove_stop_words/removes_common_english_words_from_the_string.yml +223 -0
  250. data/spec/fixtures/Article/_search/_search_titles/query_is_present_in_the_title/.yml +223 -0
  251. data/spec/fixtures/Article/_search/_search_titles/returns_an_empty_array_when_the_search_term_is_present_in_an_article_but_not_the_title.yml +223 -0
  252. data/spec/fixtures/Article/_search/matches_articles_in_the_database.yml +223 -0
  253. data/spec/fixtures/Article/_search/query_does_not_match_anything_in_the_database/returns_an_empty_array.yml +223 -0
  254. data/spec/fixtures/Article/_search/query_is_a_single_space/.yml +223 -0
  255. data/spec/fixtures/Article/_search/query_is_an_empty_string/.yml +223 -0
  256. data/spec/fixtures/Article/_to_s/when_an_article_has_a_category/returns_a_string_containing_title_id_and_category.yml +223 -0
  257. data/spec/fixtures/Article/can_be_published/an_unpublished_article/is_published.yml +223 -0
  258. data/spec/fixtures/Article/can_be_published/an_unpublished_article/returns_status_Published.yml +223 -0
  259. data/spec/fixtures/Article/has_a_friendly_url.yml +223 -0
  260. data/spec/fixtures/Article/is_valid_with_a_title.yml +223 -0
  261. data/spec/fixtures/Searches/search_results/1_result_found/.yml +22047 -0
  262. data/spec/fixtures/Searches/search_results/no_results_found/.yml +393 -0
  263. data/spec/fixtures/Searches/search_results/several_results_found/should_contain_the_title_and_preview_of_both_articles.yml +223 -0
  264. data/spec/fixtures/Searches/search_results/several_results_found/show_the_query.yml +277 -0
  265. data/spec/fixtures/articles.yml +428 -0
  266. data/spec/fixtures/categories.yml +17 -0
  267. data/spec/fixtures/contacts.yml +11 -0
  268. data/spec/fixtures/dragon_keyword_cassette.yml +77 -0
  269. data/spec/fixtures/oakland_answers.yml +2379 -0
  270. data/spec/helpers/tags_helper_spec.rb +15 -0
  271. data/spec/lib/markdownifier_spec.rb +12 -0
  272. data/spec/models/ability_spec.rb +36 -0
  273. data/spec/models/answer_spec.rb +5 -0
  274. data/spec/models/question_spec.rb +70 -0
  275. data/spec/models/user_spec.rb +55 -0
  276. data/spec/routing/answers_routing_spec.rb +19 -0
  277. data/spec/routing/questions_routing_spec.rb +19 -0
  278. data/spec/routing/routes_spec.rb +13 -0
  279. data/spec/security/brakeman_spec.rb +37 -0
  280. data/spec/spec_helper.rb +61 -0
  281. data/spec/support/login_helpers.rb +10 -0
  282. data/spec/support/wait_for_ajax_helper.rb +7 -0
  283. data/spec/support/wait_for_dom_helper.rb +12 -0
  284. data/spec/views/questions/index.html.erb_spec.rb +16 -0
  285. data/spec/views/questions/show.html.erb_spec.rb +14 -0
  286. data/spec/views/tags/index.html.erb_spec.rb +5 -0
  287. data/spec/views/tags/show.html.erb_spec.rb +5 -0
  288. data/vendor/assets/javascripts/.gitkeep +0 -0
  289. data/vendor/assets/stylesheets/.gitkeep +0 -0
  290. data/vendor/assets/stylesheets/bootstrap.css +3990 -0
  291. data/vendor/crudgen/lib/generators/crudgen/install_generator.rb +23 -0
  292. data/vendor/plugins/.gitkeep +0 -0
  293. metadata +484 -0
@@ -0,0 +1,13 @@
1
+ namespace :answers do
2
+
3
+ namespace :<%= extension_plural_name %> do
4
+
5
+ # call this task by running: rake answers:<%= extension_plural_name %>:my_task
6
+ # desc "Description of my task below"
7
+ # task :my_task => :environment do
8
+ # # add your logic here
9
+ # end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,10 @@
1
+ # <%= extension_plural_name.titleize %> extension for Answers.
2
+
3
+ ## How to build this extension as a gem (not required)
4
+
5
+ cd vendor/extensions/<%= extension_plural_name %>
6
+ gem build answers-<%= extension_plural_name %>.gemspec
7
+ gem install answers-<%= extension_plural_name %>.gem
8
+
9
+ # Sign up for a http://rubygems.org/ account and publish the gem
10
+ gem push answers-<%= extension_plural_name %>.gem
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_PATH = File.expand_path('../..', __FILE__)
5
+ dummy_rails_path = File.expand_path('../../spec/dummy/script/rails', __FILE__)
6
+ if File.exist?(dummy_rails_path)
7
+ load dummy_rails_path
8
+ else
9
+ puts "Please first run 'rake answers:testing:dummy_app' to create a dummy Answers application."
10
+ end
@@ -0,0 +1,200 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Answers do
5
+ describe "<%= namespacing %>" do
6
+ describe "Admin" do
7
+ describe "<%= plural_name %>" do
8
+ answers_login_with :answers_user
9
+ <% if (title = attributes.detect { |a| a.type.to_s == "string" }).present? %>
10
+ describe "<%= plural_name %> list" do
11
+ before do
12
+ FactoryGirl.create(:<%= singular_name %>, :<%= title.name %> => "UniqueTitleOne")
13
+ FactoryGirl.create(:<%= singular_name %>, :<%= title.name %> => "UniqueTitleTwo")
14
+ end
15
+
16
+ it "shows two items" do
17
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
18
+ page.should have_content("UniqueTitleOne")
19
+ page.should have_content("UniqueTitleTwo")
20
+ end
21
+ end
22
+
23
+ describe "create" do
24
+ before do
25
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
26
+
27
+ click_link "Add New <%= singular_name.titleize %>"
28
+ end
29
+
30
+ context "valid data" do
31
+ it "should succeed" do
32
+ fill_in "<%= title.name.titleize %>", :with => "This is a test of the first string field"
33
+ click_button "Save"
34
+
35
+ page.should have_content("'This is a test of the first string field' was successfully added.")
36
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 1
37
+ end
38
+ end
39
+
40
+ context "invalid data" do
41
+ it "should fail" do
42
+ click_button "Save"
43
+
44
+ page.should have_content("<%= title.name.titleize %> can't be blank")
45
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 0
46
+ end
47
+ end
48
+
49
+ context "duplicate" do
50
+ before { FactoryGirl.create(:<%= singular_name %>, :<%= title.name %> => "UniqueTitle") }
51
+
52
+ it "should fail" do
53
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
54
+
55
+ click_link "Add New <%= singular_name.titleize %>"
56
+
57
+ fill_in "<%= title.name.titleize %>", :with => "UniqueTitle"
58
+ click_button "Save"
59
+
60
+ page.should have_content("There were problems")
61
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 1
62
+ end
63
+ end
64
+ <% if localized? %>
65
+ context "with translations" do
66
+ before do
67
+ Answers::I18n.stub(:frontend_locales).and_return([:en, :cs])
68
+ end
69
+
70
+ describe "add a page with title for default locale" do
71
+ before do
72
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
73
+ click_link "Add New <%= singular_name.titleize %>"
74
+ fill_in "<%= title.name.titleize %>", :with => "First column"
75
+ click_button "Save"
76
+ end
77
+
78
+ it "should succeed" do
79
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 1
80
+ end
81
+
82
+ it "should show locale flag for page" do
83
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
84
+ within "#<%= singular_name %>_#{p.id}" do
85
+ page.should have_css("img[src='/assets/answers/icons/flags/en.png']")
86
+ end
87
+ end
88
+
89
+ it "should show <%= title.name %> in the admin menu" do
90
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
91
+ within "#<%= singular_name %>_#{p.id}" do
92
+ page.should have_content('First column')
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "add a <%= singular_name %> with title for primary and secondary locale" do
98
+ before do
99
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
100
+ click_link "Add New <%= singular_name.titleize %>"
101
+ fill_in "<%= title.name.titleize %>", :with => "First column"
102
+ click_button "Save"
103
+
104
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
105
+ within ".actions" do
106
+ click_link "Edit this <%= singular_name %>"
107
+ end
108
+ within "#switch_locale_picker" do
109
+ click_link "Cs"
110
+ end
111
+ fill_in "<%= title.name.titleize %>", :with => "First translated column"
112
+ click_button "Save"
113
+ end
114
+
115
+ it "should succeed" do
116
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 1
117
+ Answers::<%= namespacing %>::<%= class_name %>::Translation.count.should == 2
118
+ end
119
+
120
+ it "should show locale flag for page" do
121
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
122
+ within "#<%= singular_name %>_#{p.id}" do
123
+ page.should have_css("img[src='/assets/answers/icons/flags/en.png']")
124
+ page.should have_css("img[src='/assets/answers/icons/flags/cs.png']")
125
+ end
126
+ end
127
+
128
+ it "should show <%= title.name %> in backend locale in the admin menu" do
129
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
130
+ within "#<%= singular_name %>_#{p.id}" do
131
+ page.should have_content('First column')
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "add a <%= title.name %> with title only for secondary locale" do
137
+ before do
138
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
139
+ click_link "Add New <%= singular_name.titleize %>"
140
+ within "#switch_locale_picker" do
141
+ click_link "Cs"
142
+ end
143
+
144
+ fill_in "<%= title.name.titleize %>", :with => "First translated column"
145
+ click_button "Save"
146
+ end
147
+
148
+ it "should show title in backend locale in the admin menu" do
149
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
150
+ within "#<%= singular_name %>_#{p.id}" do
151
+ page.should have_content('First translated column')
152
+ end
153
+ end
154
+
155
+ it "should show locale flag for page" do
156
+ p = Answers::<%= namespacing %>::<%= class_name %>.last
157
+ within "#<%= singular_name %>_#{p.id}" do
158
+ page.should have_css("img[src='/assets/answers/icons/flags/cs.png']")
159
+ end
160
+ end
161
+ end
162
+ end
163
+ <% end %>
164
+ end
165
+
166
+ describe "edit" do
167
+ before { FactoryGirl.create(:<%= singular_name %>, :<%= title.name %> => "A <%= title.name %>") }
168
+
169
+ it "should succeed" do
170
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
171
+
172
+ within ".actions" do
173
+ click_link "Edit this <%= singular_name.titleize.downcase %>"
174
+ end
175
+
176
+ fill_in "<%= title.name.titleize %>", :with => "A different <%= title.name %>"
177
+ click_button "Save"
178
+
179
+ page.should have_content("'A different <%= title.name %>' was successfully updated.")
180
+ page.should have_no_content("A <%= title.name %>")
181
+ end
182
+ end
183
+
184
+ describe "destroy" do
185
+ before { FactoryGirl.create(:<%= singular_name %>, :<%= title.name %> => "UniqueTitleOne") }
186
+
187
+ it "should succeed" do
188
+ visit answers.<%= namespacing.underscore %>_admin_<%= plural_name %>_path
189
+
190
+ click_link "Remove this <%= singular_name.titleize.downcase %> forever"
191
+
192
+ page.should have_content("'UniqueTitleOne' was successfully removed.")
193
+ Answers::<%= namespacing %>::<%= class_name %>.count.should == 0
194
+ end
195
+ end
196
+ <% end %>
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Answers
4
+ module <%= namespacing %>
5
+ describe <%= class_name %> do
6
+ describe "validations" do
7
+ subject do
8
+ FactoryGirl.create(:<%= singular_name %><% if (title = attributes.detect { |a| a.type.to_s == "string" }).present? -%>,
9
+ :<%= title.name %> => "Answers"<% end %>)
10
+ end
11
+
12
+ it { should be_valid }
13
+ its(:errors) { should be_empty }
14
+ <% if title -%>
15
+ its(:<%= title.name %>) { should == "Answers" }
16
+ <% end -%>
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,31 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+
4
+ if File.exist?(dummy_path = File.expand_path('../dummy/config/environment.rb', __FILE__))
5
+ require dummy_path
6
+ elsif File.dirname(__FILE__) =~ %r{vendor/extensions}
7
+ # Require the path to the answers application this is vendored inside.
8
+ require File.expand_path('../../../../../config/environment', __FILE__)
9
+ else
10
+ puts "Could not find a config/environment.rb file to require. Please specify this in #{File.expand_path(__FILE__)}"
11
+ end
12
+
13
+ require 'rspec/rails'
14
+ require 'capybara/rspec'
15
+
16
+ Rails.backtrace_cleaner.remove_silencers!
17
+
18
+ RSpec.configure do |config|
19
+ config.mock_with :rspec
20
+ config.treat_symbols_as_metadata_keys_with_true_values = true
21
+ config.filter_run :focus => true
22
+ config.run_all_when_everything_filtered = true
23
+ end
24
+
25
+ # Requires supporting files with custom matchers and macros, etc,
26
+ # in ./support/ and its subdirectories including factories.
27
+ ([Rails.root.to_s] | ::Answers::Plugins.registered.pathnames).map{|p|
28
+ Dir[File.join(p, 'spec', 'support', '**', '*.rb').to_s]
29
+ }.flatten.sort.each do |support_file|
30
+ require support_file
31
+ end
@@ -0,0 +1,7 @@
1
+ <% if (title = attributes.detect { |a| a.type.to_s == "string" }).present? %>
2
+ FactoryGirl.define do
3
+ factory :<%= singular_name %>, :class => Answers::<%= namespacing %>::<%= class_name %> do
4
+ sequence(:<%= title.name %>) { |n| "answers#{n}" }
5
+ end
6
+ end
7
+ <% end %>
@@ -0,0 +1,6 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc "Run specs"
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.pattern = "./spec"
6
+ end
@@ -0,0 +1,8 @@
1
+ namespace :answers do
2
+ namespace :testing do
3
+ # Put any code in here that you want run when you test this extension against a dummy app.
4
+ # For example, the call to require your gem and start your generator.
5
+ task :setup_extension do
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,292 @@
1
+ require 'pathname'
2
+
3
+ module Answers
4
+ class Generator < Rails::Generators::Base
5
+ source_root Pathname.new(File.expand_path('../templates', __FILE__))
6
+
7
+ class_option :update, :type => :boolean, :aliases => nil, :group => :runtime,
8
+ :desc => "Update an existing Answers based application"
9
+ class_option :fresh_installation, :type => :boolean, :aliases => nil, :group => :runtime, :default => false,
10
+ :desc => "Allow Answers to remove default Rails files in a fresh installation"
11
+ class_option :heroku, :type => :string, :default => nil, :group => :runtime, :banner => 'APP_NAME',
12
+ :desc => "Deploy to Heroku after the generator has run."
13
+ class_option :stack, :type => :string, :default => 'cedar', :group => :runtime,
14
+ :desc => "Specify which Heroku stack you want to use. Requires --heroku option to function."
15
+ class_option :skip_db, :type => :boolean, :default => false, :aliases => nil, :group => :runtime,
16
+ :desc => "Skip over any database creation, migration or seeding."
17
+ class_option :skip_migrations, :type => :boolean, :default => false, :aliases => nil, :group => :runtime,
18
+ :desc => "Skip over installing or running migrations."
19
+
20
+ def generate
21
+ start_pretending?
22
+
23
+ manage_roadblocks! unless self.options[:update]
24
+
25
+ ensure_environments_are_sane!
26
+
27
+ stop_pretending?
28
+
29
+ append_gemfile!
30
+
31
+ append_gitignore!
32
+
33
+ append_asset_pipeline!
34
+
35
+ forced_overwriting?
36
+
37
+ copy_files!
38
+
39
+ create_decorators!
40
+
41
+ mount!
42
+
43
+ run_additional_generators! if self.options[:fresh_installation]
44
+
45
+ migrate_database!
46
+
47
+ seed_database!
48
+
49
+ deploy_to_hosting?
50
+ end
51
+
52
+ protected
53
+
54
+ def append_asset_pipeline!
55
+ application_css = 'app/assets/stylesheets/application.css'
56
+ if destination_path.join(application_css).file?
57
+ insert_into_file application_css, %q{*= require answers/formatting
58
+ *= require answers/theme
59
+ }, :before => "*= require_self"
60
+ end
61
+ end
62
+
63
+ def append_gemfile!
64
+ if destination_path.join('Gemfile').file? &&
65
+ destination_path.join('Gemfile').read !~ %r{group :development, :test do\n.+?gem 'sqlite3'\nend}m
66
+ gsub_file 'Gemfile', %q{gem 'sqlite3'}, %q{group :development, :test do
67
+ gem 'sqlite3'
68
+ end} end
69
+ end
70
+
71
+ def append_gitignore!
72
+ # Ensure .gitignore exists and append our rules to it.
73
+ create_file ".gitignore" unless destination_path.join('.gitignore').file?
74
+ our_ignore_rules = self.class.source_root.join('.gitignore').read
75
+ our_ignore_rules = our_ignore_rules.split('# ANSWERS DEVELOPMENT').first if destination_path != Answers.root
76
+ append_file ".gitignore", our_ignore_rules
77
+ end
78
+
79
+ def append_heroku_gems!
80
+ append_file 'Gemfile', %q{
81
+ # The Heroku gem allows you to interface with Heroku's API
82
+ gem 'heroku'
83
+
84
+ # Fog allows you to use S3 assets (added for Heroku)
85
+ gem 'fog'
86
+ }
87
+ # If postgres is not the database in use, Heroku still needs it.
88
+ if destination_path.join('Gemfile').file? && destination_path.join('Gemfile').read !~ %r{gem ['"]pg['"]}
89
+ append_file 'Gemfile', %q{
90
+ # Postgres support (added for Heroku)
91
+ gem 'pg'
92
+ }
93
+ end
94
+ end
95
+
96
+ def bundle!
97
+ run 'bundle install'
98
+ end
99
+
100
+ def copy_files!
101
+ # The extension installer only installs database templates.
102
+ Pathname.glob(self.class.source_root.join('**', '*')).reject{|f|
103
+ f.directory? or f.to_s =~ /\/db\//
104
+ }.sort.each do |path|
105
+ copy_file path, path.to_s.gsub(self.class.source_root.to_s, destination_path.to_s)
106
+ end
107
+ end
108
+
109
+ def create_decorators!
110
+ # Create decorator directories
111
+ %w[controllers models].each do |decorator_namespace|
112
+ src_file_path = "app/decorators/#{decorator_namespace}/answers/.keep"
113
+ copy_file self.class.source_root.join(src_file_path), destination_path.join(src_file_path)
114
+ end
115
+ end
116
+
117
+ def deploy_to_hosting?
118
+ if heroku?
119
+ append_heroku_gems!
120
+
121
+ bundle!
122
+
123
+ # Sanity check the heroku application name and save whatever messages are produced.
124
+ message = sanity_check_heroku_application_name!
125
+
126
+ # Supply the deploy process with the previous messages to make them visible.
127
+ deploy_to_hosting_heroku!(message)
128
+ end
129
+ end
130
+
131
+ def deploy_to_hosting_heroku!(message = nil)
132
+ say_status "Initializing and committing to git..", nil
133
+ run "git init && git add . && git commit -am 'Created application using Answers #{Answers.version}'"
134
+
135
+ say_status message, nil, :yellow if message
136
+
137
+ say_status "Creating Heroku app..", nil
138
+ run ["heroku create",
139
+ (options[:heroku] if heroku?),
140
+ "#{"--stack #{options[:stack]}" if options[:stack]}"
141
+ ].compact.join(' ')
142
+
143
+ say_status "Pushing to Heroku (this takes time, be patient)..", nil
144
+ run "git push heroku master"
145
+
146
+ say_status "Setting up the Heroku database..", nil
147
+ run "heroku#{' run' if options[:stack] == 'cedar'} rake db:migrate"
148
+
149
+ say_status "Restarting servers...", nil
150
+ run "heroku restart"
151
+ end
152
+
153
+ # Helper method to quickly convert destination_root to a Pathname for easy file path manipulation
154
+ def destination_path
155
+ @destination_path ||= Pathname.new(self.destination_root)
156
+ end
157
+
158
+ def ensure_environments_are_sane!
159
+ # Massage environment files
160
+ %w(development test production).map{|e| "config/environments/#{e}.rb"}.each do |env|
161
+ next unless destination_path.join(env).file?
162
+
163
+ # Answers does not necessarily expect action_mailer to be available as
164
+ # we may not always require it (currently only the authentication extension).
165
+ # Rails, however, will optimistically place config entries for action_mailer.
166
+ current_mailer_config = File.read(destination_path.join(env)).to_s.
167
+ match(%r{^\s.+?config\.action_mailer\..+([\w\W]*\})?}).
168
+ to_a.flatten.first
169
+
170
+ if current_mailer_config.present?
171
+ new_mailer_config = [
172
+ " if config.respond_to?(:action_mailer)",
173
+ current_mailer_config.gsub(%r{\A\n+?}, ''). # remove extraneous newlines at the start
174
+ gsub(%r{^\ \ }) { |line| " #{line}" }, # add indentation on each line
175
+ " end"
176
+ ].join("\n")
177
+
178
+ gsub_file env, current_mailer_config, new_mailer_config, :verbose => false
179
+ end
180
+
181
+ gsub_file env, "config.assets.compile = false", "config.assets.compile = true", :verbose => false
182
+ end
183
+ end
184
+
185
+ def forced_overwriting?
186
+ force_options = self.options.dup
187
+ force_options[:force] = self.options[:force] || self.options[:update]
188
+ self.options = force_options
189
+ end
190
+
191
+ def heroku?
192
+ options[:heroku].present?
193
+ end
194
+
195
+ def manage_roadblocks!
196
+ %w(public/index.html app/views/layouts/application.html.erb).each do |roadblock|
197
+ if (roadblock_path = destination_path.join(roadblock)).file?
198
+ if self.options[:fresh_installation]
199
+ remove_file roadblock_path, :verbose => true
200
+ else
201
+ say_status :"-- You may need to remove '#{roadblock}' for Answers to function properly --", nil, :yellow
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ def migrate_database!
208
+ unless self.options[:skip_migrations]
209
+ rake 'railties:install:migrations'
210
+ rake 'db:create db:migrate' unless self.options[:skip_db]
211
+ end
212
+ end
213
+
214
+ def mount!
215
+ if (routes_file = destination_path.join('config', 'routes.rb')).file? && (self.behavior == :revoke || (routes_file.read !~ %r{mount\ Answers::Core::Engine}))
216
+ # Append routes
217
+ mount = %Q{
218
+ # Answers Platform
219
+ # This line mounts Answers's routes at the root of your application.
220
+ # This means, any requests to the root URL of your application will go to Answers::PagesController#home.
221
+ # If you would like to change where this extension is mounted, simply change the :at option to something different.
222
+ #
223
+ # We ask that you don't use the :as option here, as Answers relies on it being the default of "answers"
224
+ mount Answers::Core::Engine, at: '/'
225
+ ActiveAdmin.routes(self)
226
+
227
+ }
228
+
229
+ inject_into_file 'config/routes.rb', mount, after: ".routes.draw do"
230
+ end
231
+ end
232
+
233
+ def run_additional_generators!
234
+ generator_args = []
235
+ generator_args << '--quiet' if self.options[:quiet]
236
+ generator_args << '--skip-migrations' if self.options[:skip_migrations]
237
+ Answers::CoreGenerator.start generator_args
238
+ Answers::AuthenticationGenerator.start generator_args if defined?(Answers::AuthenticationGenerator)
239
+ Answers::ResourcesGenerator.start generator_args if defined?(Answers::ResourcesGenerator)
240
+ Answers::PagesGenerator.start generator_args if defined?(Answers::PagesGenerator)
241
+ Answers::ImagesGenerator.start generator_args if defined?(Answers::ImagesGenerator)
242
+ Answers::I18nGenerator.start generator_args if defined?(Answers::I18nGenerator)
243
+ end
244
+
245
+ def sanity_check_heroku_application_name!
246
+ if heroku? && options[:heroku].to_s.include?('_') || options[:heroku].to_s.length > 30
247
+ message = ["\nThe application name '#{options[:heroku]}' that you specified is invalid for Heroku."]
248
+ suggested_name = options[:heroku].dup.to_s
249
+ if suggested_name.include?('_')
250
+ message << "This is because it contains underscores which Heroku does not allow."
251
+ suggested_name.gsub!(/_/, '-')
252
+ end
253
+ if suggested_name.length > 30
254
+ message << "This is#{" also" unless suggested_name.nil?} because it is longer than 30 characters."
255
+ suggested_name = suggested_name[0..29]
256
+ end
257
+
258
+ options[:heroku] = suggested_name
259
+
260
+ message << "We have changed the name to '#{suggested_name}' for you, hope it suits you.\n"
261
+ message.join("\n")
262
+ end
263
+
264
+ options[:heroku] = '' if options[:heroku] == 'heroku'
265
+ end
266
+
267
+ def seed_database!
268
+ rake 'db:seed' unless self.options[:skip_db] || self.options[:skip_migrations]
269
+ end
270
+
271
+ def start_pretending?
272
+ # Only pretend to do the next actions if this is Answers to stay DRY
273
+ if destination_path == Answers.root
274
+ say_status :'-- pretending to make changes that happen in an actual installation --', nil, :yellow
275
+ old_pretend = self.options[:pretend]
276
+ new_options = self.options.dup
277
+ new_options[:pretend] = true
278
+ self.options = new_options
279
+ end
280
+ end
281
+
282
+ def stop_pretending?
283
+ # Stop pretending
284
+ if destination_path == Answers.root
285
+ say_status :'-- finished pretending --', nil, :yellow
286
+ new_options = self.options.dup
287
+ new_options[:pretend] = old_pretend
288
+ self.options = new_options
289
+ end
290
+ end
291
+ end
292
+ end