spree_wishlist 1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +4 -0
  3. data/.travis.yml +14 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE +23 -0
  6. data/README.md +31 -0
  7. data/Rakefile +19 -0
  8. data/Versionfile +4 -0
  9. data/app/assets/javascripts/store/spree_wishlist.js +21 -0
  10. data/app/assets/stylesheets/store/spree_wishlist.css +2 -0
  11. data/app/controllers/spree/wished_products_controller.rb +37 -0
  12. data/app/controllers/spree/wishlists_controller.rb +48 -0
  13. data/app/models/spree/user_decorator.rb +11 -0
  14. data/app/models/spree/wished_product.rb +4 -0
  15. data/app/models/spree/wishlist.rb +40 -0
  16. data/app/overrides/add_wish_to_cart_form.rb +5 -0
  17. data/app/overrides/add_wishlists_to_account_my_orders.rb +5 -0
  18. data/app/views/spree/products/_wishlist_form.html.erb +10 -0
  19. data/app/views/spree/users/_wishlists.html.erb +8 -0
  20. data/app/views/spree/wishlists/_accessibility.html.erb +4 -0
  21. data/app/views/spree/wishlists/_mail_to_friend.html.erb +14 -0
  22. data/app/views/spree/wishlists/edit.html.erb +7 -0
  23. data/app/views/spree/wishlists/new.html.erb +6 -0
  24. data/app/views/spree/wishlists/show.html.erb +84 -0
  25. data/app/views/spree/wishlists/update.js.erb +0 -0
  26. data/config/locales/de.yml +26 -0
  27. data/config/locales/en.yml +26 -0
  28. data/config/locales/ru.yml +27 -0
  29. data/config/routes.rb +5 -0
  30. data/config/spree_permissions.yml +25 -0
  31. data/db/migrate/20091020182940_create_wishlists.rb +17 -0
  32. data/db/migrate/20091020183520_create_wished_products.rb +15 -0
  33. data/db/migrate/20111130204731_prefix_wishlist_tables_with_spree.rb +6 -0
  34. data/db/seeds.rb +2 -0
  35. data/lib/generators/spree_wishlist/install/install_generator.rb +27 -0
  36. data/lib/spree_wishlist.rb +3 -0
  37. data/lib/spree_wishlist/engine.rb +20 -0
  38. data/lib/wishlist_ability.rb +35 -0
  39. data/spec/controllers/spree/wished_products_controller_spec.rb +10 -0
  40. data/spec/controllers/spree/wishlists_controller_spec.rb +10 -0
  41. data/spec/lib/wishlist_ability_spec.rb +97 -0
  42. data/spec/models/spree/wished_product_spec.rb +11 -0
  43. data/spec/models/spree/wishlist_spec.rb +75 -0
  44. data/spec/spec_helper.rb +19 -0
  45. data/spree_wishlist.gemspec +25 -0
  46. metadata +151 -0
