mist 0.6.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 (147) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +192 -0
  7. data/README.md +108 -0
  8. data/Rakefile +9 -0
  9. data/app/assets/images/mist/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  10. data/app/assets/images/mist/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  11. data/app/assets/images/mist/ui-bg_flat_10_000000_40x100.png +0 -0
  12. data/app/assets/images/mist/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  13. data/app/assets/images/mist/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  14. data/app/assets/images/mist/ui-bg_glass_65_ffffff_1x400.png +0 -0
  15. data/app/assets/images/mist/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  16. data/app/assets/images/mist/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  17. data/app/assets/images/mist/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  18. data/app/assets/images/mist/ui-icons_222222_256x240.png +0 -0
  19. data/app/assets/images/mist/ui-icons_228ef1_256x240.png +0 -0
  20. data/app/assets/images/mist/ui-icons_ef8c08_256x240.png +0 -0
  21. data/app/assets/images/mist/ui-icons_ffd27a_256x240.png +0 -0
  22. data/app/assets/images/mist/ui-icons_ffffff_256x240.png +0 -0
  23. data/app/assets/javascripts/mist/jquery-ui-1.8.17.custom.min.js +356 -0
  24. data/app/assets/javascripts/mist/posts.js.coffee +3 -0
  25. data/app/assets/javascripts/mist_core.js +3 -0
  26. data/app/assets/stylesheets/mist/posts.css.sass +97 -0
  27. data/app/assets/stylesheets/mist/scaffolds.css.scss +56 -0
  28. data/app/assets/stylesheets/mist/ui-lightness/jquery-ui-1.8.17.custom.css +565 -0
  29. data/app/assets/stylesheets/mist_core.css +4 -0
  30. data/app/controllers/application_controller.rb +3 -0
  31. data/app/controllers/mist/posts_controller.rb +130 -0
  32. data/app/helpers/mist/posts_helper.rb +61 -0
  33. data/app/mailers/.gitkeep +0 -0
  34. data/app/models/.gitkeep +0 -0
  35. data/app/models/mist/post.rb +240 -0
  36. data/app/models/mist/post_sweeper.rb +63 -0
  37. data/app/views/layouts/mist/posts.html.erb +66 -0
  38. data/app/views/mist/posts/_form.html.erb +55 -0
  39. data/app/views/mist/posts/_post.html.erb +19 -0
  40. data/app/views/mist/posts/_sidebar_title.html.erb +5 -0
  41. data/app/views/mist/posts/edit.html.erb +16 -0
  42. data/app/views/mist/posts/feed.atom.builder +17 -0
  43. data/app/views/mist/posts/index.html.erb +31 -0
  44. data/app/views/mist/posts/new.html.erb +15 -0
  45. data/app/views/mist/posts/show.html.erb +3 -0
  46. data/config/cucumber.yml +8 -0
  47. data/config/environment.rb +1 -0
  48. data/config/routes.rb +7 -0
  49. data/features/atom_feed.feature +20 -0
  50. data/features/authorize_create_post.feature +14 -0
  51. data/features/authorize_destroy_post.feature +27 -0
  52. data/features/authorize_update_post.feature +28 -0
  53. data/features/authorize_view_unpublished.feature +22 -0
  54. data/features/create_post.feature +13 -0
  55. data/features/destroy_post.feature +13 -0
  56. data/features/format_with_markdown.feature +13 -0
  57. data/features/popular_posts.feature +35 -0
  58. data/features/recent_posts.feature +28 -0
  59. data/features/similar_posts.feature +43 -0
  60. data/features/step_definitions/authorization_steps.rb +17 -0
  61. data/features/step_definitions/filesystem_steps.rb +13 -0
  62. data/features/step_definitions/page_steps.rb +43 -0
  63. data/features/step_definitions/post_steps.rb +58 -0
  64. data/features/step_definitions/sidebar_steps.rb +21 -0
  65. data/features/support/env.rb +58 -0
  66. data/features/support/setup.rb +15 -0
  67. data/features/update_post.feature +19 -0
  68. data/gemfiles/common +20 -0
  69. data/gemfiles/rails-3.1.3 +4 -0
  70. data/gemfiles/rails-3.1.3.lock +195 -0
  71. data/gemfiles/rails-3.2.0 +4 -0
  72. data/lib/generators/mist/USAGE +13 -0
  73. data/lib/generators/mist/setup_generator.rb +21 -0
  74. data/lib/generators/mist/templates/initializer.rb +17 -0
  75. data/lib/generators/mist/templates/mist.css.scss +2 -0
  76. data/lib/generators/mist/templates/mist.js.coffee +1 -0
  77. data/lib/generators/mist/views_generator.rb +11 -0
  78. data/lib/mist.rb +26 -0
  79. data/lib/mist/code_example_parser.rb +86 -0
  80. data/lib/mist/configuration.rb +68 -0
  81. data/lib/mist/configuration/author.rb +8 -0
  82. data/lib/mist/engine.rb +12 -0
  83. data/lib/mist/git_file_system_history.rb +66 -0
  84. data/lib/mist/git_model.rb +154 -0
  85. data/lib/mist/git_model/attributes.rb +21 -0
  86. data/lib/mist/git_model/class_methods.rb +141 -0
  87. data/lib/mist/permalink.rb +5 -0
  88. data/lib/mist/repository.rb +15 -0
  89. data/lib/mist/version.rb +8 -0
  90. data/mist.gemspec +33 -0
  91. data/spec/controllers/posts_controller_spec.rb +263 -0
  92. data/spec/dummy_rails_app/app/assets/javascripts/mist.js.coffee +1 -0
  93. data/spec/dummy_rails_app/app/assets/stylesheets/mist.css.scss +2 -0
  94. data/spec/dummy_rails_app/app/views/layouts/mist/posts.html.erb +60 -0
  95. data/spec/dummy_rails_app/config.ru +4 -0
  96. data/spec/dummy_rails_app/config/application.rb +48 -0
  97. data/spec/dummy_rails_app/config/boot.rb +7 -0
  98. data/spec/dummy_rails_app/config/database.yml +28 -0
  99. data/spec/dummy_rails_app/config/environment.rb +5 -0
  100. data/spec/dummy_rails_app/config/environments/development.rb +32 -0
  101. data/spec/dummy_rails_app/config/environments/production.rb +60 -0
  102. data/spec/dummy_rails_app/config/environments/test.rb +42 -0
  103. data/spec/dummy_rails_app/config/initializers/active_gist_credentials.rb +8 -0
  104. data/spec/dummy_rails_app/config/initializers/backtrace_silencers.rb +7 -0
  105. data/spec/dummy_rails_app/config/initializers/inflections.rb +10 -0
  106. data/spec/dummy_rails_app/config/initializers/mime_types.rb +5 -0
  107. data/spec/dummy_rails_app/config/initializers/mist.rb +17 -0
  108. data/spec/dummy_rails_app/config/initializers/secret_token.rb +7 -0
  109. data/spec/dummy_rails_app/config/initializers/session_store.rb +8 -0
  110. data/spec/dummy_rails_app/config/initializers/wrap_parameters.rb +14 -0
  111. data/spec/dummy_rails_app/config/locales/en.yml +5 -0
  112. data/spec/dummy_rails_app/config/routes.rb +3 -0
  113. data/spec/dummy_rails_app/db/schema.rb +22 -0
  114. data/spec/dummy_rails_app/db/seeds.rb +7 -0
  115. data/spec/dummy_rails_app/doc/README_FOR_APP +2 -0
  116. data/spec/dummy_rails_app/lib/assets/.gitkeep +0 -0
  117. data/spec/dummy_rails_app/lib/tasks/.gitkeep +0 -0
  118. data/spec/dummy_rails_app/lib/tasks/cucumber.rake +65 -0
  119. data/spec/dummy_rails_app/public/404.html +26 -0
  120. data/spec/dummy_rails_app/public/422.html +26 -0
  121. data/spec/dummy_rails_app/public/500.html +26 -0
  122. data/spec/dummy_rails_app/public/favicon.ico +0 -0
  123. data/spec/dummy_rails_app/public/robots.txt +5 -0
  124. data/spec/dummy_rails_app/script/cucumber +10 -0
  125. data/spec/dummy_rails_app/script/rails +6 -0
  126. data/spec/dummy_rails_app/vendor/assets/stylesheets/.gitkeep +0 -0
  127. data/spec/dummy_rails_app/vendor/plugins/.gitkeep +0 -0
  128. data/spec/factories/posts.rb +8 -0
  129. data/spec/fixtures/gist_404 +6 -0
  130. data/spec/fixtures/gist_with_1_code_example +66 -0
  131. data/spec/helpers/posts_helper_spec.rb +64 -0
  132. data/spec/lib/mist/code_example_parser_spec.rb +135 -0
  133. data/spec/lib/mist/configuration_spec.rb +88 -0
  134. data/spec/lib/mist/permalink_spec.rb +17 -0
  135. data/spec/lib/mist/repository_spec.rb +20 -0
  136. data/spec/models/mist/git_model_spec.rb +260 -0
  137. data/spec/models/mist/post_spec.rb +575 -0
  138. data/spec/requests/posts_caching_spec.rb +152 -0
  139. data/spec/spec_helper.rb +20 -0
  140. data/spec/support/cache_helpers.rb +71 -0
  141. data/spec/support/config.rb +42 -0
  142. data/spec/support/fakeweb.rb +3 -0
  143. data/spec/views/mist/posts/edit.html.erb_spec.rb +11 -0
  144. data/spec/views/mist/posts/index.html.erb_spec.rb +27 -0
  145. data/spec/views/mist/posts/new.html.erb_spec.rb +15 -0
  146. data/spec/views/mist/posts/show.html.erb_spec.rb +11 -0
  147. metadata +371 -0
