Skip to content
Browse files

Merge branch 'auth-token'

  • Loading branch information...
2 parents b52b141 + 787214f commit 8a8db6cd71f965ab866b3ce651a444694321381c Glenn Murray committed Aug 7, 2008
View
115 Rakefile
@@ -1,25 +1,120 @@
+# I think this is the one that should be moved to the extension Rakefile template
+
+# In rails 1.2, plugins aren't available in the path until they're loaded.
+# Check to see if the rspec plugin is installed first and require
+# it if it is. If not, use the gem version.
+
+# Determine where the RSpec plugin is by loading the boot
+unless defined? RADIANT_ROOT
+ ENV["RAILS_ENV"] = "test"
+ case
+ when ENV["RADIANT_ENV_FILE"]
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
+ else
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
+ end
+end
+
require 'rake'
-require 'rake/testtask'
require 'rake/rdoctask'
+require 'rake/testtask'
-desc 'Default: run unit tests.'
-task :default => :test
+rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
+$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
+require 'spec/rake/spectask'
+# require 'spec/translator'
-desc 'Test the shopping_trike extension.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
+# 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 :stats => "spec:statsetup"
+
+desc "Run all specs in spec directory"
+Spec::Rake::SpecTask.new(:spec) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+end
+
+namespace :spec do
+ desc "Run all specs in spec directory with RCov"
+ Spec::Rake::SpecTask.new(:rcov) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
+ end
+
+ desc "Print Specdoc for all specs"
+ Spec::Rake::SpecTask.new(:doc) do |t|
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ end
+
+ [:models, :controllers, :views, :helpers].each do |sub|
+ desc "Run the specs under spec/#{sub}"
+ Spec::Rake::SpecTask.new(sub) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
+ end
+ end
+
+ # Hopefully no one has written their extensions in pre-0.9 style
+ # desc "Translate specs from pre-0.9 to 0.9 style"
+ # task :translate do
+ # translator = ::Spec::Translator.new
+ # dir = RAILS_ROOT + '/spec'
+ # translator.translate(dir, dir)
+ # end
+
+ # Setup specs for stats
+ task :statsetup do
+ require 'code_statistics'
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
+ ::CodeStatistics::TEST_TYPES << "Model specs"
+ ::CodeStatistics::TEST_TYPES << "View specs"
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
+ end
+
+ namespace :db do
+ namespace :fixtures do
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
+ task :load => :environment do
+ require 'active_record/fixtures'
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
+ end
+ end
+ end
+ end
end
-desc 'Generate documentation for the shopping_trike extension.'
+desc 'Generate documentation for the dentalcorp extension.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
- rdoc.title = 'ShoppingTrikeExtension'
+ rdoc.title = 'DentalcorpExtension'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end
+# For extensions that are in transition
+desc 'Test the dentalcorp extension.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
# Load any custom rakefiles for extension
Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
View
11 app/views/admin/coupon/edit.rhtml
@@ -7,22 +7,22 @@
<h2><%= h @product.code %>: <%= h @product.description %></h2>
-<form method="post" action="">
+<% form_for :coupon, @coupon, :url => '', :method => :post do |f| %>
<table class="fieldset">
<tbody>
<tr>
<td class="label"><label for="coupon_code">Code</label></td>
- <td class="field"><%= text_field :coupon, :code, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :code, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. Only numbers and letters allowed</td>
</tr>
<tr>
<td class="label"><label class="optional" for="coupon_expiration_date">Expiration Date</label></td>
- <td class="field"><%= text_field :coupon, :expiration_date, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :expiration_date, :size => 100, :class => 'textbox' %></td>
<td class="help">Optional, enter as yyyy-mm-dd (4 digit year, 2 digit month, 2 digit day)</td>
</tr>
<tr>
<td class="label"><label for="coupon_discount_per_order">Discount per order</label></td>
- <td class="field"><%= text_field :coupon, :discount_per_order, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :discount_per_order, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. Discount per order (regardless of product count in order) in dollars and cents.</td>
</tr>
</tbody>
@@ -32,7 +32,6 @@
<%= save_model_and_continue_editing_button(@coupon) %>
or <%= link_to "Cancel", product_index_url %>
</p>
-
-</form>
+<% end %>
<%= focus 'coupon_code' %>
View
11 app/views/admin/product/edit.rhtml
@@ -4,22 +4,22 @@
<h1>Edit Product</h1>
<% end -%>
-<form method="post" action="">
+<% form_for :product, @product, :url => '', :method => :post do |f| %>
<table class="fieldset">
<tbody>
<tr>
<td class="label"><label for="product_code">Code</label></td>
- <td class="field"><%= text_field :product, :code, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :code, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. Only numbers and letters allowed</td>
</tr>
<tr>
<td class="label"><label class="optional" for="product_description">Description</label></td>
- <td class="field"><%= text_area :product, :description, :size => '40x4' %></td>
+ <td class="field"><%= f.text_area :description, :size => '40x4' %></td>
<td class="help">Optional</td>
</tr>
<tr>
<td class="label"><label for="product_product_category">Product Category</label></td>
- <td class="field"><%= text_field :product, :product_category, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :product_category, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. One of <%= currently_used_product_categories %></td>
</tr>
</tbody>
@@ -29,7 +29,6 @@
<%= save_model_and_continue_editing_button(@product) %>
or <%= link_to "Cancel", product_index_url %>
</p>
-
-</form>
+<% end %>
<%= focus 'product_code' %>
View
6 app/views/admin/product/remove.rhtml
@@ -9,12 +9,12 @@
onmouseout="Element.removeClassName(this, 'highlight');">
<td class="code"><%= link_to h(@product.code), product_edit_path(:id => @product) %></td>
<td class="description"><%= link_to @product.description, product_edit_path(:id => @product) %></td>
- <td class="product_category"><%= link_to product.product_category, product_edit_path(:id => product) %></td>
+ <td class="product_category"><%= link_to @product.product_category, product_edit_path(:id => @product) %></td>
</tr>
</tbody>
</table>
-<form method="post" action="">
+<% form_tag '' do %>
<p class="buttons"><%= submit_tag "Delete Product", :class => 'button' %>
or <%= link_to 'Cancel', product_index_path %></p>
-</form>
+<% end %>
View
9 app/views/admin/product_price/edit.rhtml
@@ -7,17 +7,17 @@
<h2><%= h @product.code %>: <%= h @product.description %></h2>
-<form method="post" action="">
+<% form_for :product_price, @product_price, :url => '', :method => :post do |f| %>
<table class="fieldset">
<tbody>
<tr>
<td class="label"><label for="product_price_min_quantity">Minimum Quantity</label></td>
- <td class="field"><%= text_field :product_price, :min_quantity, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :min_quantity, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. Only numbers allowed.</td>
</tr>
<tr>
<td class="label"><label for="product_price_price">Price</label></td>
- <td class="field"><%= text_field :product_price, :price, :size => 100, :class => 'textbox' %></td>
+ <td class="field"><%= f.text_field :price, :size => 100, :class => 'textbox' %></td>
<td class="help">Required. Price at or above Minimum Quantity in dollars and cents.</td>
</tr>
</tbody>
@@ -27,7 +27,6 @@
<%= save_model_and_continue_editing_button(@product_price) %>
or <%= link_to "Cancel", product_index_url %>
</p>
-
-</form>
+<% end %>
<%= focus 'product_price_min_quantity' %>
View
1 shopping_trike_extension.rb
@@ -23,6 +23,7 @@ class ShoppingTrikeExtension < Radiant::Extension
product_price.product_price_remove 'admin/product_prices/remove/:id', :action => 'remove'
end
map.with_options(:controller => 'admin/coupon') do |coupon|
+ # radiant does things very different. edit is edit AND new, and is POSTed to both, not PUT
coupon.coupon_edit 'admin/coupons/edit/:id', :action => 'edit'
coupon.coupon_new 'admin/products/:product_id/coupons/new', :action => 'new'
coupon.coupon_remove 'admin/coupons/remove/:id', :action => 'remove'
View
85 spec/shared/edit_page.rb
@@ -0,0 +1,85 @@
+shared_examples_for 'edit_page' do
+ # USAGE:
+ # def instance
+ # Object.new
+ # end
+ # def self.fields
+ # {:name => 'john'}
+ # end
+ def action
+ 'edit'
+ end
+
+ it_should_behave_like 'protected_from_forgery'
+
+ it 'should successfully render' do
+ render_page
+
+ response.should be_success
+ end
+
+ it 'should only have one form' do
+ # otherwise these tests would be invalid (you could give the form an ID to revalidate them)
+ render_page
+
+ response.should have_tag('form', :count => 1)
+ end
+
+ it 'should ask for new record (for form builder)' do
+ @object.should_receive(:new_record?).at_least(:once).and_return(false)
+
+ render_page
+ end
+
+ describe 'form' do
+ describe 'input fields' do
+ fields.each do |field, value|
+ it 'should include #{field}' do
+ @object.send "#{field}=", value
+ render_page
+
+ response.should have_tag("form") do
+ with_tag("input[type='text'][name='#{class_symbol}[#{field}]'][value=?]", value)
+ end
+ end
+ end
+ end
+
+ describe 'for existing' do
+ before(:each) do
+ @object.stub!(:new_record?).and_return false
+ end
+ it 'should submit to itself' do
+ # Posting to '' is kinda silly but is the RADIANT way. Should be using RESTful routing
+ render_page
+ response.should have_tag("form[action='']")
+ end
+ it 'should use post method' do
+ render_page
+ response.should have_tag("form[method=post]")
+ end
+ it 'should not "put"' do
+ render_page
+
+ response.should have_tag("form") do
+ without_tag "input[name='_method'][type='hidden'][value='put']"
+ end
+ end
+ end
+
+ describe 'on new' do
+ before(:each) do
+ @object.stub!(:new_record?).and_return true
+ end
+ it 'should submit to itself' do
+ # Posting to '' is kinda silly. Should be using RESTful routing
+ render_page
+ response.should have_tag("form[action='']")
+ end
+ it 'should use post method' do
+ render_page
+ response.should have_tag("form[method=post]")
+ end
+ end
+ end
+end
View
38 spec/shared/protected_from_forgery.rb
@@ -0,0 +1,38 @@
+shared_examples_for 'protected_from_forgery' do
+ # USAGE:
+ # def instance
+ # Object.new
+ # end
+ # def action
+ # 'edit'
+ # end
+ def render_page
+ render "/admin/#{class_symbol}/#{action}"
+ end
+
+ def class_symbol
+ instance.class.name.underscore.to_sym
+ end
+
+ before(:each) do
+ @object = instance
+ assigns[class_symbol] = @object
+ end
+
+ describe 'authenticity token' do
+ it 'should be used' do
+ template.should_receive(:form_authenticity_token)
+
+ render_page
+ end
+
+ it 'should be included in a hidden input' do
+ template.stub!(:form_authenticity_token).and_return('MY SUPER SECRET TOKEN')
+ render_page
+
+ response.should have_tag("form") do
+ with_tag("input[type='hidden'][name='authenticity_token'][value=?]", 'MY SUPER SECRET TOKEN')
+ end
+ end
+ end
+end
View
6 spec/spec.opts
@@ -0,0 +1,6 @@
+--colour
+--format
+progress
+--loadby
+mtime
+--reverse
View
40 spec/spec_helper.rb
@@ -0,0 +1,40 @@
+unless defined? RADIANT_ROOT
+ ENV["RAILS_ENV"] = "test"
+ case
+ when ENV["RADIANT_ENV_FILE"]
+ require ENV["RADIANT_ENV_FILE"]
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
+ else
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
+ end
+end
+require "#{RADIANT_ROOT}/spec/spec_helper"
+
+if File.directory?(File.dirname(__FILE__) + "/scenarios")
+ Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios"
+end
+if File.directory?(File.dirname(__FILE__) + "/matchers")
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
+end
+if File.directory?(File.dirname(__FILE__) + "/shared")
+ Dir[File.dirname(__FILE__) + "/shared/*.rb"].each {|file| require file }
+end
+
+Spec::Runner.configure do |config|
+ # config.use_transactional_fixtures = true
+ # config.use_instantiated_fixtures = false
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
+
+ # You can declare fixtures for each behaviour like this:
+ # describe "...." do
+ # fixtures :table_a, :table_b
+ #
+ # Alternatively, if you prefer to declare them only once, you can
+ # do so here, like so ...
+ #
+ # config.global_fixtures = :table_a, :table_b
+ #
+ # If you declare global fixtures, be aware that they will be declared
+ # for all of your examples, even those that don't use them.
+end
View
17 spec/views/admin/coupon/edit.rhtml_spec.rb
@@ -0,0 +1,17 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe 'admin/coupon/edit' do
+ def instance
+ Coupon.new(:product => Product.new)
+ end
+
+ def self.fields
+ {
+ :code => 'CODE',
+ :expiration_date => '2008-01-01',
+ :discount_per_order => 250.0
+ }
+ end
+
+ it_should_behave_like 'edit_page'
+end
View
17 spec/views/admin/product/edit.rhtml_spec.rb
@@ -0,0 +1,17 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe 'admin/product/edit' do
+ def instance
+ Product.new
+ end
+
+ def self.fields
+ {
+ :code => 'CODE',
+ # :description => 'a description', # need text_area checking instead
+ :product_category => 'bCisive'
+ }
+ end
+
+ it_should_behave_like 'edit_page'
+end
View
8 spec/views/admin/product/remove.rhtml_spec.rb
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe 'admin/product/remove' do
+ def instance; Product.new; end
+ def action; 'remove'; end
+
+ it_should_behave_like 'protected_from_forgery'
+end
View
16 spec/views/admin/product_price/edit.rhtml_spec.rb
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe 'admin/product_price/edit' do
+ def instance
+ ProductPrice.new(:product => Product.new)
+ end
+
+ def self.fields
+ {
+ :min_quantity => 100,
+ :price => 49.95
+ }
+ end
+
+ it_should_behave_like 'edit_page'
+end

0 comments on commit 8a8db6c

Please sign in to comment.
Something went wrong with that request. Please try again.