Permalink
Browse files

Use nested attributes to save, reorder attachments. Test with cucumbe…

…r + webrat + selenium
  • Loading branch information...
1 parent a6bd78a commit 8105853c35071712ab130e668d14e813a95f5ebe @jgarber jgarber committed Aug 23, 2009
View
@@ -11,15 +11,6 @@ Installation
If you want `page_attachments` to generate and display thumbnails of your uploaded images you'll first need to install one of, [`image_science`][is], [`mini-magick`][mm] or [`rmagick`][rm] on your server. This is completely optional, `page_attachments` will still function in every other way without any of these packages installed.
-Next, you need to install the `attachment_fu` plugin.
-
- cd /path/to/radiant
- git clone git://github.com/technoweenie/attachment_fu.git vendor/plugins/attachment_fu
-
-If you don't have `git` installed you can simply [download a tarball][af] of `attachment_fu`, upload and unpack it to your `vendor/plugins` directory.
-
-**Failing to install the `attachment_fu` plugin before proceeding will result in an "`uninitialized constant Technoweenie::AttachmentFu`" error when you try to install `page_attachments`.**
-
Now you're ready to install `page_attachments`.
cd /path/to/radiant
@@ -29,15 +20,17 @@ Now you're ready to install `page_attachments`.
If you don't have `git` you can [download a tarball][pa].
-During the `migrate` task you may encounter an "`uninitialized constant Technoweenie::AttachmentFu::Backends`". If this happens try `git clone git://github.com/technoweenie/attachment_fu.git vendor/extensions/page_attachments/vendor/plugins/attachment_fu` and re-run the `migrate` task.
-
Attachment thumbnails for images default to `:icon => '50x50>'`. You can customize that by setting
`PAGE_ATTACHMENT_SIZES` to whatever you need in your `config/environment.rb` file
PAGE_ATTACHMENT_SIZES = {:thumb => '120x120>', :normal => '640x480>'}
Restart your server and refresh the admin interface.
+Running features and specs
+---
+The Cucumber features use Webrat and Selenium. You'll need the webrat 0.5.1 and selenium-client 1.2.16 gems installed and you'll need to change the version of webrat specified in environments/test.rb.
+
Managing Attachments
---
View
@@ -26,12 +26,15 @@ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
require 'spec/rake/spectask'
# require 'spec/translator'
+$:.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
+require 'cucumber/rake/task'
+
# Cleanup the RADIANT_ROOT constant so specs will load the environment
Object.send(:remove_const, :RADIANT_ROOT)
extension_root = File.expand_path(File.dirname(__FILE__))
-task :default => :spec
+task :default => [:features, :spec]
task :stats => "spec:statsetup"
desc "Run all specs in spec directory"
@@ -40,6 +43,10 @@ Spec::Rake::SpecTask.new(:spec) do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
end
+Cucumber::Rake::Task.new(:features) do |t|
+ t.cucumber_opts = "--format progress"
+end
+
namespace :spec do
desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
@@ -1,32 +0,0 @@
-class PageAttachmentsController < ApplicationController
- def move_higher
- if request.post?
- @attachment = PageAttachment.find(params[:id])
- @attachment.move_higher
- render :partial => 'admin/pages/attachment',
- :layout => false,
- :collection => @attachment.page.attachments
- end
- end
-
- def move_lower
- if request.post?
- @attachment = PageAttachment.find(params[:id])
- @attachment.move_lower
- render :partial => 'admin/pages/attachment',
- :layout => false,
- :collection => @attachment.page.attachments
- end
- end
-
- def destroy
- if request.post?
- @attachment = PageAttachment.find(params[:id])
- page = @attachment.page
- @attachment.destroy
- render :partial => 'admin/pages/attachment',
- :layout => false,
- :collection => page.attachments
- end
- end
-end
@@ -5,9 +5,8 @@ def self.included(base)
:class_name => "PageAttachment",
:dependent => :destroy,
:order => 'position'
- attr_accessor :add_attachments
- after_save :save_attachments
include InstanceMethods
+ accepts_nested_attributes_for :attachments, :allow_destroy => true
}
end
@@ -17,19 +16,5 @@ def attachment(name)
att = attachments.find(:first, :conditions => ["filename LIKE ?", name.to_s])
att.blank? ? ((parent.attachment(name) if parent) or nil) : att
end
-
- def save_attachments
- if @add_attachments && ! @add_attachments['file'].blank?
- i = 0
- @add_attachments['file'].each do |page_attach|
- attach = PageAttachment.new(:uploaded_data => page_attach)
- attach.title = @add_attachments['title'][i]
- attach.description = @add_attachments['description'][i]
- attachments << attach
- i += 1
- end
- end
- @add_attachments = nil
- end
end
end
@@ -11,7 +11,8 @@ module InstanceMethods
def add_page_attachment_partials
@buttons_partials ||= []
@buttons_partials << "attachments_box"
- include_javascript 'page_attachments'
+ include_javascript 'admin/page_attachments'
+ include_javascript 'dragdrop'
include_stylesheet 'admin/page_attachments'
end
end
@@ -1,19 +0,0 @@
-<li id="attachment_<%= attachment.id %>" class="attachment clearfix">
-<div>
- <%= image_tag "admin/minus.png", :alt => "Delete", :class => 'delete' %>
- <% unless attachment.first? %>
- <%= image_tag "admin/move_higher.png", :alt => "Move Higher", :class => 'higher' %>
- <% end %>
- <% unless attachment.last? %>
- <%= image_tag "admin/move_lower.png", :alt => "Move Lower", :class => 'lower' %>
- <% end %>
-</div>
-<% unless attachment.thumbnails.empty? %>
-<%= link_to image_tag(attachment.public_filename("icon")),
-attachment.public_filename, :class => 'thumbnail' %>
-<% end %>
-<% unless attachment.title.blank? %>
-<p><%= h attachment.short_title %></p>
-<% end %>
-<%= link_to attachment.short_filename, attachment.public_filename %>
-</li>
@@ -0,0 +1,12 @@
+%li{:id => "attachment_#{attachment.id}", :class =>"attachment clearfix"}
+ = hidden_field_tag "page[attachments_attributes][#{attachment_counter}][id]", attachment.id
+ = hidden_field_tag "page[attachments_attributes][#{attachment_counter}][_delete]", "0"
+ = hidden_field_tag "page[attachments_attributes][#{attachment_counter}][position]", attachment.position
+ - unless attachment.first? && attachment.last?
+ = image_tag 'admin/drag_order.png', :alt => "Drag handle", :title => "Drag to change order", :class => 'drag-order'
+ %div= image_tag "admin/minus.png", :alt => "Delete", :class => 'delete'
+ - unless attachment.thumbnails.empty?
+ = link_to image_tag(attachment.public_filename("icon")), attachment.public_filename, :class => 'thumbnail'
+ - unless attachment.title.blank?
+ %p= h attachment.short_title
+ = link_to attachment.short_filename, attachment.public_filename
@@ -1,15 +0,0 @@
-<div id="attachments">
- <div class="toolbar">
- <%= image_tag('admin/plus.png', :alt => 'Add') %>
- </div>
- <h3>Attachments (<span id="attachment_count"><%= @page.attachments.count %></span>)</h3>
-
- <%= javascript_tag "var auth_token = '#{form_authenticity_token}';" %>
- <% unless @page.attachments.count.zero? %>
- <ol id="attachment_list">
- <%= render :partial => 'attachment', :collection => @page.attachments %>
- </ol>
- <div style="clear:both;"></div>
- <% end %>
- <p id="reorder_notice" style="display:none;">Page attachments order will appear on site only when cache is cleared (on save or after 5min).</p>
-</div>
@@ -0,0 +1,12 @@
+#attachments
+ .toolbar
+ = image_tag('admin/plus.png', :alt => 'Add')
+ = hidden_field_tag('attachment_index', @page.attachments.size, :id => 'attachment-index-field')
+ %h3
+ Attachments (
+ %span#attachment_count>= @page.attachments.count
+ )
+ - unless @page.attachments.count.zero?
+ %ol#attachment_list
+ = render :partial => 'attachment', :collection => @page.attachments
+ %div{:style => "clear:both;"}
@@ -0,0 +1,42 @@
+Feature: attachments
+ As a content editor
+ I should be able to add, reorder, and delete attachments
+
+ Background:
+ Given I am logged in as admin
+
+ Scenario: attach a file
+ Given I have a page with no attachments
+ When I edit the page
+ And I click the plus icon
+ And I attach the Rails logo
+ And I save
+ Then the page should have a new attachment
+
+ Scenario: don't change attachments
+ Given I have a page with 2 attachments
+ When I edit the page
+ And I save
+ Then the page should have 2 attachments
+
+ Scenario: attach another file
+ Given I have a page with 2 attachments
+ When I edit the page
+ And I click the plus icon
+ And I attach the Rails logo
+ And I save
+ Then the page should have 3 attachments
+
+ Scenario: delete a file
+ Given I have a page with 2 attachments
+ When I edit the page
+ And I delete the first attachment
+ And I save
+ Then the page should have 1 attachment
+
+ Scenario: reorder attachments
+ Given I have a page with 2 attachments
+ When I edit the page
+ And I drag attachment 2 above attachment 1
+ And I save
+ Then attachment 2 should be in position 1
@@ -0,0 +1,61 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
+
+Given /^I am logged in as (.*)(?: user)?$/ do |username|
+ visit login_path
+ fill_in "Username", :with => username
+ fill_in "Password", :with => "password"
+ click_button "Login"
+end
+
+Given /^I have a page$/ do
+ @page = pages(:home)
+end
+
+Given /^I have a page with (\d+) attachments$/ do |number|
+ Given "I have a page"
+ @page.attachments.length.should == number.to_i
+end
+
+Given /^I have a page with no attachments$/ do
+ @page = pages(:first)
+ @page.attachments.should be_empty
+end
+
+When /^I edit the page$/ do
+ visit edit_admin_page_path(@page)
+end
+
+When /^I click the plus icon$/ do
+ selenium.click "xpath=id('attachments')//img[@alt='Add']"
+end
+
+When /^I attach the Rails logo$/ do
+ attach_file "file_input", "#{PageAttachmentsExtension.root}/spec/fixtures/rails.png"
+end
+
+When /^I delete the first attachment$/ do
+ selenium.click "xpath=id('attachment_list')/li[1]//img[@alt='Delete']"
+end
+
+When /^I drag attachment 2 above attachment 1$/ do
+ @attachment = @page.attachments[1]
+ @attachment.position.should == 2
+ selenium.dragdrop("id=attachment_#{@attachment.id}", "0, -200")
+end
+
+When /^I save$/ do
+ click_button "Save"
+ response.should_not contain("errors")
+end
+
+Then /^the page should have a new attachment$/ do
+ @page.reload.attachments.should_not be_empty
+end
+
+Then /^the page should have (\d+) attachment(?:s)?$/ do |number|
+ @page.reload.attachments.length.should == number.to_i
+end
+
+Then /^attachment 2 should be in position 1$/ do
+ @attachment.reload.position.should == 1
+end
View
@@ -0,0 +1,57 @@
+# Sets up the Rails environment for Cucumber
+ENV["RAILS_ENV"] = "test"
+require File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
+
+require 'cucumber/rails/world'
+require 'cucumber/formatter/unicode' # Comment out this line if you don't want Cucumber Unicode support
+require 'webrat'
+raise "Update the version of Webrat you specify in test.rb." if Webrat.const_defined?(:VERSION) && Webrat::VERSION < '0.5.1' # Webrat 0.4.4 won't work with selenium-client 1.2.16
+
+Webrat.configure do |config|
+ config.mode = :selenium
+ config.selenium_browser_key = "*chrome"
+end
+
+# this is necessary to have webrat "wait_for" the response body to be available
+# when writing steps that match against the response body returned by selenium
+World(Webrat::Selenium::Matchers)
+
+# Patch in attach_file functionality
+module Webrat
+ class SeleniumSession
+ def attach_file(field_locator, path, content_type = nil)
+ fill_in(field_locator, :with => path)
+ end
+ end
+end
+
+require 'cucumber/rails/rspec'
+require 'dataset'
+
+module Dataset
+ module Extensions # :nodoc:
+ # Selenium can't handle transactions, so we have to disable them in Dataset
+ module CucumberWorldNoTransactions # :nodoc:
+ def dataset(*datasets, &block)
+ add_dataset(*datasets, &block)
+
+ load = nil
+ $__cucumber_toplevel.Before do
+ Dataset::Database::Base.new.clear # Empty all tables
+ dataset_session.instance_variable_set("@load_stack", []) # notify load_stack that nothing's loaded
+ load = dataset_session.load_datasets_for(self.class)
+ extend_from_dataset_load(load)
+ end
+ end
+ end
+ end
+end
+
+Cucumber::Rails::World.class_eval do
+ include Dataset
+ self.extend Dataset::Extensions::CucumberWorldNoTransactions
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
+ Dataset::Resolver.default << (File.dirname(__FILE__) + "/../../spec/datasets")
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
+ dataset :pages_with_layouts, :users, :page_attachments
+end
View
@@ -0,0 +1,14 @@
+def path_to(page_name)
+ case page_name
+
+ when /the homepage/i
+ root_path
+
+ when /edit the page/i
+ edit_admin_page_path(@page)
+ # Add more page name => path mappings here
+
+ else
+ raise "Can't find mapping from \"#{page_name}\" to a path."
+ end
+end
@@ -19,8 +19,8 @@ namespace :radiant do
Dir[PageAttachmentsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
path = file.sub(PageAttachmentsExtension.root, '')
directory = File.dirname(path)
- mkdir_p RAILS_ROOT + directory, :verbose => false
- cp file, RAILS_ROOT + path, :verbose => false
+ mkdir_p RAILS_ROOT + directory
+ cp file, RAILS_ROOT + path
end
end
end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Deleted file not rendered
Deleted file not rendered
Oops, something went wrong.

0 comments on commit 8105853

Please sign in to comment.