mist 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +13 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +192 -0
- data/README.md +108 -0
- data/Rakefile +9 -0
- data/app/assets/images/mist/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/app/assets/images/mist/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/app/assets/images/mist/ui-bg_flat_10_000000_40x100.png +0 -0
- data/app/assets/images/mist/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/app/assets/images/mist/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/app/assets/images/mist/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/images/mist/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/app/assets/images/mist/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/mist/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/app/assets/images/mist/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/mist/ui-icons_228ef1_256x240.png +0 -0
- data/app/assets/images/mist/ui-icons_ef8c08_256x240.png +0 -0
- data/app/assets/images/mist/ui-icons_ffd27a_256x240.png +0 -0
- data/app/assets/images/mist/ui-icons_ffffff_256x240.png +0 -0
- data/app/assets/javascripts/mist/jquery-ui-1.8.17.custom.min.js +356 -0
- data/app/assets/javascripts/mist/posts.js.coffee +3 -0
- data/app/assets/javascripts/mist_core.js +3 -0
- data/app/assets/stylesheets/mist/posts.css.sass +97 -0
- data/app/assets/stylesheets/mist/scaffolds.css.scss +56 -0
- data/app/assets/stylesheets/mist/ui-lightness/jquery-ui-1.8.17.custom.css +565 -0
- data/app/assets/stylesheets/mist_core.css +4 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/controllers/mist/posts_controller.rb +130 -0
- data/app/helpers/mist/posts_helper.rb +61 -0
- data/app/mailers/.gitkeep +0 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/mist/post.rb +240 -0
- data/app/models/mist/post_sweeper.rb +63 -0
- data/app/views/layouts/mist/posts.html.erb +66 -0
- data/app/views/mist/posts/_form.html.erb +55 -0
- data/app/views/mist/posts/_post.html.erb +19 -0
- data/app/views/mist/posts/_sidebar_title.html.erb +5 -0
- data/app/views/mist/posts/edit.html.erb +16 -0
- data/app/views/mist/posts/feed.atom.builder +17 -0
- data/app/views/mist/posts/index.html.erb +31 -0
- data/app/views/mist/posts/new.html.erb +15 -0
- data/app/views/mist/posts/show.html.erb +3 -0
- data/config/cucumber.yml +8 -0
- data/config/environment.rb +1 -0
- data/config/routes.rb +7 -0
- data/features/atom_feed.feature +20 -0
- data/features/authorize_create_post.feature +14 -0
- data/features/authorize_destroy_post.feature +27 -0
- data/features/authorize_update_post.feature +28 -0
- data/features/authorize_view_unpublished.feature +22 -0
- data/features/create_post.feature +13 -0
- data/features/destroy_post.feature +13 -0
- data/features/format_with_markdown.feature +13 -0
- data/features/popular_posts.feature +35 -0
- data/features/recent_posts.feature +28 -0
- data/features/similar_posts.feature +43 -0
- data/features/step_definitions/authorization_steps.rb +17 -0
- data/features/step_definitions/filesystem_steps.rb +13 -0
- data/features/step_definitions/page_steps.rb +43 -0
- data/features/step_definitions/post_steps.rb +58 -0
- data/features/step_definitions/sidebar_steps.rb +21 -0
- data/features/support/env.rb +58 -0
- data/features/support/setup.rb +15 -0
- data/features/update_post.feature +19 -0
- data/gemfiles/common +20 -0
- data/gemfiles/rails-3.1.3 +4 -0
- data/gemfiles/rails-3.1.3.lock +195 -0
- data/gemfiles/rails-3.2.0 +4 -0
- data/lib/generators/mist/USAGE +13 -0
- data/lib/generators/mist/setup_generator.rb +21 -0
- data/lib/generators/mist/templates/initializer.rb +17 -0
- data/lib/generators/mist/templates/mist.css.scss +2 -0
- data/lib/generators/mist/templates/mist.js.coffee +1 -0
- data/lib/generators/mist/views_generator.rb +11 -0
- data/lib/mist.rb +26 -0
- data/lib/mist/code_example_parser.rb +86 -0
- data/lib/mist/configuration.rb +68 -0
- data/lib/mist/configuration/author.rb +8 -0
- data/lib/mist/engine.rb +12 -0
- data/lib/mist/git_file_system_history.rb +66 -0
- data/lib/mist/git_model.rb +154 -0
- data/lib/mist/git_model/attributes.rb +21 -0
- data/lib/mist/git_model/class_methods.rb +141 -0
- data/lib/mist/permalink.rb +5 -0
- data/lib/mist/repository.rb +15 -0
- data/lib/mist/version.rb +8 -0
- data/mist.gemspec +33 -0
- data/spec/controllers/posts_controller_spec.rb +263 -0
- data/spec/dummy_rails_app/app/assets/javascripts/mist.js.coffee +1 -0
- data/spec/dummy_rails_app/app/assets/stylesheets/mist.css.scss +2 -0
- data/spec/dummy_rails_app/app/views/layouts/mist/posts.html.erb +60 -0
- data/spec/dummy_rails_app/config.ru +4 -0
- data/spec/dummy_rails_app/config/application.rb +48 -0
- data/spec/dummy_rails_app/config/boot.rb +7 -0
- data/spec/dummy_rails_app/config/database.yml +28 -0
- data/spec/dummy_rails_app/config/environment.rb +5 -0
- data/spec/dummy_rails_app/config/environments/development.rb +32 -0
- data/spec/dummy_rails_app/config/environments/production.rb +60 -0
- data/spec/dummy_rails_app/config/environments/test.rb +42 -0
- data/spec/dummy_rails_app/config/initializers/active_gist_credentials.rb +8 -0
- data/spec/dummy_rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy_rails_app/config/initializers/inflections.rb +10 -0
- data/spec/dummy_rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/dummy_rails_app/config/initializers/mist.rb +17 -0
- data/spec/dummy_rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/dummy_rails_app/config/initializers/session_store.rb +8 -0
- data/spec/dummy_rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy_rails_app/config/locales/en.yml +5 -0
- data/spec/dummy_rails_app/config/routes.rb +3 -0
- data/spec/dummy_rails_app/db/schema.rb +22 -0
- data/spec/dummy_rails_app/db/seeds.rb +7 -0
- data/spec/dummy_rails_app/doc/README_FOR_APP +2 -0
- data/spec/dummy_rails_app/lib/assets/.gitkeep +0 -0
- data/spec/dummy_rails_app/lib/tasks/.gitkeep +0 -0
- data/spec/dummy_rails_app/lib/tasks/cucumber.rake +65 -0
- data/spec/dummy_rails_app/public/404.html +26 -0
- data/spec/dummy_rails_app/public/422.html +26 -0
- data/spec/dummy_rails_app/public/500.html +26 -0
- data/spec/dummy_rails_app/public/favicon.ico +0 -0
- data/spec/dummy_rails_app/public/robots.txt +5 -0
- data/spec/dummy_rails_app/script/cucumber +10 -0
- data/spec/dummy_rails_app/script/rails +6 -0
- data/spec/dummy_rails_app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/dummy_rails_app/vendor/plugins/.gitkeep +0 -0
- data/spec/factories/posts.rb +8 -0
- data/spec/fixtures/gist_404 +6 -0
- data/spec/fixtures/gist_with_1_code_example +66 -0
- data/spec/helpers/posts_helper_spec.rb +64 -0
- data/spec/lib/mist/code_example_parser_spec.rb +135 -0
- data/spec/lib/mist/configuration_spec.rb +88 -0
- data/spec/lib/mist/permalink_spec.rb +17 -0
- data/spec/lib/mist/repository_spec.rb +20 -0
- data/spec/models/mist/git_model_spec.rb +260 -0
- data/spec/models/mist/post_spec.rb +575 -0
- data/spec/requests/posts_caching_spec.rb +152 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/cache_helpers.rb +71 -0
- data/spec/support/config.rb +42 -0
- data/spec/support/fakeweb.rb +3 -0
- data/spec/views/mist/posts/edit.html.erb_spec.rb +11 -0
- data/spec/views/mist/posts/index.html.erb_spec.rb +27 -0
- data/spec/views/mist/posts/new.html.erb_spec.rb +15 -0
- data/spec/views/mist/posts/show.html.erb_spec.rb +11 -0
- metadata +371 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
class Mist::PostSweeper < ActionController::Caching::Sweeper
|
2
|
+
observe Mist::Post
|
3
|
+
|
4
|
+
def after_save(post)
|
5
|
+
bust! post
|
6
|
+
end
|
7
|
+
|
8
|
+
def after_destroy(post)
|
9
|
+
bust! post
|
10
|
+
end
|
11
|
+
|
12
|
+
def before_save(post)
|
13
|
+
@tags_were = post.tags_was
|
14
|
+
end
|
15
|
+
|
16
|
+
def bust!(post)
|
17
|
+
expire_page :action => 'feed', :format => 'atom'
|
18
|
+
|
19
|
+
touched = touched_posts post
|
20
|
+
each_combo(Mist.authorized_actions) do |options|
|
21
|
+
options.keys.each { |key| options.delete(key) unless options[key] }
|
22
|
+
|
23
|
+
expire_page options.merge(:action => 'index')
|
24
|
+
bust_post! post, options
|
25
|
+
touched.each { |p| bust_post! p, options }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def bust_post!(post, options)
|
30
|
+
expire_action options.merge(:action => 'show', :id => post.id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def touched_posts(post)
|
34
|
+
(post.similar_posts | Mist::Post.matching_tags(@tags_were)).tap { |a| a.delete post }
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def each_combo(keys)
|
39
|
+
len = keys.length
|
40
|
+
flags = 0 # start with all off / false
|
41
|
+
combos = []
|
42
|
+
|
43
|
+
# yields a single combination
|
44
|
+
process = proc do
|
45
|
+
options = ActiveSupport::OrderedHash.new
|
46
|
+
for i in 0...len
|
47
|
+
flag = (flags >> i) & 1
|
48
|
+
options[keys[i]] = (flag == 1)
|
49
|
+
end
|
50
|
+
combos << options
|
51
|
+
yield options if block_given?
|
52
|
+
end
|
53
|
+
|
54
|
+
# iterate through all combos and yield them one at a time
|
55
|
+
while ((flags >> len) & 1) == 0
|
56
|
+
process.call
|
57
|
+
flags += 1
|
58
|
+
end
|
59
|
+
|
60
|
+
# return combos
|
61
|
+
combos
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>
|
5
|
+
<%= Mist.title %>
|
6
|
+
<% if @post %>
|
7
|
+
- <%= @post.title %>
|
8
|
+
<% end %>
|
9
|
+
</title>
|
10
|
+
|
11
|
+
<%= auto_discovery_link_tag :atom, feed_posts_path(:format => :atom) %>
|
12
|
+
<%= stylesheet_link_tag "mist_core" %>
|
13
|
+
<%= stylesheet_link_tag "mist" %>
|
14
|
+
<%= javascript_include_tag "mist_core" %>
|
15
|
+
<%= javascript_include_tag "mist" %>
|
16
|
+
<%= csrf_meta_tags %>
|
17
|
+
</head>
|
18
|
+
<body>
|
19
|
+
<%= yield :header %>
|
20
|
+
|
21
|
+
<div id="sidebar">
|
22
|
+
<%= yield :sidebar %>
|
23
|
+
|
24
|
+
<% unless similar_posts.empty? %>
|
25
|
+
<div id="sidebar-similar-posts" class="sidebar bordered">
|
26
|
+
<h3>Similar Posts</h3>
|
27
|
+
<ul>
|
28
|
+
<% similar_posts.each do |post| %>
|
29
|
+
<li> <%= link_to post.title, post_path(post) %> </li>
|
30
|
+
<% end %>
|
31
|
+
</ul>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% unless popular_posts.empty? %>
|
36
|
+
<div id="sidebar-popular-posts" class="sidebar bordered">
|
37
|
+
<h3>Popular Posts</h3>
|
38
|
+
<ul>
|
39
|
+
<% popular_posts.each do |post| %>
|
40
|
+
<li> <%= link_to post.title, post_path(post) %> </li>
|
41
|
+
<% end %>
|
42
|
+
</ul>
|
43
|
+
</div>
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<% unless recent_posts.empty? %>
|
47
|
+
<div id="sidebar-recent-posts" class="sidebar bordered">
|
48
|
+
<h3>Recent Posts</h3>
|
49
|
+
<ul>
|
50
|
+
<% recent_posts.each do |post| %>
|
51
|
+
<li> <%= link_to post.title, post_path(post) %> </li>
|
52
|
+
<% end %>
|
53
|
+
</ul>
|
54
|
+
</div>
|
55
|
+
<% end %>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div class="content">
|
59
|
+
<%= yield %>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<div id="footer">
|
63
|
+
<p>Powered by <%= link_to "Mist", 'http://github.com/sinisterchipmunk/mist' %> <%= Mist::VERSION %></p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<%= form_for(@post) do |f| %>
|
2
|
+
<% if @post.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @post.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="fields">
|
15
|
+
<p class="field">
|
16
|
+
<div class="field-label">
|
17
|
+
<%= f.label :title %>
|
18
|
+
</div>
|
19
|
+
<div class="field-input">
|
20
|
+
<%= f.text_field :title %>
|
21
|
+
</div>
|
22
|
+
</p>
|
23
|
+
|
24
|
+
<p class="field">
|
25
|
+
<div class="field-label">
|
26
|
+
<%= f.label :published_at %>
|
27
|
+
</div>
|
28
|
+
<div class="field-input">
|
29
|
+
<%= f.text_field :published_at %>
|
30
|
+
</div>
|
31
|
+
</p>
|
32
|
+
|
33
|
+
<p class="field">
|
34
|
+
<div class="field-label">
|
35
|
+
<%= f.label :content %>
|
36
|
+
</div>
|
37
|
+
<div class="field-input">
|
38
|
+
<%= f.text_area :content %>
|
39
|
+
</div>
|
40
|
+
</p>
|
41
|
+
|
42
|
+
<p class="field">
|
43
|
+
<div class="field-label">
|
44
|
+
<%= f.label :tags %>
|
45
|
+
</div>
|
46
|
+
<div class="field-input">
|
47
|
+
<%= f.text_field :tags, :value => @post.tags.join(', ') %>
|
48
|
+
</div>
|
49
|
+
</p>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<p class="actions">
|
53
|
+
<%= f.submit "Save" %>
|
54
|
+
</p>
|
55
|
+
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="post bordered">
|
2
|
+
<div class="title">
|
3
|
+
<h1>
|
4
|
+
<%= link_to post.title, post_path(post.id) %>
|
5
|
+
</h1>
|
6
|
+
|
7
|
+
<%= authorized_links admin_link_separator,
|
8
|
+
[:edit_post, 'Edit', edit_post_path(post.id)],
|
9
|
+
[:destroy_post, 'Destroy', post.id, {:confirm => 'Are you sure?', :method => :delete}] %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<%= yield :subcaption %>
|
13
|
+
|
14
|
+
<% if preview %>
|
15
|
+
<%= post.content_as_html_preview %>
|
16
|
+
<% else %>
|
17
|
+
<%= post.content_as_html %>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= render :partial => 'sidebar_title' %>
|
2
|
+
|
3
|
+
<div class="post bordered">
|
4
|
+
<div class="title">
|
5
|
+
<h1>
|
6
|
+
Editing post "<%= @post.title %>"
|
7
|
+
</h1>
|
8
|
+
</div>
|
9
|
+
|
10
|
+
<p>
|
11
|
+
<%= link_to 'Show', @post %> |
|
12
|
+
<%= link_to 'Back', posts_path %>
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<%= render 'form' %>
|
16
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
atom_feed do |feed|
|
2
|
+
feed.title @title
|
3
|
+
feed.updated @updated
|
4
|
+
|
5
|
+
@posts.each do |post|
|
6
|
+
feed.entry(post) do |entry|
|
7
|
+
entry.title(post.title)
|
8
|
+
entry.content(post.content_as_html, :type => 'html')
|
9
|
+
entry.summary(post.content_as_html_preview, :type => 'html')
|
10
|
+
|
11
|
+
entry.author do |author|
|
12
|
+
author.name Mist.author.name
|
13
|
+
author.email Mist.author.email
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% content_for :header do %>
|
2
|
+
<div id="header" class="bordered">
|
3
|
+
<div class="banner">
|
4
|
+
<%= link_to Mist.title, posts_path %>
|
5
|
+
|
6
|
+
<div class="author">
|
7
|
+
with <%= mail_to Mist.author.email, Mist.author.name %>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="admin">
|
12
|
+
<%= authorized_link :create_post, 'New Post', new_post_path %>
|
13
|
+
</div>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<% if @posts.empty? %>
|
18
|
+
<div class="post bordered">
|
19
|
+
<div class="title">
|
20
|
+
<h1>
|
21
|
+
o hai!
|
22
|
+
</h1>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
Welcome to my new blog! I'll have some decent content up in no time — promise!
|
27
|
+
</p>
|
28
|
+
</div>
|
29
|
+
<% else %>
|
30
|
+
<%= render_posts %>
|
31
|
+
<% end %>
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('../spec/dummy_rails_app/config/environment', File.dirname(__FILE__))
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Atom feed
|
2
|
+
As a blog owner
|
3
|
+
In order to increase return visits
|
4
|
+
I want to publish an Atom feed
|
5
|
+
|
6
|
+
Scenario: With no blog posts
|
7
|
+
When I am on the feed posts page in "atom" format
|
8
|
+
# I don't know how to test this. But, at least we've made sure no errors
|
9
|
+
# were generated...
|
10
|
+
|
11
|
+
Scenario: With an unpublished blog post
|
12
|
+
Given I have created a post called "Post title"
|
13
|
+
When I am on the feed posts page in "atom" format
|
14
|
+
Then I should not see "Post title"
|
15
|
+
|
16
|
+
Scenario: With a published blog post
|
17
|
+
Given I have published a post called "Post title"
|
18
|
+
When I am on the feed posts page in "atom" format
|
19
|
+
Then I should see "Post title"
|
20
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Authorization of Create new post
|
2
|
+
As a blog owner
|
3
|
+
In order to protect by blog from malicious users
|
4
|
+
I want to authorize who creates a post
|
5
|
+
|
6
|
+
Scenario: Create post without authorization
|
7
|
+
Given I am not authorized
|
8
|
+
When I am on the posts page
|
9
|
+
Then I should not see "New Post"
|
10
|
+
|
11
|
+
Scenario: Create post with authorization
|
12
|
+
Given I am authorized
|
13
|
+
When I am on the posts page
|
14
|
+
Then I should see "New Post"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Update existing post
|
2
|
+
As a blog owner
|
3
|
+
In order to protect by site from malicious users
|
4
|
+
I want to authorize who can destroy an existing post
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I have published a post called "Post title"
|
8
|
+
|
9
|
+
Scenario: Destroy post when not authorized
|
10
|
+
Given I am not authorized
|
11
|
+
When I look at the "Post title" post
|
12
|
+
Then I should not see "Destroy"
|
13
|
+
|
14
|
+
Scenario: Destroy post when authorized
|
15
|
+
Given I am authorized
|
16
|
+
When I look at the "Post title" post
|
17
|
+
Then I should see "Destroy"
|
18
|
+
|
19
|
+
Scenario: Destroy from main page when authorized
|
20
|
+
Given I am authorized
|
21
|
+
When I am on the posts page
|
22
|
+
Then I should see "Destroy"
|
23
|
+
|
24
|
+
Scenario: Destroy from main page when not authorized
|
25
|
+
Given I am not authorized
|
26
|
+
When I am on the posts page
|
27
|
+
Then I should not see "Destroy"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Update existing post
|
2
|
+
As a blog owner
|
3
|
+
In order to protect by site from malicious users
|
4
|
+
I want to authorize who can update an existing post
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I have published a post called "Post title"
|
8
|
+
|
9
|
+
Scenario: Change post when not authorized
|
10
|
+
Given I am not authorized
|
11
|
+
When I look at the "Post title" post
|
12
|
+
Then I should not see "Edit"
|
13
|
+
|
14
|
+
Scenario: Change post when authorized
|
15
|
+
Given I am authorized
|
16
|
+
When I look at the "Post title" post
|
17
|
+
Then I should see "Edit"
|
18
|
+
|
19
|
+
Scenario: Update from main page when authorized
|
20
|
+
Given I am authorized
|
21
|
+
When I am on the posts page
|
22
|
+
Then I should see "Edit"
|
23
|
+
|
24
|
+
Scenario: Update from main page when not authorized
|
25
|
+
Given I am not authorized
|
26
|
+
When I am on the posts page
|
27
|
+
Then I should not see "Edit"
|
28
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Authorize viewing unpublished posts
|
2
|
+
As a blog author
|
3
|
+
In order to keep my content clean and consistent
|
4
|
+
I want to prevent others from seeing a post before it is published
|
5
|
+
|
6
|
+
Scenario: Shown to authorized when not published
|
7
|
+
Given I am authorized
|
8
|
+
When I create a post called "Post title"
|
9
|
+
And I am on the posts page
|
10
|
+
Then I should see "Post title"
|
11
|
+
|
12
|
+
Scenario: Not shown to unauthorized when not published
|
13
|
+
Given I have created a post called "Post title"
|
14
|
+
And I am not authorized
|
15
|
+
When I am on the posts page
|
16
|
+
Then I should not see "Post title"
|
17
|
+
|
18
|
+
Scenario: Become available when published
|
19
|
+
Given I have published a post called "Post title"
|
20
|
+
And I am not authorized
|
21
|
+
When I am on the posts page
|
22
|
+
Then I should see "Post title"
|