jeffrafter-spreadhead 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.textile CHANGED
@@ -1,7 +1,18 @@
1
- h2. 0.3.0
1
+ h2. 0.6.0
2
+
3
+ * Changed filter behavior, made editing disabled by default (Jeff Rafter)
4
+
5
+ h2. 0.5.0
6
+
7
+ * Added tasks for importing and exporting (Jeff Rafter)
8
+
9
+ h2. 0.4.0
2
10
 
3
11
  * Removed to_param behavior for page resource (Jeff Rafter)
4
12
  * Allowed for "/" in urls (Jeff Rafter)
13
+
14
+ h2. 0.3.0
15
+
5
16
  * Added a view link (Jeff Rafter)
6
17
 
7
18
  h2. 0.2.0 (unreleased)
data/README.textile CHANGED
@@ -2,7 +2,7 @@ h1. Spreadhead
2
2
 
3
3
  <strong>spreadhead</strong> <em>noun</em> two facing pages of a book or other publication.
4
4
 
5
- Rails content mangement for pages that shouldn't be views.
5
+ Rails content management for pages that shouldn't be views.
6
6
 
7
7
  h2. Installation
8
8
 
@@ -39,20 +39,15 @@ Run the migration:
39
39
  rake db:migrate
40
40
  </pre>
41
41
 
42
+ Modify the initializer in @config/initializers/spreadhead.rb@ to control access.
43
+
42
44
  h2. Routes
43
45
 
44
46
  Spreadhead installs default catch-all routes. These are given the lowest priority in your application. If your application is already catching these routes then you may not be able to access your spreadhead pages.
45
47
 