@@ -0,0 +1,4 @@
1
+ spec/dummy
2
+ spec/test_app
3
+ Gemfile.lock
4
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ mtime
@@ -0,0 +1,14 @@
1
+ before_script:
2
+ - "bundle exec rake test_app"
3
+ script: "DISPLAY=:99.0 bundle exec rspec spec"
4
+ notifications:
5
+ email:
6
+ - jdyer@spreecommerce.com
7
+ irc: "irc.freenode.org#spree"
8
+ branches:
9
+ only:
10
+ - master
11
+ rvm:
12
+ - 1.8.7
13
+ - 1.9.3
14
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :test do
4
+ gem 'faker'
5
+ end
6
+
7
+ # Specify your dependencies in spree_wishlist.gemspec
8
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Redistribution and use in source and binary forms, with or without modification,
2
+ are permitted provided that the following conditions are met:
3
+
4
+ * Redistributions of source code must retain the above copyright notice,
5
+ this list of conditions and the following disclaimer.
6
+ * Redistributions in binary form must reproduce the above copyright notice,
7
+ this list of conditions and the following disclaimer in the documentation
8
+ and/or other materials provided with the distribution.
9
+ * Neither the name of the Rails Dog LLC nor the names of its
10
+ contributors may be used to endorse or promote products derived from this
11
+ software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,31 @@
1
+ # Spree Wishlist extension
2
+
3
+ [![Build
4
+ Status](https://secure.travis-ci.org/spree/spree_wishlist.png)](http://travis-ci.org/spree/spree_wishlist)
5
+
6
+ The Spree Wishlist extension enables multiple wishlists per user, as well as managing those
7
+ as public (sharable) and private. It also includes the ability to notify a friend via email
8
+ of a recommended product.
9
+
10
+ ## Installation
11
+
12
+ 1. Add the following to your Gemfile
13
+
14
+ <pre>
15
+ gem 'spree_wishlist', '~> 1.3'
16
+ gem 'spree_email_to_friend'
17
+ </pre>
18
+
19
+ 2. Run `bundle install`
20
+
21
+ 3. To setup the asset pipeline includes and copy migrations run: `rails g spree_wishlist:install`
22
+
23
+ ## Development
24
+
25
+ * Fork the repo
26
+ * clone your repo
27
+ * Run `bundle`
28
+ * Run `bundle exec rake test_app` to create the test application in `spec/test_app`.
29
+ * Make your changes.
30
+ * Ensure specs pass by running `bundle exec rake`
31
+ * Submit your pull request
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+ Bundler.setup
6
+
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new
9
+
10
+ require 'spree/core/testing_support/common_rake'
11
+
12
+ desc "Default Task"
13
+ task :default => [:spec]
14
+
15
+ desc "Generates a dummy app for testing"
16
+ task :test_app do
17
+ ENV['LIB_NAME'] = 'spree_wishlist'
18
+ Rake::Task['common:test_app'].invoke
19
+ end
@@ -0,0 +1,4 @@
1
+ "1.0.x" => { :version => "1.3", :tag => "v1.3" }
2
+ "0.70.x" => { :ref => "0400d9e7c85f4ad637ac", :version => "1.2" }
3
+ "0.60.x" => { :ref => "5172de86dd46905e6d60288584b567155055675e", :version => "1.1" }
4
+ "0.50.x" => { :ref => "5172de86dd46905e6d60288584b567155055675e", :version => "1.1" }
@@ -0,0 +1,21 @@
1
+ $(function() {
2
+
3
+ $("#new_spree_wished_product").submit(function() {
4
+ selected_variant_id = $("#product-variants input[type=radio]:checked").val();
5
+ if (selected_variant_id)
6
+ {
7
+ $("#wished_product_variant_id").val(selected_variant_id);
8
+ }
9
+ });
10
+
11
+
12
+ $("form#change_wishlist_accessibility").submit(function() {
13
+ $.post($(this).attr("action"), $(this).serialize(), null, "script");
14
+ return false;
15
+ });
16
+
17
+ $("form#change_wishlist_accessibility input[type=radio]").click(function() {
18
+ $(this).parent().submit();
19
+ });
20
+
21
+ });
@@ -0,0 +1,2 @@
1
+ #wishlist-form {margin-top: 5px;}
2
+ #wishlist_header h1, #wishlist_header div { float: left; width: 30%; }
@@ -0,0 +1,37 @@
1
+ class Spree::WishedProductsController < Spree::BaseController
2
+ respond_to :html
3
+
4
+ def create
5
+ @wished_product = Spree::WishedProduct.new(params[:wished_product])
6
+ @wishlist = current_user.wishlist
7
+
8
+ if @wishlist.include? params[:wished_product][:variant_id]
9
+ @wished_product = @wishlist.wished_products.detect {|wp| wp.variant_id == params[:wished_product][:variant_id].to_i }
10
+ else
11
+ @wished_product.wishlist = current_user.wishlist
12
+ @wished_product.save
13
+ end
14
+
15
+ respond_with(@wished_product) do |format|
16
+ format.html { redirect_to wishlist_url(@wishlist) }
17
+ end
18
+ end
19
+
20
+ def update
21
+ @wished_product = Spree::WishedProduct.find(params[:id])
22
+ @wished_product.update_attributes(params[:wished_product])
23
+
24
+ respond_with(@wished_product) do |format|
25
+ format.html { redirect_to wishlist_url(@wished_product.wishlist) }
26
+ end
27
+ end
28
+
29
+ def destroy
30
+ @wished_product = Spree::WishedProduct.find(params[:id])
31
+ @wished_product.destroy
32
+
33
+ respond_with(@wished_product) do |format|
34
+ format.html { redirect_to wishlist_url(@wished_product.wishlist) }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ class Spree::WishlistsController < Spree::BaseController
2
+ helper 'spree/products'
3
+
4
+ respond_to :html
5
+ respond_to :js, :only => [:update]
6
+
7
+ def new
8
+ @wishlist = Spree::Wishlist.new
9
+
10
+ respond_with(@wishlist)
11
+ end
12
+
13
+ def edit
14
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
15
+
16
+ respond_with(@wishlist)
17
+ end
18
+
19
+ def update
20
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
21
+ @wishlist.update_attributes(params[:wishlist])
22
+
23
+ respond_with(@wishlist)
24
+ end
25
+
26
+ def show
27
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
28
+
29
+ respond_with(@wishlist)
30
+ end
31
+
32
+ def create
33
+ @wishlist = Spree::Wishlist.new(params[:wishlist])
34
+ @wishlist.user = current_user
35
+
36
+ @wishlist.save
37
+ respond_with(@wishlist)
38
+ end
39
+
40
+ def destroy
41
+ @wishlist = Spree::Wishlist.find_by_access_hash(params[:id])
42
+ @wishlist.destroy
43
+ respond_with(@wishlist )do |format|
44
+ format.html { redirect_to account_path }
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,11 @@
1
+ Spree::User.class_eval do
2
+ has_many :wishlists
3
+
4
+ def wishlist
5
+ default_wishlist = self.wishlists.first(:conditions => ["is_default = ?", true])
6
+ default_wishlist ||= self.wishlists.first
7
+ default_wishlist ||= self.wishlists.create(:name => I18n.t(:default_wishlist_name, :default => "My wishlist"), :is_default => true)
8
+ default_wishlist.update_attribute(:is_default, true) unless default_wishlist.is_default?
9
+ default_wishlist
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ class Spree::WishedProduct < ActiveRecord::Base
2
+ belongs_to :variant
3
+ belongs_to :wishlist
4
+ end
@@ -0,0 +1,40 @@
1
+ class Spree::Wishlist < ActiveRecord::Base
2
+ belongs_to :user
3
+ has_many :wished_products
4
+ before_create :set_access_hash
5
+
6
+ validates :name, :presence => true
7
+
8
+ def include?(variant_id)
9
+ self.wished_products.map(&:variant_id).include? variant_id.to_i
10
+ end
11
+
12
+ def to_param
13
+ self.access_hash
14
+ end
15
+
16
+ def self.get_by_param(param)
17
+ Spree::Wishlist.find_by_access_hash(param)
18
+ end
19
+
20
+ def can_be_read_by?(user)
21
+ !self.is_private? || user == self.user
22
+ end
23
+
24
+ def is_default=(value)
25
+ self['is_default'] = value
26
+ if self.is_default?
27
+ Spree::Wishlist.update_all({:is_default => false}, ["id != ? AND is_default = ? AND user_id = ?", self.id, true, self.user_id])
28
+ end
29
+ end
30
+
31
+ def is_public?
32
+ !self.is_private?
33
+ end
34
+
35
+ private
36
+
37
+ def set_access_hash
38
+ self.access_hash = Digest::SHA1.hexdigest("--#{user_id}--#{user.password_salt}--#{Time.now}--")
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/products/show",
2
+ :name => "add_wish_to_cart_form",
3
+ :insert_bottom => "[data-hook='cart_form']",
4
+ :partial => "spree/products/wishlist_form",
5
+ :disabled => false)
@@ -0,0 +1,5 @@
1
+ Deface::Override.new(:virtual_path => "spree/users/show",
2
+ :name => "add_wishlists_to_account_my_orders",
3
+ :insert_after => "[data-hook='account_my_orders']",
4
+ :partial => "spree/users/wishlists",
5
+ :disabled => false)
@@ -0,0 +1,10 @@
1
+ <% if current_user %>
2
+ <div id="wishlist-form">
3
+ <%= form_for Spree::WishedProduct.new do |f| %>
4
+ <%= f.hidden_field :variant_id, :value => @product.master.id %>
5
+ <button type="submit" class="large primary">
6
+ <%= t(:add_to_wishlist) %>
7
+ </button>
8
+ <% end %>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <h3><%= t(:my_wishlists) %></h3>
2
+ <ul>
3
+ <% @user.wishlists.each do |wl| %>
4
+ <% if !wl.is_private? || @user == current_user %>
5
+ <li><%= link_to wl.name, wl %></li>
6
+ <% end -%>
7
+ <% end -%>
8
+ </ul>
@@ -0,0 +1,4 @@
1
+ <%= form_for @wishlist, :html => {:class => 'ajax_form', :id => 'change_wishlist_accessibility'} do |f| %>
2
+ <%= f.radio_button :is_private, true %>&nbsp;<%= t(:private) %>
3
+ <%= f.radio_button :is_private, false %>&nbsp;<%= t(:public) %>
4
+ <% end -%>
@@ -0,0 +1,14 @@
1
+ <%= mail.recipient_name %>,
2
+
3
+ Please, take a look to my wishlist:
4
+
5
+ * <%= wishlist.name %>
6
+
7
+ <% unless mail.message.blank? -%>
8
+ <%= mail.message %>
9
+ <% end -%>
10
+
11
+ <%= mail.sender_name %>
12
+
13
+ Click the link below to view the <%= wishlist.name %> page.
14
+ <%= wishlist_url(wishlist) %>
@@ -0,0 +1,7 @@
1
+ <h1 class="row"><%= t(:editing_wishlist) %></h1>
2
+ <%= form_for @wishlist do |f| %>
3
+ <p><%= f.label :name, t(:name) %>:&nbsp;<%= f.text_field :name %></p>
4
+ <p><%= f.check_box :is_private %>&nbsp;<%= f.label :is_private, t(:is_private) %></p>
5
+ <p><%= f.check_box :is_default %>&nbsp;<%= f.label :is_default, t(:is_default) %></p>
6
+ <%= f.submit t(:update) %> <%= t(:or) %> <%= link_to t(:delete_wishlist), @wishlist, :method => :delete, :confirm => t(:are_you_sure_wishlist), :class => "button" %>
7
+ <% end -%>
@@ -0,0 +1,6 @@
1
+ <h1><%= t(:creating_wishlist) %></h1>
2
+ <%= form_for @wishlist do |f| %>
3
+ <p><%= f.label :name, t(:name) %>:&nbsp;<%= f.text_field :name %></p>
4
+ <p><%= f.check_box :is_private %>&nbsp;<%= f.label :is_private, t(:is_private) %></p>
5
+ <%= f.submit t(:create) %>
6
+ <% end -%>
@@ -0,0 +1,84 @@
1
+ <div id="wishlist_header" class="row">
2
+ <h1><%= @wishlist.name %></h1>
3
+ <% if @wishlist.user == current_user %>
4
+ <div id="manage_wishlist_links">
5
+ <%= link_to t(:edit_wishlist), edit_wishlist_path(@wishlist), :class => 'button' %>
6
+ </div>
7
+ <div><%= render :partial => 'accessibility' %></div>
8
+ <% end -%>
9
+ </div>
10
+ <table id="wishlist">
11
+ <thead>
12
+ <tr>
13
+ <% if @wishlist.user == current_user %>
14
+ <th><%= t(:wishlist_actions) %></th>
15
+ <% end -%>
16
+ <th><%= t(:item_view) %></th>
17
+ <th><%= t(:item_description) %></th>
18
+ <th><%= t(:availability) %></th>
19
+ <th><%= t(:date_added) %></th>
20
+ <th><%= t(:price) %></th>
21
+ </tr>
22
+ </thead>
23
+ <tbody id="line_items">
24
+ <% if @wishlist.wished_products.size > 0 %>
25
+ <% @wishlist.wished_products.each do |wish|
26
+ variant = wish.variant
27
+ product = variant.product %>
28
+ <tr class="<%= cycle('', 'alt') %>">
29
+ <% if @wishlist.user == current_user %>
30
+ <td>
31
+ <p><%= link_to t(:remove_from_wishlist), wish, :method => :delete, :class => 'button' %></p>
32
+ <%= form_for :order, :url => populate_orders_url do |f| %>
33
+ <%= hidden_field_tag "variants[#{variant.id}]", 1, :size => 3 %>
34
+ <%= link_to t(:add_to_cart), '#', :onclick => "$(this).parent().submit(); return false;", :class => "button" %>
35
+ <% end %>
36
+ <% if current_user.wishlists.count > 1 %>
37
+ <%= t(:move_to_another_wishlist) %>:
38
+ <%= form_for wish do |f| %>
39
+ <%= f.select :wishlist_id, current_user.wishlists.map{|wl| [wl.name, wl.id]} %>
40
+ <%= f.submit t(:move) %>
41
+ <% end %>
42
+ <% end %>
43
+ <br />
44
+ </td>
45
+ <% end -%>
46
+ <td>
47
+ <% if variant.images.length == 0 %>
48
+ <%= small_image(variant.product) %>
49
+ <% else %>
50
+ <%= image_tag variant.images.first.attachment.url(:small) %>
51
+ <% end %>
52
+ </td>
53
+ <td>
54
+ <h4><%= link_to product.name, product %></h4>
55
+ <p><%= variant_options variant %></p>
56
+ <%= truncate(product.description, :length => 100, :omission => "...") %>
57
+ </td>
58
+ <td>
59
+ <%= variant.in_stock? ? t(:in_stock) : t(:out_of_stock) %>
60
+ </td>
61
+ <td>
62
+ <%= wish.created_at.strftime "%m/%d/%Y" %>
63
+ </td>
64
+ <td>
65
+ <%= number_to_currency(variant.price) %>
66
+ </td>
67
+ </tr>
68
+ <% end -%>
69
+ <% else -%>
70
+ <tr>
71
+ <td colspan="6"><%= t(:your_wishlist_is_empty) %></td>
72
+ </tr>
73
+ <% end -%>
74
+ </tbody>
75
+ </table>
76
+ <div class="footer_links" data-hook="wishlist_footer_links">
77
+ <% if @wishlist.user == current_user %>
78
+ <%= link_to t(:create_new_wishlist), new_wishlist_path, :class => "button" %>
79
+ <% end -%>
80
+ <%= link_to t(:continue_shopping), products_path, :class => "button" %>
81
+ <% if respond_to?(:email_to_friend_url) %>
82
+ <%= link_to t('email_to_friend.send_to_friend'), email_to_friend_url('wishlist', @wishlist), :class => "button" %>
83
+ <% end %>
84
+ </div>
@@ -0,0 +1,26 @@
1
+ de:
2
+ add_to_wishlist: "Für die Wunschliste"
3
+ are_you_sure_wishlist: "Sind sie sicher, dass sie diese Wunschliste löschen wollen?"
4
+ availability: "Verfügbarkeit"
5
+ create_new_wishlist: "Neue Wunschliste erstellen"
6
+ creating_wishlist: "Wunschliste erstellen"
7
+ date_added: "Hinzugefügt am"
8
+ delete_wishlist: "Wunschliste löschen"
9
+ edit_wishlist: "Wunschliste ändern"
10
+ editing_wishlist: "Ändere Wunschliste"
11
+ in_stock: "Verfügbar"
12
+ is_default: "ist voreingstellt"
13
+ is_private: "ist privat"
14
+ item_view: "Bild"
15
+ move: "Verschieben"
16
+ move_to_another_wishlist: "Verschiebe in"
17
+ my_wishlists: "Meine Wuschlisten"
18
+ private_wishlist: "Private Wunschlisten"
19
+ private: "Privat"
20
+ public_wishlist: "Öffentliche Wunschlisten"
21
+ public: "Öffentlich"
22
+ remove_from_wishlist: "Von Wunschliste entfernen"
23
+ wishlist_actions: ""
24
+ your_wishlist_is_empty: "Deine Wunschliste ist leer"
25
+ update_quantity: "Ändere Menge"
26
+ item_added_to_wishlist: "Artikel wurde zur Wunschliste hinzugefügt"
@@ -0,0 +1,26 @@
1
+ en:
2
+ add_to_wishlist: "Add to wishlist"
3
+ are_you_sure_wishlist: "Are you sure that you want to delete this wishlist?"
4
+ availability: "Availability"
5
+ create_new_wishlist: "Create new wishlist"
6
+ creating_wishlist: "Creating wishlist"
7
+ date_added: "Date added"
8
+ delete_wishlist: "Delete wishlist"
9
+ edit_wishlist: "Edit wishlist"
10
+ editing_wishlist: "Editing wishlist"
11
+ in_stock: "In stock"
12
+ is_default: "is default"
13
+ is_private: "is private"
14
+ item_view: "View"
15
+ move: "Move"
16
+ move_to_another_wishlist: "Move to another wishlist"
17
+ my_wishlists: "My wishlists"
18
+ private_wishlist: "Private wishlist"
19
+ private: "Private"
20
+ public_wishlist: "Public wishlist"
21
+ public: "Public"
22
+ remove_from_wishlist: "Remove from wishlist"
23
+ wishlist_actions: "Actions"
24
+ your_wishlist_is_empty: "Your wishlist is empty"
25
+ update_quantity: "Update quantity"
26
+ item_added_to_wishlist: "Item added to wishlist"
@@ -0,0 +1,27 @@
1
+ ru:
2
+ add_to_wishlist: "Добавить в список желаний"
3
+ are_you_sure_wishlist: "Вы уверены, что хотите удалить этот список желаний?"
4
+ availability: "Доступность"
5
+ create_new_wishlist: "Создать ещё один"
6
+ creating_wishlist: "Создание списка желаний"
7
+ date_added: "Дата добавления"
8
+ delete_wishlist: "Удалить"
9
+ edit_wishlist: "Редактировать"
10
+ editing_wishlist: "Редактирование списка желаний"
11
+ in_stock: "Есть в наличии"
12
+ is_default: "по умолчанию"
13
+ is_private: "приватный"
14
+ item_view: "Миниатюра"
15
+ move: "Переместить"
16
+ move_to_another_wishlist: "Переместить в другой список"
17
+ my_wishlists: "Мои списки желаний"
18
+ private_wishlist: "Личный список желаний"
19
+ private: "Приватный"
20
+ public_wishlist: "Публичный список желаний"
21
+ public: "Публичный"
22
+ remove_from_wishlist: "Убрать из списка"
23
+ wishlist_actions: "Действия"
24
+ your_wishlist_is_empty: "Ваш список желаний пуст"
25
+ update_quantity: "Update quantity"
26
+ item_added_to_wishlist: "Item added to wishlist"
27
+ default_wishlist_name: "Мой список желаний"
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.routes.append do
2
+ resources :wishlists
3
+ resources :wished_products, :only => [:create, :update, :destroy]
4
+ match '/wishlist' => "wishlists#show", :as => "default_wishlist"
5
+ end
@@ -0,0 +1,25 @@
1
+ 'WishlistsController':
2
+ permission1:
3
+ roles : [admin]
4
+ options :
5
+ for : [show]
6
+ unless : "can_read?"
7
+ permission2:
8
+ roles : [user]
9
+ options :
10
+ for : [new, create]
11
+ permission3:
12
+ roles : [admin]
13
+ options :
14
+ except : [show, new, create]
15
+ unless : "current_user and current_user.id == object.user_id"
16
+ 'WishedProductsController':
17
+ permission1:
18
+ roles : [user]
19
+ options :
20
+ for : [index, create]
21
+ permission2:
22
+ roles : [admin]
23
+ options :
24
+ for : [update, destroy]
25
+ unless : "current_user and current_user.id == object.wishlist.user_id"
@@ -0,0 +1,17 @@
1
+ class CreateWishlists < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :wishlists do |t|
4
+ t.references :user
5
+ t.string :name
6
+ t.string :access_hash
7
+ t.boolean :is_private, :default => true, :null => false
8
+ t.boolean :is_default, :default => false, :null => false
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :wishlists
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ class CreateWishedProducts < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :wished_products do |t|
4
+ t.references :variant
5
+ t.references :wishlist
6
+ t.text :remark
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :wished_products
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ class PrefixWishlistTablesWithSpree < ActiveRecord::Migration
2
+ def change
3
+ rename_table :wishlists, :spree_wishlists
4
+ rename_table :wished_products, :spree_wished_products
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ # Use this file to load your own seed data from extensions.
2
+ # See the db/seeds.rb file in the Spree core for some ideas on what you can do here.
@@ -0,0 +1,27 @@
1
+ module SpreeWishlist
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ def add_javascripts
6
+ append_file "app/assets/javascripts/store/all.js", "//= require store/spree_wishlist\n"
7
+ end
8
+
9
+ def add_stylesheets
10
+ inject_into_file "app/assets/stylesheets/store/all.css", " *= require store/spree_wishlist\n", :before => /\*\//, :verbose => true
11
+ end
12
+
13
+ def add_migrations
14
+ run 'rake railties:install:migrations FROM=spree_wishlist'
15
+ end
16
+
17
+ def run_migrations
18
+ res = ask "Would you like to run the migrations now? [Y/n]"
19
+ if res == "" || res.downcase == "y"
20
+ run 'rake db:migrate'
21
+ else
22
+ puts "Skiping rake db:migrate, don't forget to run it!"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ require 'spree_core'
2
+ require 'spree_auth'
3
+ require 'spree_wishlist/engine'
@@ -0,0 +1,20 @@
1
+ module SpreeWishlist
2
+ class Engine < Rails::Engine
3
+ engine_name 'spree_wishlist'
4
+
5
+ config.autoload_paths += %W(#{config.root}/lib)
6
+
7
+ def self.activate
8
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
9
+ Rails.application.config.cache_classes ? require(c) : load(c)
10
+ end
11
+
12
+ #Dir.glob(File.join(File.dirname(__FILE__), "../app/overrides/**/*.rb")) do |c|
13
+ # Rails.application.config.cache_classes ? require(c) : load(c)
14
+ #end
15
+ Spree::Ability.register_ability(WishlistAbility)
16
+ end
17
+
18
+ config.to_prepare &method(:activate).to_proc
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ class WishlistAbility
2
+
3
+ # Stuff like class AbilityDecorator goes here.
4
+
5
+ include CanCan::Ability
6
+
7
+ def initialize(user)
8
+ # Anyone can create a wishlist
9
+ can :index, Spree::Wishlist do
10
+ !user.new_record?
11
+ end
12
+
13
+ can :create, Spree::Wishlist
14
+ # You can your own wishlists, and everyone cas see public ones
15
+ can :read, Spree::Wishlist do |wishlist|
16
+ wishlist.user == user || wishlist.is_public?
17
+ end
18
+ # You can only change your own wishlist
19
+ can [:read, :move, :update, :edit, :destroy], Spree::Wishlist do |wishlist|
20
+ wishlist.user == user
21
+ end
22
+
23
+ can :create, Spree::WishedProduct do |wished_product|
24
+ !user.new_record?
25
+ end
26
+
27
+ can :read, Spree::WishedProduct do |wished_product|
28
+ wished_product.wishlist.user == user || wished_product.wishlist.is_public?
29
+ end
30
+ can [:index, :update, :destroy], Spree::WishedProduct do |wished_product|
31
+ wished_product.wishlist.user == user
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishedProductsController do
4
+
5
+ #Delete this example and add some real ones
6
+ it "should use Spree::WishedProductsController" do
7
+ controller.should be_an_instance_of(Spree::WishedProductsController)
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishlistsController do
4
+
5
+ #Delete this example and add some real ones
6
+ it "should use Spree::WishlistsController" do
7
+ controller.should be_an_instance_of(Spree::WishlistsController)
8
+ end
9
+
10
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+ require 'cancan/matchers'
3
+
4
+ describe WishlistAbility do
5
+
6
+ let(:user) { Factory(:user) }
7
+ let(:ability) { WishlistAbility.new(Factory(:user)) }
8
+ let(:token) { nil }
9
+
10
+ TOKEN = "token123"
11
+
12
+ shared_examples_for "allow CRUD" do
13
+ it "should allow create" do
14
+ ability.should be_able_to(:create, resource, token)
15
+ end
16
+ it "should allow read" do
17
+ ability.should be_able_to(:read, resource, token)
18
+ end
19
+ it "should allow update" do
20
+ ability.should be_able_to(:update, resource, token)
21
+ end
22
+ it "should allow destroy" do
23
+ ability.should be_able_to(:destroy, resource, token)
24
+ end
25
+ end
26
+
27
+ shared_examples_for "access denied" do
28
+ it "should not allow read" do
29
+ ability.should_not be_able_to(:read, resource)
30
+ end
31
+ it "should not allow create" do
32
+ ability.should_not be_able_to(:create, resource)
33
+ end
34
+ it "should not allow update" do
35
+ ability.should_not be_able_to(:update, resource)
36
+ end
37
+ end
38
+
39
+ shared_examples_for "no index allowed" do
40
+ it "should not allow index" do
41
+ ability.should_not be_able_to(:index, resource)
42
+ end
43
+ end
44
+
45
+ shared_examples_for "create only" do
46
+ it "should allow create" do
47
+ ability.should be_able_to(:create, resource)
48
+ end
49
+ it "should not allow read" do
50
+ ability.should_not be_able_to(:read, resource)
51
+ end
52
+ it "should not allow update" do
53
+ ability.should_not be_able_to(:update, resource)
54
+ end
55
+ it "should not allow index" do
56
+ ability.should_not be_able_to(:index, resource)
57
+ end
58
+ end
59
+
60
+ shared_examples_for "read only" do
61
+ it "should not allow create" do
62
+ ability.should_not be_able_to(:create, resource)
63
+ end
64
+ it "should allow read" do
65
+ ability.should be_able_to(:read, resource)
66
+ end
67
+ it "should not allow update" do
68
+ ability.should_not be_able_to(:update, resource)
69
+ end
70
+ it "should allow index" do
71
+ ability.should be_able_to(:index, resource)
72
+ end
73
+ end
74
+
75
+ #context "for Wishedproduct" do
76
+ #end
77
+
78
+ #context "for Wishlist" do
79
+ #context "private" do
80
+ #let(:resource) { Spree::Wishlist.new(:is_private => true) }
81
+ #pending
82
+ #end
83
+
84
+ #context "public" do
85
+ #let(:resource) { Spree::Wishlist.new(:is_private => false) }
86
+ #context "requested by same user" do
87
+ #before { resource.user = user }
88
+ #pending
89
+ #it_should_behave_like "allow CRUD"
90
+ #end
91
+ #context "requested by other user" do
92
+ #pending
93
+ #end
94
+
95
+ #end
96
+ #end
97
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::WishedProduct do
4
+ before(:each) do
5
+ @wished_product = Spree::WishedProduct.new
6
+ end
7
+
8
+ it "should be valid" do
9
+ @wished_product.should be_valid
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Spree::Wishlist do
4
+ before(:each) do
5
+ @user = Factory(:user)
6
+ @wishlist = Spree::Wishlist.new(:user => @user, :name => "My Wishlist")
7
+ end
8
+
9
+ context "creating a new wishlist" do
10
+ it "is valid with valid attributes" do
11
+ @wishlist.should be_valid
12
+ end
13
+
14
+ it "is not valid without a name" do
15
+ @wishlist.name = nil
16
+ @wishlist.should_not be_valid
17
+ end
18
+ end
19
+
20
+ context "#include?" do
21
+ before(:each) do
22
+ @variant = Factory(:variant)
23
+ wished_product = Spree::WishedProduct.new(:variant => @variant)
24
+ @wishlist.wished_products << wished_product
25
+ @wishlist.save
26
+ end
27
+
28
+ it "should be true if the wishlist includes the specified variant" do
29
+ @wishlist.include?(@variant.id).should be_true
30
+ end
31
+ end
32
+
33
+ context "#to_param" do
34
+ it "should return the wishlist's access_hash" do
35
+ @wishlist.to_param.should == @wishlist.access_hash
36
+ end
37
+ end
38
+
39
+ context "#can_be_read_by?" do
40
+ context "when the wishlist is private" do
41
+ before(:each) do
42
+ @wishlist.is_private = true
43
+ end
44
+
45
+ it "is true when the user owns the wishlist" do
46
+ @wishlist.can_be_read_by?(@user).should be_true
47
+ end
48
+
49
+ it "is false when the user does not own the wishlist" do
50
+ other_user = Factory(:user)
51
+ @wishlist.can_be_read_by?(other_user).should be_false
52
+ end
53
+ end
54
+
55
+ context "when the wishlist is public" do
56
+ it "is true for any user" do
57
+ @wishlist.is_private = false
58
+ other_user = Factory(:user)
59
+ @wishlist.can_be_read_by?(other_user).should be_true
60
+ end
61
+ end
62
+ end
63
+
64
+ context "#is_public?" do
65
+ it "is true when the wishlist is public" do
66
+ @wishlist.is_private = false
67
+ @wishlist.is_public?.should be_true
68
+ end
69
+
70
+ it "is false when the wishlist is private" do
71
+ @wishlist.is_private = true
72
+ @wishlist.is_public?.should_not be_true
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,19 @@
1
+ # Configure Rails Environment
2
+ ENV["RAILS_ENV"] = "test"
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+
6
+ # Requires supporting ruby files with custom matchers and macros, etc,
7
+ # in spec/support/ and its subdirectories.
8
+ Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9
+
10
+ # Requires factories defined in spree_core
11
+ require 'spree/core/testing_support/factories'
12
+
13
+ RSpec.configure do |config|
14
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
15
+ # examples within a transaction, remove the following line or assign false
16
+ # instead of true.
17
+ config.use_transactional_fixtures = true
18
+ end
19
+
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ Gem::Specification.new do |s|
4
+ s.platform = Gem::Platform::RUBY
5
+ s.name = 'spree_wishlist'
6
+ s.version = '1.3'
7
+ s.summary = 'Add wishlists to Spree'
8
+ s.homepage = 'https://github.com/spree/spree_wishlist'
9
+ s.required_ruby_version = '>= 1.8.7'
10
+
11
+ s.author = 'John Dyer'
12
+ s.required_ruby_version = '>= 1.8.7'
13
+ s.rubygems_version = '1.3.6'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency 'spree_core', '>= 1.0.0'
20
+ s.add_dependency 'spree_auth', '>= 1.0.0'
21
+
22
+ s.add_development_dependency 'factory_girl'
23
+ s.add_development_dependency 'rspec-rails', '~> 2.8.0.rc1'
24
+ s.add_development_dependency 'sqlite3'
25
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_wishlist
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.3'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Dyer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: spree_core
16
+ requirement: &70114287756500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70114287756500
25
+ - !ruby/object:Gem::Dependency
26
+ name: spree_auth
27
+ requirement: &70114287755900 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70114287755900
36
+ - !ruby/object:Gem::Dependency
37
+ name: factory_girl
38
+ requirement: &70114287755480 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70114287755480
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec-rails
49
+ requirement: &70114287770860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.8.0.rc1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70114287770860
58
+ - !ruby/object:Gem::Dependency
59
+ name: sqlite3
60
+ requirement: &70114287770100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70114287770100
69
+ description:
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - .gitignore
76
+ - .rspec
77
+ - .travis.yml
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - Versionfile
83
+ - app/assets/javascripts/store/spree_wishlist.js
84
+ - app/assets/stylesheets/store/spree_wishlist.css
85
+ - app/controllers/spree/wished_products_controller.rb
86
+ - app/controllers/spree/wishlists_controller.rb
87
+ - app/models/spree/user_decorator.rb
88
+ - app/models/spree/wished_product.rb
89
+ - app/models/spree/wishlist.rb
90
+ - app/overrides/add_wish_to_cart_form.rb
91
+ - app/overrides/add_wishlists_to_account_my_orders.rb
92
+ - app/views/spree/products/_wishlist_form.html.erb
93
+ - app/views/spree/users/_wishlists.html.erb
94
+ - app/views/spree/wishlists/_accessibility.html.erb
95
+ - app/views/spree/wishlists/_mail_to_friend.html.erb
96
+ - app/views/spree/wishlists/edit.html.erb
97
+ - app/views/spree/wishlists/new.html.erb
98
+ - app/views/spree/wishlists/show.html.erb
99
+ - app/views/spree/wishlists/update.js.erb
100
+ - config/locales/de.yml
101
+ - config/locales/en.yml
102
+ - config/locales/ru.yml
103
+ - config/routes.rb
104
+ - config/spree_permissions.yml
105
+ - db/migrate/20091020182940_create_wishlists.rb
106
+ - db/migrate/20091020183520_create_wished_products.rb
107
+ - db/migrate/20111130204731_prefix_wishlist_tables_with_spree.rb
108
+ - db/seeds.rb
109
+ - lib/generators/spree_wishlist/install/install_generator.rb
110
+ - lib/spree_wishlist.rb
111
+ - lib/spree_wishlist/engine.rb
112
+ - lib/wishlist_ability.rb
113
+ - spec/controllers/spree/wished_products_controller_spec.rb
114
+ - spec/controllers/spree/wishlists_controller_spec.rb
115
+ - spec/lib/wishlist_ability_spec.rb
116
+ - spec/models/spree/wished_product_spec.rb
117
+ - spec/models/spree/wishlist_spec.rb
118
+ - spec/spec_helper.rb
119
+ - spree_wishlist.gemspec
120
+ homepage: https://github.com/spree/spree_wishlist
121
+ licenses: []
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.8.7
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 1.8.15
141
+ signing_key:
142
+ specification_version: 3
143
+ summary: Add wishlists to Spree
144
+ test_files:
145
+ - spec/controllers/spree/wished_products_controller_spec.rb
146
+ - spec/controllers/spree/wishlists_controller_spec.rb
147
+ - spec/lib/wishlist_ability_spec.rb
148
+ - spec/models/spree/wished_product_spec.rb
149
+ - spec/models/spree/wishlist_spec.rb
150
+ - spec/spec_helper.rb
151
+ has_rdoc: