diff --git a/Gemfile b/Gemfile index d272462..4e3bea9 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,6 @@ group :test do end end -gem 'spree', '~> 1.1.1' +gem 'spree', '~> 1.1.2' gemspec diff --git a/README.textile b/README.textile index a75ff35..99c881e 100644 --- a/README.textile +++ b/README.textile @@ -15,6 +15,7 @@ The idea is simple. You attach a file to a Product (or a Variant of this Product * The file @views/order_mailer/confirm_email.text.erb@ is the only thing that should need customization. But since I assume you do that anyway, it doesn't hurt to do it when you're using spree_digital. The reason is that the download links are added to the confirmation email to the customer. "http://github.com/iloveitaly/spree-html-email":http://github.com/iloveitaly/spree-html-email also supports spree_digital. * A purchased product can be downloaded even if you disable the product immediately. You would have to remove the attached file in your admin section to prevent people from downloading purchased products. * File are uploaded to @rails_root/private@. Make sure it's symlinked in case you're using Capistrano. +* You must add a views/spree/digitals/unauthorized.html.erb file to present an error message to the user if they exceed the download / days limit * We use send_file to send the files on download. Yes, it goes through the entire stack right now. h2. Installation diff --git a/app/controllers/spree/digitals_controller.rb b/app/controllers/spree/digitals_controller.rb index a5ddf86..2c00a53 100644 --- a/app/controllers/spree/digitals_controller.rb +++ b/app/controllers/spree/digitals_controller.rb @@ -1,16 +1,25 @@ module Spree class DigitalsController < Spree::BaseController - ssl_required :show def show link = DigitalLink.find_by_secret(params[:secret]) + if link.present? and link.digital.attachment.present? attachment = link.digital.attachment - if link.authorize! and File.file?(attachment.path) - send_file attachment.path, :filename => attachment.original_filename, :type => attachment.content_type and return + + # don't authorize the link unless the file exists + # the logger error will help track down customer issues easier + + if File.file?(attachment.path) + if link.authorize! + send_file attachment.path, :filename => attachment.original_filename, :type => attachment.content_type and return + end + else + Rails.logger.error "Missing Digital Item: #{attachment.path}" end end + render :unauthorized end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 5ac00de..8982712 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -10,12 +10,13 @@ Spree::Order.class_eval do false end + # UPGRADE_CHECK # TODO this works as of spree 1.1.1; make sure to check the original function on upgrade def available_shipping_methods(display_on = nil) return [] unless ship_address all_methods = Spree::ShippingMethod.all_available(self, display_on) - + puts "ALL METHODS #{all_methods.count} #{display_on}" if self.digital? all_methods.detect { |m| m.calculator.class == Spree::Calculator::DigitalDelivery }.try { |d| [d] } || all_methods else diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index e090aa4..6a17d57 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -14,7 +14,7 @@ Spree::Variant.class_eval do # We need to delete the Digital manually here as soon as the Variant is nullified. # Otherwise you'll have orphan Digitals (and their attached files!) associated with unused Variants. def destroy_digital - digital.destroy + digitals.map &:destroy end end diff --git a/spec/factories/digital_factory.rb b/spec/factories/digital_factory.rb index c8e6f3c..0250802 100644 --- a/spec/factories/digital_factory.rb +++ b/spec/factories/digital_factory.rb @@ -1,5 +1,6 @@ FactoryGirl.define do factory :digital, :class => Spree::Digital do |f| - f.variant { |p| p.association(:variant) } + # TODO good to assign variant association if no association is manually defined + # f.variant { |p| p.association(:variant) } end end \ No newline at end of file diff --git a/spec/factories/digital_shipping_factory.rb b/spec/factories/digital_shipping_factory.rb new file mode 100644 index 0000000..10f5afc --- /dev/null +++ b/spec/factories/digital_shipping_factory.rb @@ -0,0 +1,12 @@ +FactoryGirl.define do + # https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#modifying-factories + + factory :digital_shipping_calculator, class: Spree::Calculator::DigitalDelivery do |c| + after_create { |c| c.set_preference(:amount, 0) } + end + + factory :digital_shipping_method, parent: :shipping_method do |f| + name "Digital Delivery" + calculator { FactoryGirl.build :digital_shipping_calculator } + end +end \ No newline at end of file diff --git a/spec/models/order_spec.rb b/spec/models/order_spec.rb index 9600aa0..554409d 100644 --- a/spec/models/order_spec.rb +++ b/spec/models/order_spec.rb @@ -52,15 +52,37 @@ describe Spree::Order do context "digital shipping" do before do - # TODO create digital shipping factory + @order = FactoryGirl.create(:order) + # need shipp_address for rate_hash.count != 0 + @order.ship_address = FactoryGirl.create :address + @order.bill_address = FactoryGirl.create :address + @order.save! + + 3.times { @order.add_variant FactoryGirl.create(:variant, :digitals => [FactoryGirl.create(:digital)]) } + + FactoryGirl.create :digital_shipping_method + s = FactoryGirl.create :shipping_method + s.calculator.set_preference(:amount, 10) end + let(:order) { @order } + it "should only offer digital shipping if all items are digital" do - + order.digital?.should be_true + order.rate_hash.count.should == 1 + order.rate_hash.first.shipping_method.calculator.class.should == Spree::Calculator::DigitalDelivery + order.rate_hash.first.cost.should == 0.0 end it "should not offer digital shipping if only some items are digital" do - + order.digital?.should be_true + order.add_variant FactoryGirl.create(:variant) # this is the analog product + order.digital?.should be_false + + order.rate_hash.count.should == 1 + order.rate_hash.first.shipping_method.calculator.class.should_not == Spree::Calculator::DigitalDelivery + puts "SHIPP #{order.rate_hash.first}" + order.rate_hash.first.cost.should == 10.0 end end