46
- h2. Cucumber Features
47
-
48
- As your application evolves, you want to know that your pages still work. Cucumber tests are included.
49
-
50
- Run the Cucumber generator (if you haven't already) and the feature generator:
48
+ h2. Tutorial
51
49
 
52
- <pre>
53
- script/generate cucumber
54
- script/generate spreadhead_features
55
- </pre>
50
+ Checkout the "tutorial":http://wiki.github.com/jeffrafter/spreadhead/tutorial.
56
51
 
57
52
  h2. Authors
58
53
 
data/TODO.textile CHANGED
@@ -1,4 +1,6 @@
1
1
  h1. To-do
2
2
 
3
- * Include alternate views
4
- * Allow authentication and role to be checked
3
+ * Include alternate views for the forms
4
+ * Allow alternate layouts
5
+ * Caching, clearing cache
6
+ * Uploading images (basic)
data/TUTORIAL.textile ADDED
@@ -0,0 +1,248 @@
1
+ Before you can use Spreadhead you are going to need a few things, most importantly the spreadhead gem:
2
+
3
+ <pre>
4
+ <code>
5
+ sudo gem install jeffrafter-spreadhead --source=http://gems.github.com
6
+ </code>
7
+ </pre>
8
+
9
+ By default this should install the RedCloth gem, the BlueCloth gem, and the rsl-stringex gem. These handle the text and url formatting. If you want to run the spreadhead-specific tests, you will need Thoughtbot's shoulda and factory_girl. Once you have all of the requisite gems, you need to configure your Rails application to use the gem. You can do this by adding a config.gem statement to your environment.rb (or to a specific environment). For example:
10
+
11
+ <pre>
12
+ <code>
13
+ Rails::Initializer.run do |config|
14
+ # Specify gems that this application depends on and have them installed with
15
+ # rake gems:install
16
+ config.gem "spreadhead", :lib => "spreadhead"
17
+
18
+ # Skip frameworks you're not going to use. To use Rails without a database,
19
+ # you must remove the Active Record framework.
20
+ config.frameworks -= [ :active_resource ]
21
+
22
+ # Set Time.zone default to the specified zone and make Active Record
23
+ # auto-convert to this zone. Run "rake -D time" for a list of tasks for
24
+ # finding time zone names.
25
+ config.time_zone = 'UTC'
26
+ end
27
+ </code>
28
+ </pre>
29
+
30
+ After you have done this, you can use the spreadhead generator from the console (while in the rails root).
31
+
32
+ <pre>
33
+ <code>
34
+ script/generate spreadhead
35
+ </code>
36
+ </pre>
37
+
38
+ This will create (or update) a migration for the pages table, which is used to store all of the pages in your system. Additionally, it will create a Page model in your app/models folder. The model is blank except for an include statement to bring in all of the base functionality. By default the page creation and editing is completely disabled, you need to enable it in the @config/initializers/spreadhead.rb@ file.This is all you need to get started, you should be able to run the migration and restart your application and navigate to the "/pages" url.
39
+
40
+ h2. Security
41
+
42
+ It is important to note that allowing users to create pages, especially pages that can contain &lt;script&gt; tags is just a bad idea. You need to trust the user, which is also a bad idea. Because of this, page creation, editing, deleting - _everything_ - is disabled when you install it into your application. This is a safety feature to protect your app from some accidental inclusion or deployment.
43
+
44
+ To enable the application you need to modify initializer, where you can control which users get access to create, edit, destroy and update pages. To do this, you can add a before filter. If you are using a toolkit like Clearance, then you can use the something like the following:
45
+
46
+ <pre>
47
+ <code>
48
+ module Spreadhead
49
+ module PagesAuth
50
+ def self.filter(controller)
51
+ controller.redirect_to_root unless signed_in?
52
+ end
53
+ end
54
+ end
55
+ </code>
56
+ </pre>
57
+
58
+ If you give everyone access, this is probably still a bad idea and you will want to check that the current user is an admin:
59
+
60
+ <pre>
61
+ <code>
62
+ module Spreadhead
63
+ module PagesAuth
64
+ def self.filter(controller)
65
+ controller.redirect_to_root unless admin?
66
+ end
67
+ end
68
+ end
69
+ </code>
70
+ </pre>
71
+
72
+ Of course, you will probably want to add something to your application controller for checking if the current user is an admin:
73
+
74
+ <pre>
75
+ <code>
76
+ def admin?
77
+ signed_in? && current_user.admin?
78
+ end
79
+ </code>
80
+ </pre>
81
+
82
+ Remember to protect that admin attribute in your user model so that it can't be mass assigned.
83
+
84
+ This same kind of methodology will work for authlogic, restful_authentication, or your favorite authorization toolkit or homegrown solution. This really isn't the place for security how-to, but just keep in mind that if the hackers get access to this, they will win.
85
+
86
+ h2. What do I get?
87
+
88
+ By default you will have the "/pages":http://localhost:3000/pages resource. This is where you make new pages:
89
+
90
+ <div class="thumbnail"><a href="http://skitch.com/jeffrafter/b5anb/malachite.org-simpler-message-service"><img src="http://img.skitch.com/20090818-bfje6q835cdcnaf9hx2adj5qxx.preview.jpg" alt="Malachite.org - Simpler message service." /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>'s <a href="http://skitch.com">Skitch</a>!</span></div>
91
+
92
+ Once you have made a page you can access that by the created URL. If you title your page "Brachiosaurus or woozle!" and leave the URL blank it will be located at "/brachiosaurus-or-woozle" (notice that you don't need the leading "/"). If you wanted to get fancy you could set the URL yourself (or change it) to something like "2004/09/13/brachs-and-woo" and then you can access this full path from the root of your site.
93
+
94
+ You can blank the URL out at any time and Spreadhead will generate a new one. If there is a conflict it will add "-1" to the end (or "-2" and so on).
95
+
96
+ h2. Hey my routes aren't working
97
+
98
+ Maybe you have some fancy routes already, maybe something using a glob? Maybe something like:
99
+
100
+ <pre>
101
+ <code>
102
+ map.connect '/:username/:project_name', :controller => 'projects', :action => 'show', :conditions => {:method => :put}
103
+ </code>
104
+ </pre>
105
+
106
+ Well, that is going to catch anything before it gets to Spreadhead's routes (which have the lowest priority). You will probably want to redeclare the pages resource with a higher priority. Put this before the special route:
107
+
108
+ <pre>
109
+ <code>
110
+ map.resources :pages, :controller => 'spreadhead/pages'
111
+ </code>
112
+ </pre>
113
+
114
+ h2. Adding some style
115
+
116
+ The views for the admin interface are pretty plain:
117
+
118
+ <div class="thumbnail"><a href="http://skitch.com/jeffrafter/b5ab9/malachite.org-simpler-message-service"><img src="http://img.skitch.com/20090818-rpcd6uqf9u678a68rc5r4ed1tu.preview.jpg" alt="Malachite.org - Simpler message service." /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>'s <a href="http://skitch.com">Skitch</a>!</span></div>
119
+
120
+ But you might want to dress them up. I wanted to just drop some basic CSS here for now, but updates are welcome:
121
+
122
+ <pre>
123
+ <code>
124
+ div.checkbox,
125
+ div.text,
126
+ div.textarea,
127
+ div.select {
128
+ float:none;
129
+ clear:both;
130
+ padding-top:8px;
131
+ }
132
+ div.checkbox label,
133
+ div.text label,
134
+ div.textarea label,
135
+ div.select label {
136
+ padding-top:5px;
137
+ padding-right:15px;
138
+ display:block;
139
+ width:150px;
140
+ float:left;
141
+ text-align:right;
142
+ }
143
+ div.submit {
144
+ margin-top:10px;
145
+ padding-top:10px;
146
+ width:90%;
147
+ float:right;
148
+ border-top:1px dotted silver;
149
+ }
150
+ div.optional {
151
+ color:gray;
152
+ }
153
+ div.required {
154
+ }
155
+ div.syntax {
156
+ background:#4C5E29;
157
+ padding:4px;
158
+ color:white;
159
+ margin-left:165px;
160
+ margin-top:-3px;
161
+ width:324px;
162
+ text-align:right;
163
+ }
164
+ div.syntax a {
165
+ color:white;
166
+ }
167
+ input {
168
+ margin-top:4px;
169
+ }
170
+ select {
171
+ margin-top:4px;
172
+ }
173
+ textarea {
174
+ margin-top:4px;
175
+ }
176
+ </code>
177
+ </pre>
178
+
179
+ And some basic table styling:
180
+
181
+ <pre>
182
+ <code>
183
+ table.pages {
184
+ background:#FFFFFF none repeat scroll 0 0;
185
+ border-collapse:collapse;
186
+ margin-bottom:20px;
187
+ text-align:left;
188
+ -moz-background-clip:border;
189
+ -moz-background-inline-policy:continuous;
190
+ -moz-background-origin:padding;
191
+ }
192
+ table.pages th {
193
+ border-bottom:2px solid #4C5E29;
194
+ font-family:"Helvetica Neue",Arial,Helvetica,Geneva,sans-serif;
195
+ color:#4C5E29;
196
+ font-weight:normal;
197
+ padding:10px 8px;
198
+ }
199
+ table.pages td {
200
+ border-bottom:1px solid silver;
201
+ padding:6px 8px;
202
+ background:#EAEAEA;
203
+ }
204
+ table.pages td.odd {
205
+ }
206
+ table.pages td.even {
207
+ background:#DBDBDB;
208
+ }
209
+ table.pages tr:hover td {
210
+ background:#F3F3F3;
211
+ }
212
+ table.pages td.published, th.published {
213
+ text-align:center;
214
+ }
215
+ table.pages td.commands {
216
+ text-align:right;
217
+ }
218
+ </code>
219
+ </pre>
220
+
221
+
222
+ h2. Layouts and adding extension points to your site
223
+
224
+ The pages should render using the default application layout just fine, but you can add a few things to make this better. Spreadhead wants to push content for the title, the description, and even keywords. This allows you to do some basic page-specific optimization. Add the following to the &lt;head&gt; section of your site:
225
+
226
+ <pre>
227
+ <code>
228
+ <title>Yoursite.org - <%= @title || yield(:title) -%></title>
229
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
230
+ <meta name="Description" content="<%= yield :description -%>" />
231
+ <meta name="Keywords" content="<%= yield :keywords -%>" />
232
+ </code>
233
+ </pre>
234
+
235
+ You can also create nice little extension points for your users to modify smaller areas of the site. For example, you might have a welcome page that needs to have various cover information, but you want your client to be able to modify the copy on the front. Simply do the following:
236
+
237
+ <pre>
238
+ <code>
239
+ <div id="blurb"><%= spreadhead "welcome" -%></div>
240
+ </code>
241
+ </pre>
242
+
243
+ Then, the client simply needs to create a page with the URL "welcome" and Spreadhead will insert the content. This could be used for headers, footers (including links).
244
+
245
+
246
+ h2. Importing and exporting
247
+
248
+ Spreadhead comes with some basic rake tasks for importing and exporting the pages: @rake spreadhead:export@ and @rake spreadhead:import@. Exporting will dump a set of Yaml fixutres to the file @db/data/pages.yml@ in your rails root. Importing will erase all of the current pages and replace them with those in the @db/data/pages.yml@ file (or none if the file does not exist).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.6.0
@@ -1,7 +1,8 @@
1
1
  module Spreadhead
2
2
  class PagesController < ApplicationController
3
3
  unloadable
4
-
4
+ before_filter :filter, :except => [:show]
5
+
5
6
  def new
6
7
  @page = ::Page.new
7
8
  end
@@ -22,7 +23,7 @@ module Spreadhead
22
23
  @page = ::Page.new(params[:page])
23
24
  respond_to do |format|
24
25
  if @page.save
25
- format.html { redirect_to page_url(@page) }
26
+ format.html { redirect_to pages_url }
26
27
  format.xml { head :created, :location => pages_url }
27
28
  else
28
29
  format.html { render :action => "new" }
@@ -52,5 +53,10 @@ module Spreadhead
52
53
  format.xml { head :ok }
53
54
  end
54
55
  end
56
+
57
+ private
58
+ def filter
59
+ Spreadhead::PagesAuth.filter(self)
60
+ end
55
61
  end
56
62
  end
@@ -2,35 +2,39 @@
2
2
  <%= form.error_messages %>
3
3
  </div>
4
4
 
5
- <div class="text">
5
+ <div class="text required unique">
6
6
  <%= form.label :title %>
7
7
  <%= form.text_field :title %>
8
8
  </div>
9
- <div class="text">
9
+ <div class="text optional unique">
10
10
  <%= form.label :url %>
11
11
  <%= form.text_field :url %>
12
12
  </div>
13
- <div class="text">
13
+ <div class="text optional">
14
14
  <%= form.label :description %>
15
15
  <%= form.text_field :description %>
16
16
  </div>
17
- <div class="text">
17
+ <div class="text optional">
18
18
  <%= form.label :keywords %>
19
19
  <%= form.text_field :keywords %>
20
20
  </div>
21
- <div class="text">
21
+ <div class="text optional">
22
22
  <%= form.label :category %>
23
23
  <%= form.text_field :category %>
24
24
  </div>
25
- <div class="textarea">
25
+ <div class="textarea required">
26
26
  <%= form.label :text %>
27
27
  <%= form.text_area :text %>
28
28
  </div>
29
- <div class="checkbox">
30
- <%= form.label :published %>
31
- <%= form.check_box :published %>
29
+ <div class="syntax">
30
+ <a href="http://daringfireball.net/projects/markdown/syntax" target="_blank">Learn Markdown</a> |
31
+ <a href="http://hobix.com/textile/" target="_blank">Learn Textile</a>
32
32
  </div>
33
- <div class="select">
33
+ <div class="select required">
34
34
  <%= form.label :formatting %>
35
35
  <%= form.select :formatting, [['Plain','plain'], ['Markdown', 'markdown'], ['Textile', 'textile']] %>
36
36
  </div>
37
+ <div class="checkbox optional">
38
+ <%= form.label :published %>
39
+ <%= form.check_box :published %>
40
+ </div>
@@ -1,12 +1,15 @@
1
1
  <h2>Pages</h2>
2
2
 
3
3
  <table class="pages">
4
- <tr>
5
- <th class="title">Title</th>
6
- <th class="path">Path</th>
7
- <th class="published">Published</th>
8
- <th class="commands"></th>
9
- </tr>
4
+ <thead>
5
+ <tr>
6
+ <th class="title">Title</th>
7
+ <th class="path">Path</th>
8
+ <th class="published">Published</th>
9
+ <th class="commands"></th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
10
13
  <% for page in @pages %>
11
14
  <tr class="<%= cycle("even","odd") -%>" >
12
15
  <td class="title"><%= link_to page.title || 'No title', edit_page_url(page) %></td>
@@ -15,6 +18,7 @@
15
18
  <td class="commands"><%= link_to "View", page.url %> | <%= link_to 'Destroy', page_url(page), :confirm => 'Are you sure?', :method => :delete %></td>
16
19
  </tr>
17
20
  <% end %>
21
+ </tbody>
18
22
  </table>
19
23
  <div>
20
24
  <%= link_to 'New page', new_page_url %>
@@ -19,6 +19,9 @@ class SpreadheadGenerator < Rails::Generator::Base
19
19
  m.directory File.join("test", "factories")
20
20
  m.file "factories.rb", "test/factories/spreadhead.rb"
21
21
 
22
+ m.directory File.join("config", "initializers")
23
+ m.file "initializer.rb", "config/initializers/spreadhead.rb"
24
+
22
25
  m.migration_template "migrations/#{migration_name}.rb", 'db/migrate',
23
26
  :migration_file_name => "spreadhead_#{migration_name}"
24
27
 
@@ -3,8 +3,8 @@
3
3
 
4
4
  Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting.
5
5
 
6
- By default, Spreadhead does not restrict access to page creation, updating and
7
- deleting. To implement this you will need to modify
6
+ By default, Spreadhead restricts access to page creation, updating and deleting.
7
+ To implement this you will need to modify
8
8
 
9
9
  config/initializers/spreadhead.rb
10
10
 
@@ -7,6 +7,21 @@
7
7
  # filter. If you are using a toolkit like Clearance, then you can use the
8
8
  # following:
9
9
  #
10
- # Spreadhead::PagesController.before_filter :redirect_to_root,
11
- # :except => [:show],
12
- # :unless => :signed_in?
10
+ # module Spreadhead
11
+ # module PagesAuth
12
+ # def self.filter(controller)
13
+ # controller.redirect_to_root unless signed_in?
14
+ # end
15
+ # end
16
+ # end
17
+ #
18
+ # By default all access to creating an modifying pages is forbidden. You need
19
+ # to make sure you trust the people creating pages because they can easily
20
+ # inject malicious scripts using this tool.
21
+ module Spreadhead
22
+ module PagesAuth
23
+ def self.filter(controller)
24
+ controller.send(:head, 403)
25
+ end
26
+ end
27
+ end
data/lib/spreadhead.rb CHANGED
@@ -3,4 +3,5 @@ require 'redcloth'
3
3
  require 'bluecloth'
4
4
  require 'spreadhead/extensions/routes'
5
5
  require 'spreadhead/page'
6
+ require 'spreadhead/filter'
6
7
 
@@ -0,0 +1,7 @@
1
+ module Spreadhead
2
+ module PagesAuth
3
+ def self.filter(controller)
4
+ controller.send(:head, 403)
5
+ end
6
+ end
7
+ end
@@ -37,6 +37,7 @@ module Spreadhead
37
37
  validates_presence_of :title
38
38
  validates_uniqueness_of :title
39
39
  validates_uniqueness_of :url
40
+ validates_presence_of :url
40
41
  end
41
42
  end
42
43
  end
@@ -67,6 +68,15 @@ module Spreadhead
67
68
  end
68
69
 
69
70
  module ClassMethods
71
+ def to_fixtures(path=nil)
72
+ path ||= File.expand_path("db/data/#{table_name}.yml", RAILS_ROOT)
73
+ path = File.join(path, "#{table_name}.yml") if File.directory?(path)
74
+ file = File.open(path, "w")
75
+ file.puts(self.find(:all).inject({}) { |hash, record|
76
+ hash.merge("\"#{record.title}\"" => record.attributes)
77
+ }.to_yaml(:SortKeys => true))
78
+ file.close
79
+ end
70
80
  end
71
81
  end
72
82
  end
@@ -0,0 +1,16 @@
1
+ require 'active_record/fixtures'
2
+
3
+ namespace :spreadhead do
4
+ desc "Export a set of fixtures from the current database pages"
5
+ task :export => [:environment] do
6
+ data = File.join(RAILS_ROOT, 'db', 'data')
7
+ Dir.mkdir(data) unless File.exists?(data)
8
+ Page.to_fixtures(data)
9
+ end
10
+
11
+ desc "Import a set of page fixtures into the current database (overwrites existing pages)"
12
+ task :import => [:environment] do
13
+ puts 'Importing fixtures'
14
+ Fixtures.create_fixtures("db/data/", 'pages')
15
+ end
16
+ end
@@ -5,79 +5,114 @@ class PagesControllerTest < ActionController::TestCase
5
5
 
6
6
  tests Spreadhead::PagesController
7
7
 
8
- context "on GET to #new" do
9
- setup { get :new }
10
-
11
- should_respond_with :success
12
- should_render_template :new
13
- should_not_set_the_flash
14
- end
15
-
16
- context "on GET to #index" do
17
- setup { get :index }
18
-
19
- should_respond_with :success
20
- should_render_template :index
21
- should_not_set_the_flash
22
- end
23
-
24
- context "on GET to #show" do
8
+ context "default setup" do
25
9
  setup do
26
- page = Factory(:page)
27
- get :show, :url => page.url
10
+ module Spreadhead::PagesAuth
11
+ def self.filter(controller); controller.send(:head, 403); end
12
+ end
28
13
  end
14
+
15
+ context "on GET to #new" do
16
+ setup { get :new }
17
+ should_respond_with 403
18
+ end
19
+
20
+ context "on GET to #show" do
21
+ setup do
22
+ page = Factory(:page)
23
+ get :show, :url => page.url
24
+ end
29
25
 
30
- should_respond_with :success
31
- should_render_template :show
32
- should_not_set_the_flash
26
+ should_respond_with :success
27
+ should_render_template :show
28
+ should_not_set_the_flash
29
+ end
33
30
  end
34
31
 
35
- context "on GET to #edit" do
32
+ context "authorized" do
36
33
  setup do
37
- page = Factory(:page)
38
- get :edit, :id => page.id
34
+ module Spreadhead::PagesAuth
35
+ def self.filter(controller); true; end
36
+ end
39
37
  end
38
+
39
+ context "on GET to #new" do
40
+ setup { get :new }
40
41
 
41
- should_respond_with :success
42
- should_render_template :edit
43
- should_not_set_the_flash
44
- end
42
+ should_respond_with :success
43
+ should_render_template :new
44
+ should_not_set_the_flash
45
+ end
45
46
 
46
- context "on POST to #create with valid attributes" do
47
- setup do
48
- page_attributes = Factory.attributes_for(:page)
49
- post :create, :page => page_attributes
47
+ context "on GET to #index" do
48
+ setup { get :index }
49
+
50
+ should_respond_with :success
51
+ should_render_template :index
52
+ should_not_set_the_flash
50
53
  end
51
-
52
- should_respond_with :redirect
53
- should_not_set_the_flash
54
- end
55
-
56
- context "on PUT to #update with valid attributes" do
57
- setup do
58
- page = Factory(:page)
59
- put :update, :id => page.id, :page => page.attributes
54
+
55
+ context "on GET to #show" do
56
+ setup do
57
+ page = Factory(:page)
58
+ get :show, :url => page.url
59
+ end
60
+
61
+ should_respond_with :success
62
+ should_render_template :show
63
+ should_not_set_the_flash
60
64
  end
61
-
62
- should_respond_with :redirect
63
- should_not_set_the_flash
64
- end
65
-
66
- context "on DELETE to #destroy with valid attributes" do
67
- setup do
68
- page = Factory(:page)
69
- delete :destroy, :id => page.id
65
+
66
+ context "on GET to #edit" do
67
+ setup do
68
+ page = Factory(:page)
69
+ get :edit, :id => page.id
70
+ end
71
+
72
+ should_respond_with :success
73
+ should_render_template :edit
74
+ should_not_set_the_flash
70
75
  end
71
-
72
- should_respond_with :redirect
73
- should_not_set_the_flash
74
76
 
75
- should "Destroy the page" do
76
- count = Page.count
77
- page = Factory(:page)
78
- delete :destroy, :id => page.id
79
- assert_equal Page.count, count
77
+ context "on POST to #create with valid attributes" do
78
+ setup do
79
+ page_attributes = Factory.attributes_for(:page)
80
+ post :create, :page => page_attributes
81
+ end
82
+
83
+ should_respond_with :redirect
84
+ should_not_set_the_flash
85
+ should_redirect_to("The list of pages") { pages_url }
86
+ end
87
+
88
+ context "on PUT to #update with valid attributes" do
89
+ setup do
90
+ page = Factory(:page)
91
+ put :update, :id => page.id, :page => page.attributes
92
+ end
93
+
94
+ should_respond_with :redirect
95
+ should_not_set_the_flash
96
+ should_redirect_to("The list of pages") { pages_url }
80
97
  end
98
+
99
+ context "on DELETE to #destroy with valid attributes" do
100
+ setup do
101
+ page = Factory(:page)
102
+ delete :destroy, :id => page.id
103
+ end
104
+
105
+ should_respond_with :redirect
106
+ should_not_set_the_flash
107
+ should_redirect_to("The list of pages") { pages_url }
81
108
 
82
- end
109
+ should "Destroy the page" do
110
+ count = Page.count
111
+ page = Factory(:page)
112
+ delete :destroy, :id => page.id
113
+ assert_equal Page.count, count
114
+ end
115
+
116
+ end
117
+ end
83
118
  end
@@ -42,6 +42,20 @@ class PageTest < ActiveSupport::TestCase
42
42
  assert dup.save
43
43
  assert !dup.errors.on(:url)
44
44
  end
45
+
46
+ should "add suffix and be valid when two different titles generate the same url" do
47
+ page = Factory(:page, :title => 'smurf', :url => 'smurf')
48
+ dup = Factory(:page, :title => 'smurf!', :url => 'buttons')
49
+ assert dup.update_attributes(:url => nil)
50
+ assert_equal 'smurf-1', dup.url
51
+ end
52
+
53
+ should "be valid when a url is a subset of another url" do
54
+ page = Factory(:page, :title => 'smurf', :url => 'woozles')
55
+ dup = Factory(:page, :title => 'Woo', :url => 'brick-spin-brachiosaurus')
56
+ assert dup.update_attributes(:url => nil)
57
+ assert_equal 'woo', dup.url
58
+ end
45
59
 
46
60
  end
47
61
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeffrafter-spreadhead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Rafter
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-17 00:00:00 -07:00
12
+ date: 2009-08-20 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -57,6 +57,7 @@ files:
57
57
  - README.textile
58
58
  - Rakefile
59
59
  - TODO.textile
60
+ - TUTORIAL.textile
60
61
  - VERSION
61
62
  - app/controllers/spreadhead/pages_controller.rb
62
63
  - app/views/spreadhead/pages/_form.html.erb
@@ -77,8 +78,10 @@ files:
77
78
  - generators/spreadhead/templates/page.rb
78
79
  - lib/spreadhead.rb
79
80
  - lib/spreadhead/extensions/routes.rb
81
+ - lib/spreadhead/filter.rb
80
82
  - lib/spreadhead/page.rb
81
83
  - lib/spreadhead/render.rb
84
+ - lib/tasks/spreadhead_tasks.rake
82
85
  - rails/init.rb
83
86
  - test/controllers/pages_controller_test.rb
84
87
  - test/models/page_test.rb