Skip to content

Commit

Permalink
Use nested attributes to save, reorder attachments. Test with cucumbe…
Browse files Browse the repository at this point in the history
…r + webrat + selenium
  • Loading branch information
jgarber committed Sep 1, 2009
1 parent a6bd78a commit 8105853
Show file tree
Hide file tree
Showing 26 changed files with 284 additions and 139 deletions.
15 changes: 4 additions & 11 deletions README.md
Expand Up @@ -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
Expand All @@ -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
---

Expand Down
9 changes: 8 additions & 1 deletion Rakefile
Expand Up @@ -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"
Expand All @@ -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|
Expand Down
32 changes: 0 additions & 32 deletions app/controllers/page_attachments_controller.rb

This file was deleted.

17 changes: 1 addition & 16 deletions app/models/page_attachment_associations.rb
Expand Up @@ -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

Expand All @@ -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
3 changes: 2 additions & 1 deletion app/models/page_attachments_interface.rb
Expand Up @@ -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
Expand Down
19 changes: 0 additions & 19 deletions app/views/admin/pages/_attachment.html.erb

This file was deleted.

12 changes: 12 additions & 0 deletions app/views/admin/pages/_attachment.html.haml
@@ -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
15 changes: 0 additions & 15 deletions app/views/admin/pages/_attachments_box.html.erb

This file was deleted.

12 changes: 12 additions & 0 deletions app/views/admin/pages/_attachments_box.html.haml
@@ -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;"}
42 changes: 42 additions & 0 deletions features/attachments.feature
@@ -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
61 changes: 61 additions & 0 deletions features/step_definitions/attachment_steps.rb
@@ -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
57 changes: 57 additions & 0 deletions features/support/env.rb
@@ -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
14 changes: 14 additions & 0 deletions features/support/paths.rb
@@ -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
4 changes: 2 additions & 2 deletions lib/tasks/page_attachments_extension_tasks.rake
Expand Up @@ -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
Expand Down
Binary file added public/images/admin/drag_order.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/admin/move_higher.png
Binary file not shown.
Binary file removed public/images/admin/move_lower.png
Binary file not shown.

0 comments on commit 8105853

Please sign in to comment.