@@ -0,0 +1,21 @@
1
+ class Mist::GitModel::Attributes < HashWithIndifferentAccess
2
+ def initialize(model)
3
+ @model = model
4
+ super()
5
+ end
6
+
7
+ def []=(key, value)
8
+ @model.send(:"#{key}_will_change!") unless !@model || value == self[key]
9
+ super
10
+ end
11
+
12
+ # Yamlers using Psych will call this method, we just delegate it into
13
+ # `HashWithIndifferentAccess`. If we don't, the yaml tag will be
14
+ # "!ruby/object:Mist::GitModel::Attributes" so that when the record
15
+ # is deserialized, this class will be instantiated, resulting in an
16
+ # error. (This class should only be instantiated directly by
17
+ # `Mist::GitModel`.)
18
+ def to_yaml(*args)
19
+ HashWithIndifferentAccess.new(self).to_yaml(*args)
20
+ end
21
+ end
@@ -0,0 +1,141 @@
1
+ module Mist::GitModel::ClassMethods
2
+ def self.extended(base) #:nodoc:
3
+ base.class_attribute :default_attributes
4
+ base.default_attributes ||= HashWithIndifferentAccess.new
5
+ end
6
+
7
+ # this is necessary because without it default_attributes will be
8
+ # inherited and shared across all subclasses of base, which we
9
+ # don't exactly want.
10
+ def inherited(subclass) #:nodoc:
11
+ if subclass.default_attributes
12
+ subclass.default_attributes = subclass.default_attributes.dup
13
+ else
14
+ subclass.default_attributes = HashWithIndifferentAccess.new
15
+ end
16
+ end
17
+
18
+ def timestamps
19
+ attribute :created_at, :default => proc { Time.now }
20
+ attribute :updated_at, :default => proc { Time.now }
21
+ before_save { |record| record.updated_at = Time.now }
22
+ end
23
+
24
+ def attribute(name, options = {})
25
+ name = name.to_sym
26
+ default_attributes[name] = options[:default]
27
+ define_attribute_methods [name.to_s]
28
+ add_attribute_default(name, options)
29
+ add_attribute_getter(name)
30
+ add_attribute_setter(name)
31
+ end
32
+
33
+ def add_attribute_getter(name)
34
+ define_method(name) do # def id
35
+ attributes[name] # attributes[:id]
36
+ end # end
37
+ end
38
+
39
+ def add_attribute_setter(name)
40
+ define_method(:"#{name}=") do |value| # def id=(value)
41
+ unless value == attributes[name] # unless value == attributes[:id]
42
+ attributes[name] = value # attributes[:id] = value
43
+ end # end
44
+ end
45
+ end
46
+
47
+ def add_attribute_default(name, options)
48
+ define_method(:"default_#{name}") do # def default_id
49
+ if options[:default].kind_of?(Proc) # if options[:default].kind_of?(Proc)
50
+ options[:default].call # options[:default].call
51
+ else # else
52
+ options[:default] # options[:default]
53
+ end # end
54
+ end # end
55
+ end
56
+
57
+ def table_name
58
+ if name =~ /GitModel/
59
+ raise
60
+ end
61
+ name.underscore.pluralize
62
+ end
63
+
64
+ # Returns meta data for this model.
65
+ def [](type)
66
+ @meta ||= {}
67
+ @meta[type] ||= if File.file?(meta_file_path(type))
68
+ YAML.load(File.read(meta_file_path(type))) || {}
69
+ else
70
+ {}
71
+ end.with_indifferent_access
72
+ end
73
+
74
+ # Assigns, saves and commits meta data for this model.
75
+ def save_meta_data(type)
76
+ FileUtils.mkdir_p File.dirname(meta_file_path(type))
77
+ File.open(meta_file_path(type), 'w') { |f| f.print self[type].to_yaml }
78
+ if Mist.commit_meta_data
79
+ Mist.repository.add meta_file_path(type)
80
+ Mist.repository.commit '%s meta changes to %s' % [type, table_name]
81
+ end
82
+
83
+ # we must force meta to be reloaded because otherwise it could get out of sync with filesystem
84
+ @meta = nil
85
+ end
86
+
87
+ def meta_file_path(type)
88
+ Mist.repository_location.join('.meta', table_name, type.to_s)
89
+ end
90
+
91
+ def all
92
+ # it's dangerous to rely on Dir[] because we have no guarantee of the
93
+ # returned order. Git will be more reliable.
94
+ files = Mist::GitFileSystemHistory.new(Mist.repository).find(nil, /^#{Regexp::escape table_name}\/?/)
95
+ files.collect! { |path| load Mist.repository_location.join(path) }
96
+ end
97
+
98
+ def load(path, attributes = {})
99
+ # id is always the filename, ensure id isn't changed by yaml
100
+ attributes = attributes.with_indifferent_access.reverse_merge(YAML.load(File.read(path)))
101
+ attributes['id'] = File.basename(path)
102
+ new(attributes).tap do |instance|
103
+ instance.changed_attributes.clear
104
+ end
105
+ end
106
+
107
+ def record_path(id)
108
+ Mist.repository_location.join(table_name, id.to_s)
109
+ end
110
+
111
+ def find(id, new_attributes = {})
112
+ if path = exist?(id)
113
+ load path, new_attributes
114
+ else
115
+ nil
116
+ end
117
+ end
118
+
119
+ # If the id exists, its file path is returned. Otherwise, nil.
120
+ def exist?(id)
121
+ path = record_path(id)
122
+ File.exist?(path) ? path : nil
123
+ end
124
+
125
+ def last(count = nil)
126
+ files = Mist::GitFileSystemHistory.new(Mist.repository).find(count || 1, /^#{Regexp::escape table_name}\/?/)
127
+ files.collect! { |path| load Mist.repository_location.join(path) }
128
+ count.nil? ? files.first : files
129
+ end
130
+
131
+ def create!(attributes = {})
132
+ new(attributes).tap do |record|
133
+ record.save!
134
+ end
135
+ end
136
+
137
+ def count
138
+ Dir[Mist.repository_location.join(table_name, '*')].length
139
+ end
140
+ end
141
+
@@ -0,0 +1,5 @@
1
+ module Mist::Permalink
2
+ def permalink(text)
3
+ text.underscore.gsub(/[^a-zA-Z0-9]+/, '-').sub(/-$/, '')
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ module Mist::Repository
2
+ def repository
3
+ @repository ||= begin
4
+ if File.directory? Mist.repository_location.join('.git')
5
+ Git.open(Mist.repository_location.to_s, :log => Rails.logger)
6
+ else
7
+ Git.init(Mist.repository_location.to_s, :log => Rails.logger)
8
+ end
9
+ end
10
+ end
11
+
12
+ def reload_repository!
13
+ @repository = nil
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module Mist
2
+ module Version
3
+ MAJOR, MINOR, PATCH = 0, 6, 0
4
+ STRING = [MAJOR, MINOR, PATCH].join('.')
5
+ end
6
+
7
+ VERSION = Version::STRING
8
+ end
data/mist.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mist/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mist"
7
+ s.version = Mist::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Colin MacKenzie IV"]
10
+ s.email = ["sinisterchipmunk@gmail.com"]
11
+ s.homepage = "http://github.com/sinisterchipmunk/mist"
12
+ s.summary = %q{a git-powered, gist-backed blogging engine for Rails 3}
13
+ s.description = %q{a git-powered, gist-backed blogging engine for Rails 3}
14
+
15
+ s.add_dependency 'git', '~> 1.2'
16
+ s.add_dependency 'github-markup', '~> 0.7'
17
+ s.add_dependency 'redcarpet', '~> 2.0'
18
+ s.add_dependency 'activegist', '~> 0.6'
19
+
20
+ s.add_development_dependency 'cucumber-rails', '~> 1.2.1'
21
+ s.add_development_dependency 'database_cleaner', '~> 0.7.0'
22
+ s.add_development_dependency 'rspec-rails', '~> 2.8.1'
23
+ s.add_development_dependency 'fakeweb', '~> 1.3.0'
24
+ # v1.5.0 has gemspec errors under ree, so force v1.4.0 until that's fixed
25
+ s.add_development_dependency 'factory_girl_rails', '= 1.4.0'
26
+
27
+ s.rubyforge_project = "mist"
28
+
29
+ s.files = `git ls-files`.split("\n")
30
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
+ s.require_paths = ["lib"]
33
+ end
@@ -0,0 +1,263 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mist::PostsController do
4
+ before { Mist.authorize :all do true end }
5
+
6
+ # This should return the minimal set of attributes required to create a valid
7
+ # Post. As you add validations to Post, be sure to
8
+ # update the return value of this method accordingly.
9
+ def valid_attributes
10
+ attributes_for :post
11
+ end
12
+
13
+ # This should return the minimal set of values that should be in the session
14
+ # in order to pass any filters (e.g. authentication) defined in
15
+ # PostsController. Be sure to keep this updated too.
16
+ def valid_session
17
+ {}
18
+ end
19
+
20
+ describe "GET feed .rss" do
21
+ it "redirects to feed .atom" do
22
+ get :feed, {:format => :rss}, valid_session
23
+ response.should redirect_to(feed_posts_path :format => :atom)
24
+ end
25
+ end
26
+
27
+ describe "GET index" do
28
+ it "assigns all posts as @posts" do
29
+ post = create :post, :published_at => Time.now
30
+ get :index, {:use_route => :mist}, valid_session
31
+ assigns(:posts).should eq([post])
32
+ end
33
+ end
34
+
35
+ describe "GET show" do
36
+ describe "draft while unauthorized" do
37
+ before { Mist.authorize(:view_drafts) { false } }
38
+
39
+ it "does not assign the requested post as @post" do
40
+ post = Mist::Post.create! valid_attributes
41
+ get :show, {:id => post.to_param}, valid_session
42
+ assigns(:post).should eq(post)
43
+ end
44
+
45
+ it "does not increment the post popularity" do
46
+ post = Mist::Post.create! valid_attributes
47
+ popularity = post.popularity
48
+ get :show, {:id => post.to_param}, valid_session
49
+ popularity.should == Mist::Post.popularity_for(post.id)
50
+ end
51
+
52
+ it "redirects out" do
53
+ post = Mist::Post.create! valid_attributes
54
+ get :show, {:id => post.to_param}, valid_session
55
+ response.should redirect_to(posts_path)
56
+ end
57
+ end
58
+
59
+ it "assigns the requested post as @post" do
60
+ post = Mist::Post.create! valid_attributes.merge(:published => true)
61
+ get :show, {:id => post.to_param}, valid_session
62
+ assigns(:post).should eq(post)
63
+ end
64
+
65
+ it "increments the post popularity" do
66
+ post = Mist::Post.create! valid_attributes.merge(:published_at => Time.now)
67
+ popularity = post.popularity
68
+ get :show, {:id => post.to_param}, valid_session
69
+ popularity.should be < Mist::Post.popularity_for(post.id)
70
+ end
71
+ end
72
+
73
+ describe "GET new" do
74
+ describe "while unauthorized" do
75
+ before { Mist.authorize(:create_post) { false } }
76
+
77
+ it "should redirect" do
78
+ post = Mist::Post.create! valid_attributes
79
+ get :new, {}, valid_session
80
+ response.status.should redirect_to(posts_path)
81
+ end
82
+ end
83
+
84
+ it "assigns a new post as @post" do
85
+ get :new, {}, valid_session
86
+ assigns(:post).should be_a_new(Mist::Post)
87
+ end
88
+ end
89
+
90
+ describe "GET edit" do
91
+ describe "while unauthorized" do
92
+ before { Mist.authorize(:update_post) { false } }
93
+
94
+ it "should redirect" do
95
+ post = Mist::Post.create! valid_attributes
96
+ get :edit, {:id => post.to_param}, valid_session
97
+ response.status.should redirect_to(posts_path)
98
+ end
99
+ end
100
+
101
+ it "assigns the requested post as @post" do
102
+ post = Mist::Post.create! valid_attributes
103
+ get :edit, {:id => post.to_param}, valid_session
104
+ assigns(:post).should eq(post)
105
+ end
106
+ end
107
+
108
+ describe "POST create" do
109
+ describe "while unauthorized" do
110
+ before { Mist.authorize(:create_post) { false } }
111
+
112
+ it "should not create a new post" do
113
+ expect {
114
+ post :create, {:post => valid_attributes}, valid_session
115
+ }.to_not change(Mist::Post, :count).by(1)
116
+ end
117
+
118
+ it "should not assign post" do
119
+ post :create, {:post => valid_attributes}, valid_session
120
+ assigns(:post).should_not be_a(Mist::Post)
121
+ end
122
+
123
+ it "should redirect out" do
124
+ post :create, {:post => valid_attributes}, valid_session
125
+ response.should redirect_to(posts_path)
126
+ end
127
+ end
128
+
129
+ describe "with valid params" do
130
+ it "creates a new Post" do
131
+ expect {
132
+ post :create, {:post => valid_attributes}, valid_session
133
+ }.to change(Mist::Post, :count).by(1)
134
+ end
135
+
136
+ it "assigns a newly created post as @post" do
137
+ post :create, {:post => valid_attributes}, valid_session
138
+ assigns(:post).should be_a(Mist::Post)
139
+ assigns(:post).should be_persisted
140
+ end
141
+
142
+ it "redirects to the created post" do
143
+ post :create, {:post => valid_attributes}, valid_session
144
+ response.should redirect_to(Mist::Post.last)
145
+ end
146
+ end
147
+
148
+ describe "with invalid params" do
149
+ it "assigns a newly created but unsaved post as @post" do
150
+ # Trigger the behavior that occurs when invalid params are submitted
151
+ Mist::Post.any_instance.stub(:save).and_return(false)
152
+ post :create, {:post => {}}, valid_session
153
+ assigns(:post).should be_a_new(Mist::Post)
154
+ end
155
+
156
+ it "re-renders the 'new' template" do
157
+ # Trigger the behavior that occurs when invalid params are submitted
158
+ Mist::Post.any_instance.stub(:save).and_return(false)
159
+ post :create, {:post => {}}, valid_session
160
+ response.should render_template("new")
161
+ end
162
+ end
163
+ end
164
+
165
+ describe "PUT update" do
166
+ describe "with valid params" do
167
+ describe "while unauthorized" do
168
+ before { Mist.authorize(:update_post) { false } }
169
+
170
+ it "should not update the post" do
171
+ post = Mist::Post.create! valid_attributes
172
+ Mist::Post.any_instance.should_not_receive(:update_attributes).with({'these' => 'params'})
173
+ put :update, {:id => post.to_param, :post => {'these' => 'params'}}, valid_session
174
+ end
175
+
176
+ it "should not assign post" do
177
+ post = Mist::Post.create! valid_attributes
178
+ put :update, {:id => post.to_param, :post => valid_attributes}, valid_session
179
+ assigns(:post).should_not be_a(Mist::Post)
180
+ end
181
+
182
+ it "should redirect out" do
183
+ post = Mist::Post.create! valid_attributes
184
+ put :update, {:id => post.to_param, :post => valid_attributes}, valid_session
185
+ response.should redirect_to(posts_path)
186
+ end
187
+ end
188
+
189
+ it "updates the requested post" do
190
+ post = Mist::Post.create! valid_attributes
191
+ # Assuming there are no other posts in the database, this
192
+ # specifies that the Mist::Post created on the previous line
193
+ # receives the :update_attributes message with whatever params are
194
+ # submitted in the request.
195
+ Mist::Post.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
196
+ put :update, {:id => post.to_param, :post => {'these' => 'params'}}, valid_session
197
+ end
198
+
199
+ it "assigns the requested post as @post" do
200
+ post = Mist::Post.create! valid_attributes
201
+ put :update, {:id => post.to_param, :post => valid_attributes}, valid_session
202
+ assigns(:post).should eq(post)
203
+ end
204
+
205
+ it "redirects to the post" do
206
+ post = Mist::Post.create! valid_attributes
207
+ put :update, {:id => post.to_param, :post => valid_attributes}, valid_session
208
+ response.should redirect_to(post)
209
+ end
210
+ end
211
+
212
+ describe "with invalid params" do
213
+ it "assigns the post as @post" do
214
+ post = Mist::Post.create! valid_attributes
215
+ # Trigger the behavior that occurs when invalid params are submitted
216
+ Mist::Post.any_instance.stub(:save).and_return(false)
217
+ put :update, {:id => post.to_param, :post => {}}, valid_session
218
+ assigns(:post).should eq(post)
219
+ end
220
+
221
+ it "re-renders the 'edit' template" do
222
+ post = Mist::Post.create! valid_attributes
223
+ # Trigger the behavior that occurs when invalid params are submitted
224
+ Mist::Post.any_instance.stub(:save).and_return(false)
225
+ put :update, {:id => post.to_param, :post => {}}, valid_session
226
+ response.should render_template("edit")
227
+ end
228
+ end
229
+ end
230
+
231
+ describe "DELETE destroy" do
232
+ describe "while unauthorized" do
233
+ before { Mist.authorize(:destroy_post) { false } }
234
+
235
+ it "does not destroy the requested post" do
236
+ post = Mist::Post.create! valid_attributes
237
+ expect {
238
+ delete :destroy, {:id => post.to_param}, valid_session
239
+ }.to_not change(Mist::Post, :count).by(-1)
240
+ end
241
+
242
+ it "redirects to the posts list" do
243
+ post = Mist::Post.create! valid_attributes
244
+ delete :destroy, {:id => post.to_param}, valid_session
245
+ response.should redirect_to(posts_path)
246
+ end
247
+ end
248
+
249
+ it "destroys the requested post" do
250
+ post = Mist::Post.create! valid_attributes
251
+ expect {
252
+ delete :destroy, {:id => post.to_param}, valid_session
253
+ }.to change(Mist::Post, :count).by(-1)
254
+ end
255
+
256
+ it "redirects to the posts list" do
257
+ post = Mist::Post.create! valid_attributes
258
+ delete :destroy, {:id => post.to_param}, valid_session
259
+ response.should redirect_to(posts_path)
260
+ end
261
+ end
262
+
263
+ end