spree_essential_blog 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +12 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +27 -0
  5. data/README.md +126 -0
  6. data/Rakefile +21 -0
  7. data/Versionfile +5 -0
  8. data/app/controllers/blog/admin/disqus_settings_controller.rb +22 -0
  9. data/app/controllers/blog/admin/post_categories_controller.rb +20 -0
  10. data/app/controllers/blog/admin/post_images_controller.rb +37 -0
  11. data/app/controllers/blog/admin/post_products_controller.rb +25 -0
  12. data/app/controllers/blog/admin/posts_controller.rb +32 -0
  13. data/app/controllers/blog/post_categories_controller.rb +23 -0
  14. data/app/controllers/blog/posts_controller.rb +60 -0
  15. data/app/controllers/pages_controller_decorator.rb +5 -0
  16. data/app/helpers/blog/posts_helper.rb +24 -0
  17. data/app/models/blog_configuration.rb +10 -0
  18. data/app/models/post.rb +87 -0
  19. data/app/models/post_category.rb +33 -0
  20. data/app/models/post_image.rb +45 -0
  21. data/app/models/post_product.rb +9 -0
  22. data/app/overrides/spree_essential_blog.rb +5 -0
  23. data/app/validators/datetime_validator.rb +6 -0
  24. data/app/views/blog/admin/configurations/_disqus_config.html.erb +4 -0
  25. data/app/views/blog/admin/disqus_settings/edit.html.erb +16 -0
  26. data/app/views/blog/admin/disqus_settings/show.html.erb +14 -0
  27. data/app/views/blog/admin/post_categories/_form.html.erb +8 -0
  28. data/app/views/blog/admin/post_categories/edit.html.erb +11 -0
  29. data/app/views/blog/admin/post_categories/index.html.erb +45 -0
  30. data/app/views/blog/admin/post_categories/new.html.erb +10 -0
  31. data/app/views/blog/admin/post_images/_form.html.erb +8 -0
  32. data/app/views/blog/admin/post_images/edit.html.erb +17 -0
  33. data/app/views/blog/admin/post_images/index.html.erb +40 -0
  34. data/app/views/blog/admin/post_images/new.html.erb +19 -0
  35. data/app/views/blog/admin/post_products/_form.html.erb +8 -0
  36. data/app/views/blog/admin/post_products/_related_products_table.html.erb +18 -0
  37. data/app/views/blog/admin/post_products/edit.html.erb +18 -0
  38. data/app/views/blog/admin/post_products/index.html.erb +50 -0
  39. data/app/views/blog/admin/post_products/new.html.erb +21 -0
  40. data/app/views/blog/admin/posts/_form.html.erb +40 -0
  41. data/app/views/blog/admin/posts/edit.html.erb +12 -0
  42. data/app/views/blog/admin/posts/index.html.erb +54 -0
  43. data/app/views/blog/admin/posts/new.html.erb +14 -0
  44. data/app/views/blog/admin/posts/show.html.erb +17 -0
  45. data/app/views/blog/admin/shared/_post_tabs.html.erb +26 -0
  46. data/app/views/blog/post_categories/show.html.erb +12 -0
  47. data/app/views/blog/posts/archive.html.erb +13 -0
  48. data/app/views/blog/posts/index.html.erb +16 -0
  49. data/app/views/blog/posts/index.rss.builder +17 -0
  50. data/app/views/blog/posts/show.html.erb +37 -0
  51. data/app/views/blog/shared/_archive.html.erb +31 -0
  52. data/app/views/blog/shared/_disqus_comments.html.erb +20 -0
  53. data/app/views/blog/shared/_preview.html.erb +18 -0
  54. data/app/views/blog/shared/_sidebar.html.erb +26 -0
  55. data/config/locales/en.yml +77 -0
  56. data/config/routes.rb +38 -0
  57. data/lib/generators/spree_essentials/blog_generator.rb +20 -0
  58. data/lib/generators/templates/db/migrate/acts_as_taggable_on_posts.rb +32 -0
  59. data/lib/generators/templates/db/migrate/create_post_categories.rb +13 -0
  60. data/lib/generators/templates/db/migrate/create_post_categories_posts.rb +12 -0
  61. data/lib/generators/templates/db/migrate/create_post_products.rb +13 -0
  62. data/lib/generators/templates/db/migrate/create_posts.rb +18 -0
  63. data/lib/spree_essential_blog/version.rb +3 -0
  64. data/lib/spree_essential_blog.rb +34 -0
  65. data/lib/tasks/sample/sailing.jpg +0 -0
  66. data/lib/tasks/sample/sailing2.jpg +0 -0
  67. data/lib/tasks/sample/sailing3.jpg +0 -0
  68. data/lib/tasks/sample.rake +41 -0
  69. data/public/stylesheets/posts.css +65 -0
  70. data/spree_essential_blog.gemspec +32 -0
  71. data/test/dummy_hooks/after_migrate.rb.sample +1 -0
  72. data/test/dummy_hooks/before_migrate.rb +13 -0
  73. data/test/dummy_hooks/templates/admin/all.css +3 -0
  74. data/test/dummy_hooks/templates/admin/all.js +1 -0
  75. data/test/dummy_hooks/templates/store/all.css +3 -0
  76. data/test/dummy_hooks/templates/store/all.js +1 -0
  77. data/test/integration/admin/disqus_integration_test.rb +25 -0
  78. data/test/integration/admin/post_category_integration_test.rb +131 -0
  79. data/test/integration/admin/post_integration_test.rb +80 -0
  80. data/test/integration/post_category_integration_test.rb +43 -0
  81. data/test/integration/post_integration_test.rb +240 -0
  82. data/test/support/factories.rb +15 -0
  83. data/test/test_helper.rb +7 -0
  84. data/test/unit/post_category_test.rb +24 -0
  85. data/test/unit/post_test.rb +33 -0
  86. metadata +236 -0
@@ -0,0 +1,18 @@
1
+ <div class="post-preview">
2
+
3
+ <div class="post-title">
4
+ <h2><%= link_to h(post.title), post_seo_path(post) %></h2>
5
+ <h5><%= date_full(post.posted_at) %></h5>
6
+ </div>
7
+
8
+ <% if post.has_images? %>
9
+ <p class="post-images"><%= link_to image_tag(post.images.first.attachment.url, :alt => post.title), post_seo_path(post) %></p>
10
+ <% end %>
11
+
12
+ <%= post.rendered_preview %>
13
+
14
+ <br class="clear" />
15
+
16
+ <p><%= link_to t('.read_more'), post_seo_path(post) %></p>
17
+
18
+ </div>
@@ -0,0 +1,26 @@
1
+ <div class="post-sidebar">
2
+
3
+ <h3><%= t('.recent_posts') %></h3>
4
+ <%= render 'blog/shared/archive', :posts => @archive_posts %>
5
+
6
+ <p class="more"><%= link_to t('.view_archive'), archive_posts_path %></p>
7
+
8
+ <div class="post-categories">
9
+ <h3><%= t('.categories') %></h3>
10
+ <ul>
11
+ <% @post_categories.each do |category| %>
12
+ <li><%= link_to category.name, post_category_path(category.permalink) %></li>
13
+ <% end %>
14
+ </ul>
15
+ </div>
16
+
17
+ <div class="tag-cloud">
18
+ <h3><%= t('.tags') %></h3>
19
+ <ul class="tags">
20
+ <% tag_cloud @tags, %w(neat cool rad awesome) do |tag, css_class| %>
21
+ <li><%= link_to tag.name, search_posts_path(tag.name), :class => css_class %></li>
22
+ <% end %>
23
+ </ul>
24
+ </div>
25
+
26
+ </div>
@@ -0,0 +1,77 @@
1
+ en:
2
+ post:
3
+ model_name: Post
4
+ title: Title
5
+ posted_at: Posted At
6
+ body: Body
7
+ live: Published
8
+ tags: Tags
9
+ post_category:
10
+ model_name: Category
11
+ name: Name
12
+ permalink: Permalink
13
+
14
+ admin:
15
+ subnav:
16
+ posts: Posts
17
+
18
+ blog:
19
+ admin:
20
+ posts:
21
+ new:
22
+ new_post: New Post
23
+ post_products:
24
+ index:
25
+ add_related_product: Add Related Products
26
+ post_categories:
27
+ index:
28
+ manage_categories: Manage Categories
29
+ new:
30
+ new_category: New Category
31
+ edit:
32
+ edit_category: Edit Category
33
+
34
+ shared:
35
+ post_tabs:
36
+ post_details: Post Details
37
+ editing_post: Editing Post
38
+ related_products: Related Products
39
+ post_categories: Categories
40
+ comments: Comments
41
+ home:
42
+ title: Recent Posts
43
+ archive: Blog Archive
44
+ no_posts: No posts found!
45
+ posts:
46
+ index:
47
+ blog: Blog
48
+ rss: Subscribe via RSS
49
+ archive:
50
+ where_to_next: Where to next?
51
+ go_to_store: "Shop the Store"
52
+ back_to_posts: "Back to the blog"
53
+ settings:
54
+ disqus: Disqus Settings
55
+ explain_disqus: Configure Disqus Comments for Blog
56
+ disqus_shortname: Disqus Shortname
57
+ shared:
58
+ sidebar:
59
+ recent_posts: Recent Posts
60
+ categories: Categories
61
+ archives: Archive
62
+ view_archive: View Full Archive
63
+ tags: Tags
64
+ preview:
65
+ read_more: Read More
66
+ post_tabs:
67
+ editing_post: Editing Post
68
+ post_details: Post Details
69
+ related_products: Related Products
70
+ post_categories: Categories
71
+ subnav:
72
+ posts: Blog Posts
73
+
74
+
75
+ faker:
76
+ lorem:
77
+ words: [alias, consequatur, perferendis, voluptatem, accusantium, doloremque, aperiam, eaque, ipsa, quae, illo, inventore, veritatis, quasi, architecto, beatae, vitae, dicta, sunt, explicabo, aspernatur, aut, odit, aut, fugit, sed, quia, consequuntur, magni, dolores, eos, qui, ratione, voluptatem, sequi, nesciunt, neque, dolorem, ipsum, quia, dolor, sit, amet, consectetur, adipisci, velit, sed, quia, non, numquam, eius, modi, tempora, incidunt, ut, labore, et, dolore, magnam, aliquam, quaerat, voluptatem, ut, enim, ad, minima, veniam, quis, nostrum, exercitationem, ullam, corporis, nemo, enim, ipsam, voluptatem, quia, voluptas, sit, suscipit, laboriosam, nisi, ut, aliquid, ex, ea, commodi, consequatur, quis, autem, vel, eum, iure, reprehenderit, qui, in, ea, voluptate, velit, esse, quam, nihil, molestiae, et, iusto, odio, dignissimos, ducimus, qui, blanditiis, praesentium, laudantium, totam, rem, voluptatum, deleniti, atque, corrupti, quos, dolores, et, quas, molestias, excepturi, sint, occaecati, cupiditate, non, provident, sed, ut, perspiciatis, unde, omnis, iste, natus, error, similique, sunt, in, culpa, qui, officia, deserunt, mollitia, animi, id, est, laborum, et, dolorum, fuga, et, harum, quidem, rerum, facilis, est, et, expedita, distinctio, nam, libero, tempore, cum, soluta, nobis, est, eligendi, optio, cumque, nihil, impedit, quo, porro, quisquam, est, qui, minus, id, quod, maxime, placeat, facere, possimus, omnis, voluptas, assumenda, est, omnis, dolor, repellendus, temporibus, autem, quibusdam, et, aut, consequatur, vel, illum, qui, dolorem, eum, fugiat, quo, voluptas, nulla, pariatur, accusamus, officiis, debitis, aut, rerum, necessitatibus, saepe, eveniet, ut, et, voluptates, repudiandae, sint, molestiae, non, recusandae, itaque, earum, rerum, tenetur, sapiente, delectus, reiciendis, voluptatibus, maiores, doloribus, asperiores, repellat]
data/config/routes.rb ADDED
@@ -0,0 +1,38 @@
1
+ Rails.application.routes.draw do
2
+
3
+ scope(:module => "Blog") do
4
+
5
+ constraints(
6
+ :year => /\d{4}/,
7
+ :month => /\d{1,2}/,
8
+ :day => /\d{1,2}/
9
+ ) do
10
+ get '/blog/:year(/:month(/:day))' => 'posts#index', :as => :post_date
11
+ get '/blog/:year/:month/:day/:id' => 'posts#show', :as => :full_post
12
+ get '/blog/category/:id' => 'post_categories#show', :as => :post_category
13
+ end
14
+
15
+ get '/blog/search/:query', :to => 'posts#search', :as => :search_posts, :query => /.*/
16
+
17
+ resources :posts, :path => 'blog' do
18
+ get :archive, :on => :collection
19
+ end
20
+
21
+ namespace :admin do
22
+
23
+ resources :posts do
24
+ resources :images, :controller => "post_images" do
25
+ collection do
26
+ post :update_positions
27
+ end
28
+ end
29
+ resources :products, :controller => "post_products"
30
+ resources :categories, :controller => "post_categories"
31
+ end
32
+
33
+ resource :disqus_settings
34
+
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ require 'generators/essentials_base'
2
+
3
+ module SpreeEssentials
4
+ module Generators
5
+ class BlogGenerator < SpreeEssentials::Generators::EssentialsBase
6
+
7
+ desc "Installs required migrations for spree_essentials_blog"
8
+ source_root File.expand_path("../../templates/db/migrate", __FILE__)
9
+
10
+ def copy_migrations
11
+ migration_template "create_posts.rb", "db/migrate/create_posts.rb"
12
+ migration_template "create_post_products.rb", "db/migrate/create_post_products.rb"
13
+ migration_template "acts_as_taggable_on_posts.rb", "db/migrate/acts_as_taggable_on_posts.rb"
14
+ migration_template "create_post_categories.rb", "db/migrate/create_post_categories.rb"
15
+ migration_template "create_post_categories_posts.rb", "db/migrate/create_post_categories_posts.rb"
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ class ActsAsTaggableOnPosts < ActiveRecord::Migration
2
+ def self.up
3
+ return if table_exists? :tags
4
+
5
+ create_table :tags do |t|
6
+ t.string :name
7
+ end
8
+
9
+ create_table :taggings do |t|
10
+ t.references :tag
11
+
12
+ # You should make sure that the column created is
13
+ # long enough to store the required class names.
14
+ t.references :taggable, :polymorphic => true
15
+ t.references :tagger, :polymorphic => true
16
+
17
+ t.string :context
18
+
19
+ t.datetime :created_at
20
+ end
21
+
22
+ add_index :taggings, :tag_id
23
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
24
+ end
25
+
26
+ def self.down
27
+ return unless table_exists? :tags
28
+ drop_table :tags
29
+ drop_table :taggings
30
+ end
31
+
32
+ end
@@ -0,0 +1,13 @@
1
+ class CreatePostCategories < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :post_categories, :force => true do |t|
4
+ t.string :name
5
+ t.string :permalink
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :post_categories
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ class CreatePostCategoriesPosts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :post_categories_posts, :id => false, :force => true do |t|
4
+ t.integer :post_id
5
+ t.integer :post_category_id
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :post_categories_posts
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class CreatePostProducts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :post_products do |t|
4
+ t.references :post
5
+ t.references :product
6
+ t.integer :position
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :post_products
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ class CreatePosts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :posts do |t|
4
+ t.string :title, :required => true
5
+ t.string :path, :required => true
6
+ t.string :teaser
7
+ t.datetime :posted_at
8
+ t.text :body
9
+ t.string :author
10
+ t.boolean :live, :default => true
11
+ t.timestamps
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :posts
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module SpreeEssentialBlog
2
+ VERSION = "0.1.0.rc1"
3
+ end
@@ -0,0 +1,34 @@
1
+ require 'spree_essentials'
2
+ require 'acts-as-taggable-on'
3
+
4
+ module SpreeEssentialBlog
5
+
6
+ def self.tab
7
+ { :label => "Posts", :route => :admin_posts }
8
+ end
9
+
10
+ def self.sub_tab
11
+ [:posts, { :label => 'admin.subnav.posts', :match_path => '/posts' }]
12
+ end
13
+
14
+ class Engine < Rails::Engine
15
+
16
+ config.autoload_paths += %W(#{config.root}/lib)
17
+
18
+ config.to_prepare do
19
+ #loads application's model / class decorators
20
+ Dir.glob File.expand_path("../../app/**/*_decorator*.rb") do |c|
21
+ Rails.configuration.cache_classes ? require(c) : load(c)
22
+ end
23
+
24
+ #loads application's deface view overrides
25
+ Dir.glob File.expand_path("../../app/overrides/*.rb", __FILE__) do |c|
26
+ Rails.application.config.cache_classes ? require(c) : load(c)
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ SpreeEssentials.register :blog, SpreeEssentialBlog
Binary file
Binary file
Binary file
@@ -0,0 +1,41 @@
1
+ namespace :db do
2
+ namespace :sample do
3
+ desc "creates sample blog posts"
4
+ task :blog do
5
+
6
+ require 'faker'
7
+ require Rails.root.join('config/environment.rb')
8
+
9
+ image_dir = File.expand_path("../sample", __FILE__)
10
+ images = Dir[image_dir + "/*.jpg"]
11
+
12
+ product_ids = Product.select('id').all.collect(&:id) rescue []
13
+
14
+ 25.times { |i|
15
+
16
+ post = Post.create(
17
+ :title => Faker::Lorem.sentence,
18
+ :posted_at => Time.now - i * rand(10000000),
19
+ :body => Faker::Lorem.paragraph,
20
+ :tag_list => Faker::Lorem.words(rand(10)).join(", ")
21
+ )
22
+
23
+ rand(5).times { |i|
24
+ image = post.images.create(:attachment => File.open(images.sort_by{rand}.first), :alt => Faker::Lorem.sentence)
25
+ }
26
+
27
+ unless product_ids.empty?
28
+ rand(5).times { |i|
29
+ post.post_products.create(:product => Product.find(product_ids.sort_by{rand}.first), :position => i)
30
+ }
31
+ end
32
+
33
+ print "*"
34
+
35
+ }
36
+
37
+ puts "\ndone."
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,65 @@
1
+ /* ==========================================
2
+ Post Archive
3
+ */
4
+
5
+ .posts {
6
+ position: relative;
7
+ }
8
+
9
+ #posts-rss {
10
+ display: block;
11
+ position: absolute;
12
+ left: 0;
13
+ bottom: 4px;
14
+ line-height: 16px;
15
+ text-decoration: none;
16
+ img {
17
+ display: block;
18
+ float: left;
19
+ margin-right: 5px;
20
+ }
21
+ }
22
+
23
+ .post-archive ul.archive {
24
+ list-style-type: none;
25
+ text-decoration: none;
26
+ margin: 0;
27
+ }
28
+ .post-archive h4.year,
29
+ .post-archive h5.month,
30
+ .post-archive ul.archive li span.day {
31
+ display: block;
32
+ position: relative;
33
+ border-bottom: 1px solid #ccc;
34
+ font-size: 17px;
35
+ font-weight: normal;
36
+ margin: 0 0 0.5em 0;
37
+ }
38
+ .post-archive ul.archive li ul.posts {
39
+ list-style-type: none;
40
+ display: block;
41
+ float: left;
42
+ width: 90%;
43
+ margin: 0 0 1em 0;
44
+ padding: 0;
45
+ }
46
+ .post-archive ul.archive li ul.posts li {
47
+ margin: 0 0 0.5em 0;
48
+ }
49
+
50
+
51
+ /* ==========================================
52
+ Post Preview
53
+ */
54
+
55
+ .post-preview {
56
+ clear: both;
57
+ padding-bottom: 1em;
58
+ border-bottom: 1px solid #ccc;
59
+ }
60
+ .post-preview h2 {
61
+ margin-bottom: 0;
62
+ }
63
+ .post-comments {
64
+ clear: both;
65
+ }
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "spree_essential_blog/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "spree_essential_blog"
7
+ s.version = SpreeEssentialBlog::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Spencer Steffen"]
10
+ s.email = ["spencer@citrusme.com"]
11
+ s.homepage = "https://github.com/citrus/spree_essential_blog"
12
+ s.summary = %q{Spree Essential Blog is a blog plugin for Spree sites equipped with spree_essentials.}
13
+ s.description = %q{Spree Essential Blog is a blog plugin for Spree sites equipped with spree_essentials.}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+
18
+ s.require_paths = ["lib"]
19
+
20
+ # Runtime
21
+ s.add_dependency('spree_essentials', '>= 0.3.1')
22
+ s.add_dependency('acts-as-taggable-on', '>= 2.2.0')
23
+
24
+ # Development
25
+ s.add_development_dependency('shoulda', '>= 3.0.0.beta2')
26
+ s.add_development_dependency('dummier', '>= 0.2.4')
27
+ s.add_development_dependency('factory_girl', '>= 2.3.2')
28
+ s.add_development_dependency('capybara', '>= 1.1.2')
29
+ s.add_development_dependency('selenium-webdriver', '>= 2.15.0')
30
+ s.add_development_dependency('sqlite3', '>= 1.3.5')
31
+
32
+ end
@@ -0,0 +1 @@
1
+ rake "db:migrate db:seed db:sample:blog", :env => "development"
@@ -0,0 +1,13 @@
1
+ run "bundle exec rails g spree:site"
2
+ run "bundle exec rails g spree_essentials:install"
3
+ run "bundle exec rails g spree_essentials:blog"
4
+
5
+ # remove all stylesheets except core
6
+ %w(admin store).each do |ns|
7
+ js = "app/assets/javascripts/#{ns}/all.js"
8
+ css = "app/assets/stylesheets/#{ns}/all.css"
9
+ remove_file js
10
+ remove_file css
11
+ template "#{ns}/all.js", js
12
+ template "#{ns}/all.css", css
13
+ end
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require admin/spree_core
3
+ */
@@ -0,0 +1 @@
1
+ //= require admin/spree_core
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require store/spree_core
3
+ */
@@ -0,0 +1 @@
1
+ //= require store/spree_core
@@ -0,0 +1,25 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require 'test_helper'
5
+
6
+ class Admin::DisqusIntegrationTest < ActiveSupport::IntegrationCase
7
+
8
+ should "have a link to disqus config" do
9
+ visit admin_configurations_path
10
+ within "#content table.index" do
11
+ assert has_link?("Disqus Settings", :href => edit_admin_disqus_settings_path)
12
+ end
13
+ end
14
+
15
+ should "edit disqus config" do
16
+ visit edit_admin_disqus_settings_path
17
+ within "form.edit_blog_configuration" do
18
+ fill_in "Disqus Shortname", :with => "its-just-a-test"
19
+ click_button "Update"
20
+ end
21
+ assert_equal current_path, admin_disqus_settings_path
22
+ assert_seen "its-just-a-test", :within => "#content .member-list h3"
23
+ end
24
+
25
+ end
@@ -0,0 +1,131 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require 'test_helper'
5
+
6
+ class Admin::PostCategoryIntegrationTest < ActiveSupport::IntegrationCase
7
+
8
+ #include Blog::PostsHelper
9
+
10
+ def setup
11
+ Post.destroy_all
12
+ PostCategory.destroy_all
13
+ @post = Factory.create(:post)
14
+ @category = Factory.create(:post_category)
15
+ end
16
+
17
+ should "have a link to post categories" do
18
+ visit admin_post_path(@post)
19
+ within ".sidebar.post-menu" do
20
+ assert has_link?("Categories")
21
+ end
22
+ end
23
+
24
+ should "get the post categories index" do
25
+ visit admin_post_categories_path(@post)
26
+ assert_seen "Categories", :within => ".sidebar.post-menu li.active"
27
+ assert_seen "Manage Categories", :within => ".edit_post legend"
28
+ assert_seen @category.name, :within => "tr#post_category_#{@category.id} td label"
29
+ assert has_selector?("button[type=submit]")
30
+ assert has_selector?("a#btn_new_category")
31
+ end
32
+
33
+ should "add a new post category" do
34
+ visit admin_post_categories_path(@post)
35
+ click_link "btn_new_category"
36
+ fill_in "Name", :with => "Just a Category"
37
+ fill_in "Permalink", :with => "just-a-category"
38
+ click_button "Create"
39
+ @category = PostCategory.last
40
+ assert_equal admin_post_categories_path(@post), current_path
41
+ assert_flash :notice, %(Post category "#{@category.name}" has been successfully created!)
42
+ assert_seen @category.name, :within => "tr#post_category_#{@category.id} td label"
43
+ end
44
+
45
+ should "edit existing post category" do
46
+ visit edit_admin_post_category_path(@post, @category.id)
47
+ assert_equal @category.name, find_field("Name").value
48
+ assert_equal @category.permalink, find_field("Permalink").value
49
+ fill_in "Name", :with => "Not just a Category"
50
+ fill_in "Permalink", :with => "not-just-a-category"
51
+ click_button "Update"
52
+ assert_equal admin_post_categories_path(@post), current_path
53
+ assert_flash :notice, %(Post category "Not just a Category" has been successfully updated!)
54
+ assert_seen "Not just a Category", :within => "tr#post_category_#{@category.id} td label"
55
+ end
56
+
57
+ should "destroy the post category" do
58
+ visit admin_post_categories_path(@post)
59
+ find("tr#post_category_#{@category.id} td.options a[href='#']").click
60
+ assert find_by_id("popup_ok").click
61
+ end
62
+
63
+ should "link a post category" do
64
+ visit admin_post_categories_path(@post)
65
+ assert !field_labeled(@category.name).checked?
66
+ check @category.name
67
+ click_button "Update"
68
+ assert field_labeled(@category.name).checked?
69
+ assert_equal admin_post_categories_path(@post), current_path
70
+ assert_flash :notice, %(Post "#{@post.title}" has been successfully updated!)
71
+ end
72
+
73
+ should "unlink a post category" do
74
+ @post.categories << @category
75
+ @post.save
76
+ visit admin_post_categories_path(@post.reload)
77
+ assert field_labeled(@category.name).checked?
78
+ uncheck @category.name
79
+ click_button "Update"
80
+ assert_equal admin_post_categories_path(@post), current_path
81
+ assert !field_labeled(@category.name).checked?
82
+ assert_flash :notice, %(Post "#{@post.title}" has been successfully updated!)
83
+ end
84
+
85
+ context "with multiple categories" do
86
+
87
+ setup do
88
+ PostCategory.destroy_all
89
+ @categories = %w(one two three four five).map{|i| Factory.create(:post_category, :name => i) }
90
+ end
91
+
92
+ should "link a multiple post categories" do
93
+ visit admin_post_categories_path(@post)
94
+ @categories.each do |category|
95
+ assert !field_labeled(category.name).checked?
96
+ end
97
+ @categories.take(3).each do |category|
98
+ check category.name
99
+ end
100
+ click_button "Update"
101
+ @categories.take(3).each do |category|
102
+ assert field_labeled(category.name).checked?
103
+ end
104
+ @categories.slice(3, 2).each do |category|
105
+ assert !field_labeled(category.name).checked?
106
+ end
107
+ assert_equal admin_post_categories_path(@post), current_path
108
+ assert_flash :notice, %(Post "#{@post.title}" has been successfully updated!)
109
+ end
110
+
111
+ should "unlink multiple post category" do
112
+ @post.categories = @categories.take(3)
113
+ @post.save
114
+ visit admin_post_categories_path(@post.reload)
115
+ @categories.take(3).each do |category|
116
+ assert field_labeled(category.name).checked?
117
+ end
118
+ @categories.take(3).each do |category|
119
+ uncheck category.name
120
+ end
121
+ click_button "Update"
122
+ @categories.each do |category|
123
+ assert !field_labeled(category.name).checked?
124
+ end
125
+ assert_equal admin_post_categories_path(@post), current_path
126
+ assert_flash :notice, %(Post "#{@post.title}" has been successfully updated!)
127
+ end
128
+
129
+ end
130
+
131
+ end