mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-04 02:31:33 +00:00
Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ad49cc080 | ||
|
|
2a7e8816c0 | ||
|
|
601c921b4b | ||
|
|
39fbf01e98 | ||
|
|
69586ae5ae | ||
|
|
c87eb05c0e | ||
|
|
a1f363c53b | ||
|
|
76c6362db0 | ||
|
|
5c3308de36 | ||
|
|
a82b2c2799 | ||
|
|
4895010fe0 | ||
|
|
962097f237 | ||
|
|
941707a0df | ||
|
|
f7e119d06f | ||
|
|
52ee5929cf | ||
|
|
1e58882217 | ||
|
|
ca23f12451 | ||
|
|
cce37aa915 | ||
|
|
f808fe9685 | ||
|
|
dd5db396b4 | ||
|
|
e121a799ed | ||
|
|
5dfef4a3ae | ||
|
|
8236603f76 | ||
|
|
315d52961a | ||
|
|
dcb6f4676d | ||
|
|
3455ceb722 | ||
|
|
7361b2da0b | ||
|
|
3ebacbc31a | ||
|
|
c0bcf177e7 | ||
|
|
8dfede11c6 | ||
|
|
bac123f223 | ||
|
|
fdc775ae6d | ||
|
|
26b39d6626 | ||
|
|
8953e8481d | ||
|
|
1ce76a3166 | ||
|
|
1c703905fe | ||
|
|
feed223ab4 | ||
|
|
90f962a886 | ||
|
|
82f6484031 | ||
|
|
282fb44da4 | ||
|
|
82f40d2e93 | ||
|
|
cae1655ec3 | ||
|
|
26702e6f0d | ||
|
|
8cd9e94148 | ||
|
|
a934b60f67 | ||
|
|
7fc9a6bf93 | ||
|
|
781bf940f6 | ||
|
|
92382ca473 | ||
|
|
76a3e913df | ||
|
|
23ab6bb489 | ||
|
|
368da19993 | ||
|
|
419f4490d6 | ||
|
|
39245d55e2 | ||
|
|
fe8200b7e8 | ||
|
|
c799f15067 | ||
|
|
54f1047dcb | ||
|
|
c1e599deef | ||
|
|
f3c60148c1 | ||
|
|
2e08c9c44e | ||
|
|
93f2af7e7d | ||
|
|
cb7a4b67ce | ||
|
|
41a8d06326 | ||
|
|
a957df1205 | ||
|
|
a1bdfa0a20 | ||
|
|
1adf94093e | ||
|
|
476daf0d30 | ||
|
|
79a9dbcf68 | ||
|
|
61c7c26822 | ||
|
|
969dcae8d0 | ||
|
|
ce5a95ff4f | ||
|
|
0d5330d388 | ||
|
|
3676acf244 | ||
|
|
caf6b087c1 | ||
|
|
24d6c1e386 | ||
|
|
a120e390d0 | ||
|
|
98a2bf5d47 | ||
|
|
bb0c1e7a0f | ||
|
|
55a15b914c | ||
|
|
8ce14a55c8 | ||
|
|
d1f47f6956 | ||
|
|
2d50dace20 | ||
|
|
bbbbe71bc4 | ||
|
|
b3dc76b8cf | ||
|
|
ad4b26e86d | ||
|
|
c2a7a89381 | ||
|
|
68e3623861 | ||
|
|
577aa55f98 | ||
|
|
b8e62b3d84 | ||
|
|
dbb8e07b9a | ||
|
|
19550ed4fe | ||
|
|
4d0c710e3b | ||
|
|
fccde70690 | ||
|
|
0f59333cd9 | ||
|
|
ad4ce14486 |
@@ -1,2 +0,0 @@
|
||||
defaults
|
||||
IE 11
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -8,4 +8,3 @@
|
||||
# Same thing for following files, but they don't have an sh extension
|
||||
pre-commit eol=lf
|
||||
webpack-dev-server eol=lf
|
||||
install-bundler eol=lf
|
||||
@@ -1 +1 @@
|
||||
3.2.9
|
||||
3.4.8
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ruby:3.2.9-alpine3.19 AS base
|
||||
FROM ruby:3.4.8-alpine3.19 AS base
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Europe/London \
|
||||
@@ -31,4 +31,4 @@ FROM development-base
|
||||
COPY . $RAILS_ROOT
|
||||
COPY Gemfile Gemfile.lock ./
|
||||
RUN bundle install --jobs "$(nproc)"
|
||||
COPY --from=yarn-dependencies $RAILS_ROOT/node_modules ./node_modules
|
||||
COPY --from=yarn-dependencies $RAILS_ROOT/node_modules ./node_modules
|
||||
|
||||
@@ -83,11 +83,8 @@ RUN wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.z
|
||||
# Copy code and install app dependencies
|
||||
COPY . /usr/src/app/
|
||||
|
||||
# Install Bundler
|
||||
RUN ./script/install-bundler
|
||||
|
||||
# Install front-end dependencies
|
||||
RUN yarn install
|
||||
|
||||
# Run bundler install in parallel with the amount of available CPUs
|
||||
RUN bundle install --jobs="$(nproc)"
|
||||
RUN bundle install --jobs="$(nproc)"
|
||||
|
||||
6
Gemfile
6
Gemfile
@@ -18,7 +18,7 @@ gem 'activemerchant'
|
||||
gem 'angular-rails-templates'
|
||||
gem 'ransack', '~> 4.1.0'
|
||||
gem 'responders'
|
||||
gem 'webpacker', '~> 5'
|
||||
gem 'shakapacker', '6.6.0'
|
||||
|
||||
# Indirect dependency but we access it directly in JS specs.
|
||||
# It turns out to be hard to upgrade but please do if you can.
|
||||
@@ -49,7 +49,7 @@ gem 'acts_as_list', '1.0.4'
|
||||
gem 'cancancan', '~> 1.15.0'
|
||||
gem 'digest'
|
||||
gem 'ffaker'
|
||||
gem 'highline', '2.0.3' # Necessary for the install generator
|
||||
gem 'highline'
|
||||
gem 'json'
|
||||
gem 'monetize', '~> 1.11'
|
||||
gem 'paranoia', '~> 2.4'
|
||||
@@ -126,6 +126,8 @@ gem 'angular_rails_csrf'
|
||||
|
||||
gem 'jquery-rails', '4.4.0'
|
||||
gem 'jquery-ui-rails', '~> 4.2'
|
||||
# TODO move away from sass-rails, master branch will get rid of dependency, so we can move to
|
||||
# https://github.com/sass/embedded-host-node
|
||||
gem "select2-rails", github: "openfoodfoundation/select2-rails", branch: "v349_with_thor_v1"
|
||||
|
||||
gem 'good_migrations'
|
||||
|
||||
25
Gemfile.lock
25
Gemfile.lock
@@ -389,7 +389,8 @@ GEM
|
||||
hashdiff (1.2.1)
|
||||
hashery (2.1.2)
|
||||
hashie (5.0.0)
|
||||
highline (2.0.3)
|
||||
highline (3.1.2)
|
||||
reline
|
||||
htmlentities (4.4.2)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.14.7)
|
||||
@@ -614,7 +615,7 @@ GEM
|
||||
rack-protection (3.2.0)
|
||||
base64 (>= 0.1.0)
|
||||
rack (~> 2.2, >= 2.2.4)
|
||||
rack-proxy (0.7.6)
|
||||
rack-proxy (0.7.7)
|
||||
rack
|
||||
rack-rewrite (1.5.1)
|
||||
rack-session (1.0.2)
|
||||
@@ -813,7 +814,12 @@ GEM
|
||||
tilt (>= 1.1, < 3)
|
||||
sd_notify (0.1.1)
|
||||
securerandom (0.4.1)
|
||||
semantic_range (3.0.0)
|
||||
semantic_range (3.1.0)
|
||||
shakapacker (6.6.0)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
shoulda-matchers (7.0.1)
|
||||
activesupport (>= 7.1)
|
||||
sidekiq (7.2.4)
|
||||
@@ -941,11 +947,6 @@ GEM
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
webpacker (5.4.4)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.9.2)
|
||||
websocket-driver (0.7.7)
|
||||
base64
|
||||
@@ -1018,7 +1019,7 @@ DEPENDENCIES
|
||||
good_migrations
|
||||
haml
|
||||
haml_lint
|
||||
highline (= 2.0.3)
|
||||
highline
|
||||
i18n
|
||||
i18n-js (~> 3.9.0)
|
||||
i18n-tasks
|
||||
@@ -1082,6 +1083,7 @@ DEPENDENCIES
|
||||
rubocop-rspec_rails
|
||||
sd_notify
|
||||
select2-rails!
|
||||
shakapacker (= 6.6.0)
|
||||
shoulda-matchers
|
||||
sidekiq
|
||||
sidekiq-scheduler
|
||||
@@ -1107,13 +1109,12 @@ DEPENDENCIES
|
||||
web!
|
||||
web-console
|
||||
webmock
|
||||
webpacker (~> 5)
|
||||
whenever
|
||||
wicked_pdf
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.2.9p265
|
||||
ruby 3.4.8p72
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.19
|
||||
4.0.3
|
||||
|
||||
2
Procfile
2
Procfile
@@ -1,5 +1,5 @@
|
||||
# Foreman Procfile. Start all dev server processes with: `foreman start`
|
||||
|
||||
rails: DEV_CACHING=true bundle exec rails s -p 3000
|
||||
webpack: ./bin/webpack-dev-server
|
||||
webpack: ./bin/webpacker-dev-server
|
||||
sidekiq: DEV_CACHING=true bundle exec sidekiq -q mailers -q default
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Foreman Procfile for Docker env. Start all dev server processes with: `bundle exec foreman start -f Procfile.docker`
|
||||
|
||||
webpack: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpack-dev-server
|
||||
webpack: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 ./bin/webpacker-dev-server
|
||||
sidekiq: DEV_CACHING=true bundle exec sidekiq -q mailers -q default
|
||||
rails: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 DEV_CACHING=true bundle exec rails s -p 3000 -b 0.0.0.0
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
angular.module('Darkswarm').controller "TmpCtrl", ($scope)->
|
||||
$scope.test = {foo: "bar"}
|
||||
@@ -1,4 +1,4 @@
|
||||
= render ConfirmModalComponent.new(id: dom_id(@order, :ship), confirm_reflexes: "click->Admin::OrdersReflex#ship", controller: "orders", reflex: "Admin::Orders#ship") do
|
||||
= render ConfirmModalComponent.new(id: dom_id(@order, :ship), confirm_actions: "click->modal#close", confirm_reflexes: "click->Admin::OrdersReflex#ship", controller: "orders", reflex: "Admin::Orders#ship") do
|
||||
%div{class: "margin-bottom-30"}
|
||||
%p= t('spree.admin.orders.shipment.mark_as_shipped_message_html')
|
||||
%div{class: "margin-bottom-30"}
|
||||
|
||||
@@ -11,10 +11,10 @@ module Spree
|
||||
respond_to :html
|
||||
|
||||
PAYMENT_METHODS = %w{
|
||||
Spree::PaymentMethod::Check
|
||||
Spree::Gateway::PayPalExpress
|
||||
Spree::Gateway::StripeSCA
|
||||
}.index_with(&:constantize).freeze
|
||||
Spree::PaymentMethod::Check
|
||||
}.freeze
|
||||
|
||||
def create
|
||||
force_environment
|
||||
@@ -95,7 +95,7 @@ module Spree
|
||||
@payment_method = PaymentMethod.find(params[:pm_id])
|
||||
end
|
||||
else
|
||||
@payment_method = PAYMENT_METHODS.fetch(params[:provider_type], PaymentMethod).new
|
||||
@payment_method = PaymentMethod.new(type: params[:provider_type])
|
||||
end
|
||||
|
||||
render partial: 'provider_settings'
|
||||
@@ -117,7 +117,7 @@ module Spree
|
||||
end
|
||||
|
||||
def validate_payment_method_provider
|
||||
valid_payment_methods = Rails.application.config.spree.payment_methods.map(&:to_s)
|
||||
valid_payment_methods = PAYMENT_METHODS
|
||||
return if valid_payment_methods.include?(params[:payment_method][:type])
|
||||
|
||||
flash[:error] = Spree.t(:invalid_payment_provider)
|
||||
@@ -133,13 +133,11 @@ module Spree
|
||||
end
|
||||
|
||||
def load_providers
|
||||
providers = Gateway.providers.sort_by(&:name)
|
||||
providers = PAYMENT_METHODS.dup
|
||||
|
||||
unless show_stripe?
|
||||
providers.reject! { |provider| stripe_provider?(provider) }
|
||||
end
|
||||
providers.delete("Spree::Gateway::StripeSCA") unless show_stripe?
|
||||
|
||||
providers
|
||||
providers.map(&:constantize)
|
||||
end
|
||||
|
||||
# Show Stripe as an option if enabled, or if the
|
||||
@@ -164,10 +162,6 @@ module Spree
|
||||
@payment_method.try(:type) == "Spree::Gateway::StripeSCA"
|
||||
end
|
||||
|
||||
def stripe_provider?(provider)
|
||||
provider.name.ends_with?("StripeSCA")
|
||||
end
|
||||
|
||||
def base_params
|
||||
@base_params ||= PermittedAttributes::PaymentMethod.new(params[:payment_method]).
|
||||
call.to_h.with_indifferent_access
|
||||
|
||||
@@ -90,11 +90,13 @@ class VoucherAdjustmentsController < BaseController
|
||||
voucher_code: voucher_params[:voucher_code], enterprise: @order.distributor
|
||||
)
|
||||
voucher = vine_voucher_validator.validate
|
||||
errors = vine_voucher_validator.errors
|
||||
|
||||
return nil if vine_voucher_validator.errors[:not_found_voucher].present?
|
||||
return nil if errors[:not_found_voucher].present?
|
||||
|
||||
if vine_voucher_validator.errors.present?
|
||||
@order.errors.add(:voucher_code, I18n.t('checkout.errors.add_voucher_error'))
|
||||
if errors.present?
|
||||
message = errors[:invalid_voucher] || I18n.t('checkout.errors.add_voucher_error')
|
||||
@order.errors.add(:voucher_code, message)
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ module ApplicationHelper
|
||||
end
|
||||
end
|
||||
|
||||
# Update "v1" to invalidate existing cache key
|
||||
def cache_key_with_locale(key, locale)
|
||||
Array.wrap(key) + [locale.to_s, I18nDigests.for_locale(locale)]
|
||||
Array.wrap(key) + ["v1", locale.to_s, I18nDigests.for_locale(locale)]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -31,7 +31,6 @@ module Spree
|
||||
preference :admin_products_per_page, :integer, default: 10
|
||||
# Should only be true if you don't need to track inventory
|
||||
preference :allow_backorder_shipping, :boolean, default: false
|
||||
preference :allow_checkout_on_gateway_error, :boolean, default: false
|
||||
preference :allow_guest_checkout, :boolean, default: true
|
||||
preference :currency_decimal_mark, :string, default: "."
|
||||
preference :currency_symbol_position, :string, default: "before"
|
||||
|
||||
@@ -437,18 +437,13 @@ module Spree
|
||||
#
|
||||
# Returns:
|
||||
# - true if all pending_payments processed successfully
|
||||
# - true if a payment failed, ie. raised a GatewayError
|
||||
# which gets rescued and converted to TRUE when
|
||||
# :allow_checkout_gateway_error is set to true
|
||||
# - false if a payment failed, ie. raised a GatewayError
|
||||
# which gets rescued and converted to FALSE when
|
||||
# :allow_checkout_on_gateway_error is set to false
|
||||
# which gets rescued and converted to FALSE
|
||||
#
|
||||
def process_payments!
|
||||
process_each_payment(&:process!)
|
||||
rescue Core::GatewayError => e
|
||||
result = !!Spree::Config[:allow_checkout_on_gateway_error]
|
||||
errors.add(:base, e.message) && (return result)
|
||||
errors.add(:base, e.message) && (return false)
|
||||
end
|
||||
|
||||
def process_payments_offline!
|
||||
|
||||
@@ -52,10 +52,6 @@ module Spree
|
||||
.where(environment: [Rails.env, "", nil])
|
||||
}
|
||||
|
||||
def self.providers
|
||||
Rails.application.config.spree.payment_methods
|
||||
end
|
||||
|
||||
def configured?
|
||||
!stripe? || stripe_configured?
|
||||
end
|
||||
@@ -93,8 +89,8 @@ module Spree
|
||||
type.demodulize.downcase
|
||||
end
|
||||
|
||||
def self.find_with_destroyed(*args)
|
||||
unscoped { find(*args) }
|
||||
def self.find_with_destroyed(*)
|
||||
unscoped { find(*) }
|
||||
end
|
||||
|
||||
def payment_profiles_supported?
|
||||
@@ -118,8 +114,8 @@ module Spree
|
||||
end
|
||||
|
||||
def self.clean_name
|
||||
i18n_key = "spree.admin.payment_methods.providers.#{name.demodulize.downcase}"
|
||||
I18n.t(i18n_key)
|
||||
scope = "spree.admin.payment_methods.providers"
|
||||
I18n.t(name.demodulize.downcase, scope:)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
module Vine
|
||||
class VoucherValidatorService
|
||||
VINE_ERRORS = {
|
||||
# https://github.com/openfoodfoundation/vine/blob/main/app/Enums/ApiResponse.php
|
||||
"This voucher has expired." => :expired,
|
||||
}.freeze
|
||||
|
||||
attr_reader :voucher_code, :errors
|
||||
|
||||
def initialize(voucher_code:, enterprise:)
|
||||
@@ -42,8 +47,10 @@ module Vine
|
||||
end
|
||||
|
||||
def handle_errors(response)
|
||||
if response[:status] == 400
|
||||
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.invalid_voucher")
|
||||
if [400, 409].include?(response[:status])
|
||||
message = response[:body] && JSON.parse(response[:body]).dig("meta", "message")
|
||||
key = VINE_ERRORS.fetch(message, :invalid_voucher)
|
||||
errors[:invalid_voucher] = I18n.t("vine_voucher_validator_service.errors.#{key}")
|
||||
elsif response[:status] == 404
|
||||
errors[:not_found_voucher] =
|
||||
I18n.t("vine_voucher_validator_service.errors.not_found_voucher")
|
||||
|
||||
@@ -7,5 +7,6 @@
|
||||
#no-products-actions
|
||||
%a{ href: "/admin/products/new", class: "button icon-plus", icon: "icon-plus" }
|
||||
= t(:new_product)
|
||||
%a{ href: "/admin/products/import", class: "button icon-upload secondary", icon: "icon-upload" }
|
||||
%a{ href: admin_product_import_path, class: "button icon-upload secondary", icon: "icon-upload" }
|
||||
= t(".import_products")
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
- else
|
||||
= favicon_link_tag "/favicon-staging.ico"
|
||||
%link{href: "https://fonts.googleapis.com/css?family=Roboto:400,300italic,400italic,300,700,700italic|Oswald:300,400,700", rel: "stylesheet", type: "text/css"}
|
||||
%link{href: asset_pack_path("media/fonts/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
|
||||
%link{href: asset_pack_path("static/OFN-v2.woff"), rel: "preload", as: "font", crossorigin: "anonymous"}
|
||||
= render "layouts/matomo_tag"
|
||||
= language_meta_tags
|
||||
|
||||
= stylesheet_pack_tag "darkswarm", "data-turbo-track": "reload", media: "screen"
|
||||
= javascript_pack_tag "application", "data-turbo-track": "reload"
|
||||
= javascript_pack_tag "application", "data-turbo-track": "reload", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
|
||||
|
||||
= render "layouts/shopfront_script" if @shopfront_layout
|
||||
= render "layouts/bugsnag_js"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
= stylesheet_pack_tag "darkswarm", media: "screen"
|
||||
= javascript_include_tag "darkswarm/all"
|
||||
= javascript_pack_tag "application"
|
||||
= javascript_pack_tag "application", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
|
||||
|
||||
= csrf_meta_tags
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
= render "spree/admin/shared/translations"
|
||||
= render "spree/admin/shared/routes"
|
||||
|
||||
= javascript_pack_tag "admin", "data-turbo-track": "reload"
|
||||
= javascript_pack_tag "admin", "data-turbo-track": "reload", defer: false # do not use defer because our javascript currently depend on order of execution of loaded script.
|
||||
|
||||
%script
|
||||
= raw "var AUTH_TOKEN = \"#{form_authenticity_token}\";"
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
// While in feature-toggle, we inherit all files from old admin design.
|
||||
// Individual files may be copied in order to replace the old files.
|
||||
|
||||
@import "vendor/assets/stylesheets/normalize";
|
||||
@import "vendor/assets/stylesheets/responsive-tables";
|
||||
@import "vendor/assets/stylesheets/jquery.powertip";
|
||||
@import "~jquery-ui/themes/base/core";
|
||||
@import "~jquery-ui/themes/base/button";
|
||||
@import "~jquery-ui/themes/base/resizable";
|
||||
@import "vendor/assets/stylesheets/jquery-ui-theme";
|
||||
@import "~jquery-ui/themes/base/dialog";
|
||||
@import "assets/stylesheets/normalize";
|
||||
@import "assets/stylesheets/responsive-tables";
|
||||
@import "assets/stylesheets/jquery.powertip";
|
||||
@import "jquery-ui/themes/base/core";
|
||||
@import "jquery-ui/themes/base/button";
|
||||
@import "jquery-ui/themes/base/resizable";
|
||||
@import "assets/stylesheets/jquery-ui-theme";
|
||||
@import "jquery-ui/themes/base/dialog";
|
||||
@import "../shared/ng-tags-input.min";
|
||||
@import "vendor/assets/stylesheets/select2.css.scss";
|
||||
@import "~flatpickr/dist/flatpickr";
|
||||
@import "~flatpickr/dist/themes/material_blue";
|
||||
@import "~shortcut-buttons-flatpickr/dist/themes/light";
|
||||
@import "assets/stylesheets/select2";
|
||||
@import "flatpickr/dist/flatpickr";
|
||||
@import "flatpickr/dist/themes/material_blue";
|
||||
@import "shortcut-buttons-flatpickr/dist/themes/light";
|
||||
|
||||
@import "../admin/globals/functions";
|
||||
@import "globals/palette"; // admin_v3
|
||||
@@ -123,13 +123,13 @@
|
||||
@import "shared/question-mark-icon";
|
||||
@import "../admin/question-mark-tooltip";
|
||||
|
||||
@import "~tom-select/src/scss/tom-select.default";
|
||||
@import "tom-select/src/scss/tom-select.default";
|
||||
@import "components/tom_select"; // admin_v3
|
||||
|
||||
@import "app/components/modal_component/modal_component";
|
||||
@import "app/components/vertical_ellipsis_menu_component/vertical_ellipsis_menu_component"; // admin_v3 and only V3
|
||||
@import "app/components/tag_list_input_component/tag_list_input_component";
|
||||
@import "app/webpacker/css/admin/trix.scss";
|
||||
@import "modal_component/modal_component";
|
||||
@import "vertical_ellipsis_menu_component/vertical_ellipsis_menu_component"; // admin_v3 and only V3
|
||||
@import "tag_list_input_component/tag_list_input_component";
|
||||
@import "admin/trix";
|
||||
|
||||
@import "terms_of_service_banner"; // admin_v3
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
@import 'vendor/assets/stylesheets/autocomplete';
|
||||
@import 'vendor/assets/stylesheets/leaflet';
|
||||
@import 'assets/stylesheets/autocomplete';
|
||||
@import 'assets/stylesheets/leaflet';
|
||||
@import 'variables';
|
||||
@import '../shared/variables/layout';
|
||||
@import '../shared/utilities';
|
||||
@import '~foundation-sites/scss/foundation';
|
||||
@import 'foundation-sites/scss/foundation';
|
||||
|
||||
@import 'big-input';
|
||||
@import 'branding';
|
||||
@@ -77,4 +77,4 @@ ofn-modal {
|
||||
@import "../shared/question-mark-icon";
|
||||
@import '../admin/shared/scroll_bar';
|
||||
|
||||
@import 'app/components/modal_component/modal_component';
|
||||
@import 'modal_component/modal_component';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "~foundation-sites/scss/foundation/components/global";
|
||||
@import "foundation-sites/scss/foundation/components/global";
|
||||
|
||||
// Brand guide colours:
|
||||
// International: #81c26e
|
||||
|
||||
@@ -1,72 +1,6 @@
|
||||
module.exports = function(api) {
|
||||
var validEnv = ['development', 'test', 'production']
|
||||
var currentEnv = api.env()
|
||||
var isDevelopmentEnv = api.env('development')
|
||||
var isProductionEnv = api.env('production')
|
||||
var isTestEnv = api.env('test')
|
||||
module.exports = function (api) {
|
||||
const defaultConfigFunc = require("shakapacker/package/babel/preset.js");
|
||||
const resultConfig = defaultConfigFunc(api);
|
||||
|
||||
if (!validEnv.includes(currentEnv)) {
|
||||
throw new Error(
|
||||
'Please specify a valid `NODE_ENV` or ' +
|
||||
'`BABEL_ENV` environment variables. Valid values are "development", ' +
|
||||
'"test", and "production". Instead, received: ' +
|
||||
JSON.stringify(currentEnv) +
|
||||
'.'
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
presets: [
|
||||
isTestEnv && [
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: 'current'
|
||||
}
|
||||
}
|
||||
],
|
||||
(isProductionEnv || isDevelopmentEnv) && [
|
||||
'@babel/preset-env',
|
||||
{
|
||||
forceAllTransforms: true,
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 3,
|
||||
modules: false,
|
||||
exclude: ['transform-typeof-symbol']
|
||||
}
|
||||
]
|
||||
].filter(Boolean),
|
||||
plugins: [
|
||||
'babel-plugin-macros',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
isTestEnv && 'babel-plugin-dynamic-import-node',
|
||||
'@babel/plugin-transform-destructuring',
|
||||
[
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
{
|
||||
loose: true
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
{
|
||||
useBuiltIns: true
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
helpers: false
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/plugin-transform-regenerator',
|
||||
{
|
||||
async: false
|
||||
}
|
||||
],
|
||||
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
|
||||
["@babel/plugin-proposal-private-methods", { "loose": true }]
|
||||
].filter(Boolean)
|
||||
}
|
||||
}
|
||||
return resultConfig;
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@ FileUtils.chdir APP_ROOT do
|
||||
# Add necessary setup steps to this file.
|
||||
|
||||
puts "== Installing dependencies =="
|
||||
system! "script/install-bundler"
|
||||
|
||||
# Check first (it's quicker), then install new gems if necessary
|
||||
system("bundle check 2> /dev/null") || system!(BUNDLE_ENV, "bundle install")
|
||||
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||
ENV["NODE_ENV"] ||= "development"
|
||||
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
|
||||
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require "bundler/setup"
|
||||
|
||||
require "webpacker"
|
||||
require "webpacker/webpack_runner"
|
||||
|
||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
|
||||
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
Webpacker::WebpackRunner.run(ARGV)
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
|
||||
ENV["NODE_ENV"] ||= "development"
|
||||
ENV["NODE_OPTIONS"] ||= "--openssl-legacy-provider"
|
||||
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
15
bin/yarn
15
bin/yarn
@@ -1,9 +1,16 @@
|
||||
#!/usr/bin/env ruby
|
||||
APP_ROOT = File.expand_path('..', __dir__)
|
||||
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
begin
|
||||
exec "yarnpkg", *ARGV
|
||||
rescue Errno::ENOENT
|
||||
yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
|
||||
select { |dir| File.expand_path(dir) != __dir__ }.
|
||||
product(["yarn", "yarnpkg", "yarn.cmd", "yarn.ps1"]).
|
||||
map { |dir, file| File.expand_path(file, dir) }.
|
||||
find { |file| File.executable?(file) }
|
||||
|
||||
if yarn
|
||||
exec yarn, *ARGV
|
||||
else
|
||||
$stderr.puts "Yarn executable was not detected in the system."
|
||||
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
|
||||
exit 1
|
||||
|
||||
@@ -89,7 +89,7 @@ services:
|
||||
build: .
|
||||
command: >
|
||||
sh -lc 'until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
|
||||
exec ./bin/webpack-dev-server'
|
||||
exec ./bin/webpacker-dev-server'
|
||||
ports:
|
||||
- "3035:3035"
|
||||
volumes:
|
||||
|
||||
@@ -76,14 +76,6 @@ module Openfoodnetwork
|
||||
end
|
||||
end
|
||||
|
||||
initializer "spree.register.payment_methods" do |app|
|
||||
Rails.application.reloader.to_prepare do
|
||||
app.config.spree.payment_methods = [
|
||||
Spree::PaymentMethod::Check
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
initializer "spree.mail.settings" do |_app|
|
||||
Rails.application.reloader.to_prepare do
|
||||
Spree::Core::MailSettings.init
|
||||
@@ -131,14 +123,6 @@ module Openfoodnetwork
|
||||
end
|
||||
end
|
||||
|
||||
# Register Spree payment methods
|
||||
initializer "spree.gateway.payment_methods", :after => "spree.register.payment_methods" do |app|
|
||||
Rails.application.reloader.to_prepare do
|
||||
app.config.spree.payment_methods << Spree::Gateway::StripeSCA
|
||||
app.config.spree.payment_methods << Spree::Gateway::PayPalExpress
|
||||
end
|
||||
end
|
||||
|
||||
initializer "ofn.reports" do |app|
|
||||
module ::Reporting; end
|
||||
Rails.application.reloader.to_prepare do
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
module WebpackImageExtension
|
||||
def image_pack_path(image)
|
||||
# The Webpacker::Helper#resolve_path_to_image method is incredibly useful
|
||||
# for nicely fetching Webpacker image paths, but it's private.
|
||||
resolve_path_to_image(image)
|
||||
end
|
||||
end
|
||||
|
||||
Webpacker::Helper.include WebpackImageExtension
|
||||
@@ -627,6 +627,7 @@ en:
|
||||
errors:
|
||||
vine_api: "There was an error communicating with the API, please try again later."
|
||||
invalid_voucher: "The voucher is not valid"
|
||||
expired: "The voucher has expired"
|
||||
not_found_voucher: "Sorry, we couldn't find that voucher, please check the code."
|
||||
vine_voucher_redeemer_service:
|
||||
errors:
|
||||
|
||||
@@ -115,6 +115,67 @@ en_CA:
|
||||
blank: "can't be blank"
|
||||
too_short: "is too short (minimum is %{count} characters)"
|
||||
errors:
|
||||
messages:
|
||||
content_type_invalid:
|
||||
one: "has an invalid content type (authorized content type is %{authorized_human_content_types})"
|
||||
other: "has an invalid content type (authorized content types are %{authorized_human_content_types})"
|
||||
content_type_spoofed:
|
||||
one: "has a content type that is not equivalent to the one that is detected through its content (authorized content type is %{authorized_human_content_types})"
|
||||
other: "has a content type that is not equivalent to the one that is detected through its content (authorized content types are %{authorized_human_content_types})"
|
||||
file_size_not_less_than: "file size must be less than %{max} (current size is %{file_size})"
|
||||
file_size_not_less_than_or_equal_to: "file size must be less than or equal to %{max} (current size is %{file_size})"
|
||||
file_size_not_greater_than: "file size must be greater than %{min} (current size is %{file_size})"
|
||||
file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min} (current size is %{file_size})"
|
||||
file_size_not_between: "file size must be between %{min} and %{max} (current size is %{file_size})"
|
||||
file_size_not_equal_to: "file size must be equal to %{exact} (current size is %{file_size})"
|
||||
total_file_size_not_less_than: "total file size must be less than %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_greater_than: "total file size must be greater than %{min} (current size is %{total_file_size})"
|
||||
total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min} (current size is %{total_file_size})"
|
||||
total_file_size_not_between: "total file size must be between %{min} and %{max} (current size is %{total_file_size})"
|
||||
total_file_size_not_equal_to: "total file size must be equal to %{exact} (current size is %{total_file_size})"
|
||||
duration_not_less_than: "duration must be less than %{max} (current duration is %{duration})"
|
||||
duration_not_less_than_or_equal_to: "duration must be less than or equal to %{max} (current duration is %{duration})"
|
||||
duration_not_greater_than: "duration must be greater than %{min} (current duration is %{duration})"
|
||||
duration_not_greater_than_or_equal_to: "duration must be greater than or equal to %{min} (current duration is %{duration})"
|
||||
duration_not_between: "duration must be between %{min} and %{max} (current duration is %{duration})"
|
||||
duration_not_equal_to: "duration must be equal to %{exact} (current duration is %{duration})"
|
||||
limit_out_of_range:
|
||||
zero: "no files attached (must have between %{min} and %{max} files)"
|
||||
one: "only 1 file attached (must have between %{min} and %{max} files)"
|
||||
other: "total number of files must be between %{min} and %{max} files (there are %{count} files attached)"
|
||||
limit_min_not_reached:
|
||||
zero: "no files attached (must have at least %{min} files)"
|
||||
one: "only 1 file attached (must have at least %{min} files)"
|
||||
other: "%{count} files attached (must have at least %{min} files)"
|
||||
limit_max_exceeded:
|
||||
zero: "no files attached (maximum is %{max} files)"
|
||||
one: "too many files attached (maximum is %{max} files, got %{count})"
|
||||
other: "too many files attached (maximum is %{max} files, got %{count})"
|
||||
attachment_missing: "is missing its attachment"
|
||||
media_metadata_missing: "is not a valid media file"
|
||||
dimension_min_not_included_in: "must be greater than or equal to %{width} x %{height} pixels"
|
||||
dimension_max_not_included_in: "must be less than or equal to %{width} x %{height} pixels"
|
||||
dimension_width_not_included_in: "width is not included between %{min} and %{max} pixels"
|
||||
dimension_height_not_included_in: "height is not included between %{min} and %{max} pixels"
|
||||
dimension_width_not_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixels"
|
||||
dimension_height_not_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixels"
|
||||
dimension_width_not_less_than_or_equal_to: "width must be less than or equal to %{length} pixels"
|
||||
dimension_height_not_less_than_or_equal_to: "height must be less than or equal to %{length} pixels"
|
||||
dimension_width_not_equal_to: "width must be equal to %{length} pixels"
|
||||
dimension_height_not_equal_to: "height must be equal to %{length} pixels"
|
||||
aspect_ratio_not_square: "must be square (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_portrait: "must be portrait (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_landscape: "must be landscape (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_not_x_y: "must be %{authorized_aspect_ratios} (current file is %{width}x%{height}px)"
|
||||
aspect_ratio_invalid: "has an invalid aspect ratio (valid aspect ratios are %{authorized_aspect_ratios})"
|
||||
file_not_processable: "is not identified as a valid media file"
|
||||
pages_not_less_than: "page count must be less than %{max} (current page count is %{pages})"
|
||||
pages_not_less_than_or_equal_to: "page count must be less than or equal to %{max} (current page count is %{pages})"
|
||||
pages_not_greater_than: "page count must be greater than %{min} (current page count is %{pages})"
|
||||
pages_not_greater_than_or_equal_to: "page count must be greater than or equal to %{min} (current page count is %{pages})"
|
||||
pages_not_between: "page count must be between %{min} and %{max} (current page count is %{pages})"
|
||||
pages_not_equal_to: "page count must be equal to %{exact} (current page count is %{pages})"
|
||||
not_found:
|
||||
title: "The page you were looking for doesn't exist (404)"
|
||||
message_html: "<b>Please try again</b> <p>This might be a temporary problem. Please click the back button to return to the previous screen or go back to <a href='/'>Home</a>and try again.</p> <b>Contact support <p>If the problem persists or is urgent, please tell us about it. Find our contact details from the global <a href='https://openfoodnetwork.org/ofn-local/' target='blank'>Open Food Network Local page</a>.</p> <p>It really helps us if you can give as much detail as possible about what the missing page is about.</p>"
|
||||
@@ -520,6 +581,7 @@ en_CA:
|
||||
errors:
|
||||
vine_api: "There was an error communicating with the API, please try again later."
|
||||
invalid_voucher: "The voucher is not valid"
|
||||
expired: "The voucher has expired"
|
||||
not_found_voucher: "Sorry, we couldn't find that voucher, please check the code."
|
||||
vine_voucher_redeemer_service:
|
||||
errors:
|
||||
@@ -3908,6 +3970,8 @@ en_CA:
|
||||
destroy:
|
||||
success: Webhook endpoint successfully deleted
|
||||
error: Webhood endpoint failed to delete
|
||||
test:
|
||||
success: Some test data will be sent to the webhook url
|
||||
spree:
|
||||
order_updated: "Order Updated"
|
||||
cannot_perform_operation: "Can not perform this operation"
|
||||
@@ -4014,6 +4078,7 @@ en_CA:
|
||||
logourl: "Logourl"
|
||||
are_you_sure_delete: "Are you sure you want to delete this record?"
|
||||
confirm_delete: "Confirm Deletion"
|
||||
tag_rule: "Tag Rule"
|
||||
voucher: "Voucher"
|
||||
configurations: "Configurations"
|
||||
general_settings: "General Settings"
|
||||
@@ -4897,6 +4962,8 @@ en_CA:
|
||||
create_placeholder: Enter the URL of the remove webhook endpoint
|
||||
event_types:
|
||||
order_cycle_opened: Order Cycle Opened
|
||||
payment_status_changed: Post webhook on Payment status change
|
||||
test_endpoint: Test webhook endpoint
|
||||
invisible_captcha:
|
||||
sentence_for_humans: "Please leave empty"
|
||||
timestamp_error_message: "Please try again after 5 seconds."
|
||||
|
||||
@@ -1616,7 +1616,7 @@ hu:
|
||||
has_no_shipping_methods: "%{enterprise} nem rendelkezik szállítási móddal"
|
||||
has_no_enterprise_fees: "A %{enterprise}-nek nincsenek vállalkozási díjai"
|
||||
flashes:
|
||||
dismiss: Elutasítás
|
||||
dismiss: Bezárás
|
||||
side_menu:
|
||||
enterprise:
|
||||
primary_details: "Főbb adatok"
|
||||
@@ -2620,7 +2620,7 @@ hu:
|
||||
failed_to_create_enterprise: "Nem sikerült létrehozni a vállalkozást."
|
||||
failed_to_create_enterprise_unknown: "Nem sikerült létrehozni a vállalkozást. Győződj meg arról, hogy minden mezőt hiánytalanul kitöltöttél."
|
||||
failed_to_update_enterprise_unknown: "Nem sikerült frissíteni a vállalkozást. Győződj meg arról, hogy minden mezőt hiánytalanul kitöltöttél."
|
||||
enterprise_confirm_delete_message: "Ezzel a vállalkozás által szállított %{product} is törlődik. Biztos, hogy akarod folytatni?"
|
||||
enterprise_confirm_delete_message: "Ezzel a vállalkozás %{product} terméke is törlődik. Biztos, hogy akarod folytatni?"
|
||||
order_not_saved_yet: "Megrendelésed még nem lett elmentve. Adj nekünk néhány másodpercet, hogy befejezzük!"
|
||||
filter_by: "Szűrés"
|
||||
hide_filters: "Szűrők elrejtése"
|
||||
@@ -2782,7 +2782,7 @@ hu:
|
||||
instagram: "Instagram"
|
||||
instagram_placeholder: "pl. @instagram_handle"
|
||||
limit_reached:
|
||||
headline: "Ó ne!"
|
||||
headline: "Ó, ne!"
|
||||
message: "Elérted a korlátot!"
|
||||
text: "Elérted a vállalkozások számának korlátját, amelyeknek a tulajdonosa lehetsz"
|
||||
action: "Vissza a kezdőlapra"
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
@@ -1,35 +0,0 @@
|
||||
const { environment } = require('@rails/webpacker')
|
||||
|
||||
module.exports = environment
|
||||
|
||||
function hotfixPostcssLoaderConfig (subloader) {
|
||||
const subloaderName = subloader.loader
|
||||
if (subloaderName === 'postcss-loader') {
|
||||
if (subloader.options.postcssOptions) {
|
||||
console.log(
|
||||
'\x1b[31m%s\x1b[0m',
|
||||
'Remove postcssOptions workaround in config/webpack/environment.js'
|
||||
)
|
||||
} else {
|
||||
subloader.options.postcssOptions = subloader.options.config;
|
||||
delete subloader.options.config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addQuietDepsToSassLoader (subloader) {
|
||||
if (subloader.loader === 'sass-loader') {
|
||||
subloader.options.sassOptions = {
|
||||
...subloader.options.sassOptions,
|
||||
quietDeps: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
environment.loaders.keys().forEach(loaderName => {
|
||||
const loader = environment.loaders.get(loaderName);
|
||||
if (loaderName === 'sass') {
|
||||
loader.use.forEach(addQuietDepsToSassLoader);
|
||||
}
|
||||
loader.use.forEach(hotfixPostcssLoaderConfig);
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
@@ -1,5 +0,0 @@
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
|
||||
|
||||
const environment = require('./environment')
|
||||
|
||||
module.exports = environment.toWebpackConfig()
|
||||
20
config/webpack/webpack.config.js
Normal file
20
config/webpack/webpack.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const { webpackConfig, merge } = require("shakapacker")
|
||||
|
||||
const options = {
|
||||
resolve: {
|
||||
extensions: [".mjs", ".js", ".sass",".scss", ".css", ".module.sass", ".module.scss", ".module.css", ".png", ".svg", ".gif", ".jpeg", ".jpg", ".eot", ".ttf", ".woff"]
|
||||
}
|
||||
}
|
||||
|
||||
const OFNwebpackConfig = merge(webpackConfig, options)
|
||||
|
||||
// quiet deprecations in dependencies, notably foundation-sites
|
||||
const scssRule = OFNwebpackConfig.module.rules.find((rule) => rule.test.test(".scss"))
|
||||
const sassDefaultOptions = scssRule.use[3].options.sassOptions
|
||||
scssRule.use[3].options.sassOptions = {
|
||||
...sassDefaultOptions,
|
||||
quietDeps: true
|
||||
}
|
||||
|
||||
// This results in a new object copied from the mutable global
|
||||
module.exports = OFNwebpackConfig
|
||||
@@ -8,7 +8,7 @@ default: &default
|
||||
cache_path: tmp/cache/webpacker
|
||||
webpack_compile_output: true
|
||||
|
||||
# Additional paths webpack should lookup modules
|
||||
# Additional paths webpack should look up modules
|
||||
# ['app/assets', 'engine/foo/app/assets']
|
||||
additional_paths: [
|
||||
'vendor',
|
||||
@@ -25,37 +25,6 @@ default: &default
|
||||
# Extract and emit a css file
|
||||
extract_css: true
|
||||
|
||||
static_assets_extensions:
|
||||
- .jpg
|
||||
- .jpeg
|
||||
- .png
|
||||
- .gif
|
||||
- .tiff
|
||||
- .ico
|
||||
- .svg
|
||||
- .eot
|
||||
- .otf
|
||||
- .ttf
|
||||
- .woff
|
||||
- .woff2
|
||||
|
||||
extensions:
|
||||
- .mjs
|
||||
- .js
|
||||
- .sass
|
||||
- .scss
|
||||
- .css
|
||||
- .module.sass
|
||||
- .module.scss
|
||||
- .module.css
|
||||
- .png
|
||||
- .svg
|
||||
- .gif
|
||||
- .jpeg
|
||||
- .jpg
|
||||
- .eot
|
||||
- .ttf
|
||||
- .woff
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
@@ -66,22 +35,40 @@ development:
|
||||
https: false
|
||||
host: localhost
|
||||
port: 3035
|
||||
public: localhost:3035
|
||||
# Hot Module Replacement updates modules while the application is running without a full reload
|
||||
hmr: false
|
||||
# Inline should be set to true if using HMR
|
||||
inline: true
|
||||
overlay: true
|
||||
# Defaults to the inverse of hmr. Uncomment to manually set this.
|
||||
# live_reload: true
|
||||
client:
|
||||
# Should we show a full-screen overlay in the browser when there are compiler errors or warnings?
|
||||
overlay: false
|
||||
# May also be a string
|
||||
# webSocketURL:
|
||||
# hostname: "0.0.0.0"
|
||||
# pathname: "/ws"
|
||||
# port: 8080
|
||||
# Should we use gzip compression?
|
||||
compress: true
|
||||
disable_host_check: true
|
||||
use_local_ip: false
|
||||
quiet: false
|
||||
pretty: false
|
||||
# Note that apps that do not check the host are vulnerable to DNS rebinding attacks
|
||||
allowed_hosts: "all"
|
||||
#TODO Old config
|
||||
#pretty: false
|
||||
pretty: true
|
||||
headers:
|
||||
'Access-Control-Allow-Origin': '*'
|
||||
watch_options:
|
||||
ignored:
|
||||
- '**/node_modules/**'
|
||||
- '**/*.swp'
|
||||
static:
|
||||
watch:
|
||||
ignored:
|
||||
- '**/node_modules/**'
|
||||
- '**/*.swp'
|
||||
|
||||
test:
|
||||
<<: *default
|
||||
compile: true
|
||||
compiler_strategy: mtime
|
||||
|
||||
# Compile test packs to a separate directory
|
||||
public_output_path: packs-test
|
||||
|
||||
production: &production
|
||||
<<: *default
|
||||
@@ -91,9 +78,3 @@ production: &production
|
||||
|
||||
# Cache manifest.json for performance
|
||||
cache_manifest: true
|
||||
|
||||
test:
|
||||
<<: *default
|
||||
|
||||
# Compile test packs to a separate directory
|
||||
public_output_path: packs-test
|
||||
|
||||
@@ -1,57 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'highline/import'
|
||||
|
||||
# see last line where we create an admin if there is none, asking for email and password
|
||||
def prompt_for_admin_password
|
||||
if ENV['ADMIN_PASSWORD']
|
||||
password = ENV['ADMIN_PASSWORD'].dup
|
||||
say "Admin Password #{password}"
|
||||
else
|
||||
password = ask('Password [ofn123]: ') do |q|
|
||||
q.echo = false
|
||||
q.validate = /^(|.{5,40})$/
|
||||
q.responses[:not_valid] = 'Invalid password. Must be at least 5 characters long.'
|
||||
q.whitespace = :strip
|
||||
end
|
||||
password = 'ofn123' if password.blank?
|
||||
end
|
||||
|
||||
password
|
||||
end
|
||||
|
||||
def prompt_for_admin_email
|
||||
if ENV['ADMIN_EMAIL']
|
||||
email = ENV['ADMIN_EMAIL'].dup
|
||||
say "Admin User #{email}"
|
||||
else
|
||||
email = ask('Email [ofn@example.com]: ') do |q|
|
||||
q.echo = true
|
||||
q.whitespace = :strip
|
||||
end
|
||||
email = 'ofn@example.com' if email.blank?
|
||||
end
|
||||
|
||||
email
|
||||
end
|
||||
|
||||
def create_admin_user
|
||||
attributes = read_user_attributes
|
||||
|
||||
load 'spree/user.rb'
|
||||
|
||||
if Spree::User.find_by(email: attributes[:email])
|
||||
say <<~TEXT
|
||||
|
||||
WARNING: There is already a user with the email: #{email},
|
||||
so no account changes were made. If you wish to create an additional admin
|
||||
user, please run rake spree_auth:admin:create again with a different email.
|
||||
|
||||
TEXT
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
admin = Spree::User.new(attributes)
|
||||
admin.skip_confirmation!
|
||||
admin.skip_confirmation_notification!
|
||||
@@ -60,24 +11,22 @@ def create_admin_user
|
||||
ValidEmail2::Address.define_method(:valid_mx?) { true }
|
||||
|
||||
if admin.save
|
||||
say "New admin user persisted!"
|
||||
printf <<~TEXT
|
||||
New admin user persisted!
|
||||
Username: #{admin.email}
|
||||
Password: #{admin.password}
|
||||
TEXT
|
||||
else
|
||||
say "There was some problems with persisting new admin user:"
|
||||
printf "There was some problems with persisting new admin user:\n"
|
||||
admin.errors.full_messages.each do |error|
|
||||
say error
|
||||
printf "#{error}\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_user_attributes
|
||||
if ENV.fetch("AUTO_ACCEPT", true)
|
||||
password = ENV.fetch("ADMIN_PASSWORD", "ofn123")
|
||||
email = ENV.fetch("ADMIN_EMAIL", "ofn@example.com")
|
||||
else
|
||||
say 'Create the admin user (press enter for defaults).'
|
||||
email = prompt_for_admin_email
|
||||
password = prompt_for_admin_password
|
||||
end
|
||||
password = ENV.fetch("ADMIN_PASSWORD", "ofn123")
|
||||
email = ENV.fetch("ADMIN_EMAIL", "ofn@example.com")
|
||||
|
||||
{
|
||||
admin: true,
|
||||
@@ -88,4 +37,4 @@ def read_user_attributes
|
||||
}
|
||||
end
|
||||
|
||||
create_admin_user if Spree::User.admin.empty?
|
||||
create_admin_user if Spree::User.none?
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Catalog::ProductImport::ProductsResetStrategy do
|
||||
let(:products_reset) { described_class.new(excluded_items_ids) }
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class AffiliateSalesQuery
|
||||
<<~SQL.squish
|
||||
spree_products.name AS product_name,
|
||||
spree_variants.display_name AS unit_name,
|
||||
spree_products.variant_unit AS unit_type,
|
||||
spree_variants.variant_unit AS unit_type,
|
||||
spree_variants.unit_value AS units,
|
||||
spree_variants.unit_presentation,
|
||||
spree_line_items.price,
|
||||
|
||||
@@ -6,7 +6,17 @@ RSpec.describe AffiliateSalesQuery do
|
||||
subject(:query) { described_class }
|
||||
|
||||
describe ".data" do
|
||||
let(:order) { create(:order_with_totals_and_distribution, :completed) }
|
||||
let(:product) { create(:simple_product, name: "Tomatoes") }
|
||||
let(:variant1) {
|
||||
product.variants.first.tap{ |v|
|
||||
v.update!(
|
||||
display_name: "Tomatoes - Roma",
|
||||
variant_unit: "weight", unit_value: 1000, variant_unit_scale: 1000 # 1kg
|
||||
)
|
||||
}
|
||||
}
|
||||
let!(:order1) { create(:order_with_totals_and_distribution, :completed, variant: variant1) }
|
||||
|
||||
let(:today) { Time.zone.today }
|
||||
let(:yesterday) { Time.zone.yesterday }
|
||||
let(:tomorrow) { Time.zone.tomorrow }
|
||||
@@ -18,12 +28,12 @@ RSpec.describe AffiliateSalesQuery do
|
||||
travel_to(Time.zone.today.noon)
|
||||
end
|
||||
|
||||
it "returns data" do
|
||||
it "returns records filtered by date" do
|
||||
# Test data creation takes time.
|
||||
# So I'm executing more tests in one `it` block here.
|
||||
# And make it simpler to call the subject many times:
|
||||
count_rows = lambda do |**args|
|
||||
query.data(order.distributor, **args).count
|
||||
query.data(order1.distributor, **args).count
|
||||
end
|
||||
|
||||
# Without any filters:
|
||||
@@ -47,6 +57,85 @@ RSpec.describe AffiliateSalesQuery do
|
||||
# From tomorrow:
|
||||
expect(count_rows.call(start_date: tomorrow)).to eq 0
|
||||
end
|
||||
|
||||
it "returns data" do
|
||||
labelled_row = query.label_row(query.data(order1.distributor).first)
|
||||
|
||||
expect(labelled_row).to include(
|
||||
product_name: "Tomatoes",
|
||||
unit_name: "Tomatoes - Roma",
|
||||
unit_type: "weight",
|
||||
units: 1000.to_f,
|
||||
unit_presentation: "1kg",
|
||||
price: 10.to_d,
|
||||
distributor_postcode: order1.distributor.address.zipcode,
|
||||
distributor_country: order1.distributor.address.country.name,
|
||||
supplier_postcode: variant1.supplier.address.zipcode,
|
||||
supplier_country: variant1.supplier.address.country.name,
|
||||
quantity_sold: 1,
|
||||
)
|
||||
end
|
||||
|
||||
it "returns data stored in line item at time of order" do
|
||||
# Records are updated after the orders are created
|
||||
product.update! name: "Tomatoes Updated"
|
||||
variant1.update! display_name: "Tomatoes - Updated Roma", price: 11
|
||||
|
||||
labelled_row = query.label_row(query.data(order1.distributor).first)
|
||||
|
||||
pending "#13220 store product and variant names"
|
||||
expect(labelled_row).to include(
|
||||
product_name: "Tomatoes",
|
||||
unit_name: "Tomatoes - Roma",
|
||||
price: 10.to_d, # this price is hardcoded in the line item factory.
|
||||
)
|
||||
end
|
||||
|
||||
context "with multiple orders" do
|
||||
let!(:order2) {
|
||||
create(:order_with_totals_and_distribution, :completed, variant: product.variants.first,
|
||||
distributor: order1.distributor)
|
||||
}
|
||||
|
||||
it "returns data grouped by product name" do
|
||||
labelled_row = query.label_row(query.data(order1.distributor).first)
|
||||
|
||||
expect(labelled_row).to include(
|
||||
product_name: "Tomatoes",
|
||||
quantity_sold: 2,
|
||||
)
|
||||
end
|
||||
|
||||
context "and multiple variants" do
|
||||
let!(:order2) {
|
||||
create(:order_with_totals_and_distribution, :completed, variant: variant2,
|
||||
distributor: order1.distributor)
|
||||
}
|
||||
let(:variant2) {
|
||||
create_variant_for(product,
|
||||
display_name: "Tomatoes - Cherry",
|
||||
variant_unit: "weight", unit_value: 500, variant_unit_scale: 1) # 500g
|
||||
}
|
||||
|
||||
it "returns data grouped by variant name" do
|
||||
labelled_data = query.data(order1.distributor).map{ |row| query.label_row(row) }
|
||||
|
||||
expect(labelled_data).to include a_hash_including(
|
||||
product_name: "Tomatoes",
|
||||
unit_name: "Tomatoes - Roma",
|
||||
quantity_sold: 1,
|
||||
)
|
||||
expect(labelled_data).to include a_hash_including(
|
||||
product_name: "Tomatoes",
|
||||
unit_name: "Tomatoes - Cherry",
|
||||
quantity_sold: 1,
|
||||
units: 500,
|
||||
unit_presentation: "500g",
|
||||
price: 10,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".label_row" do
|
||||
@@ -81,4 +170,15 @@ RSpec.describe AffiliateSalesQuery do
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Create variant for product, ready to add to line item
|
||||
def create_variant_for(product, **attrs)
|
||||
variant = product.variants.first.dup
|
||||
variant.update!(
|
||||
price: 10,
|
||||
**attrs,
|
||||
)
|
||||
variant.update! on_demand: true
|
||||
variant
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Order
|
||||
RSpec.describe StripeScaPaymentAuthorize do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Order::Updater do
|
||||
let(:order) { create(:order) }
|
||||
let(:updater) { OrderManagement::Order::Updater.new(order) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Stock
|
||||
RSpec.describe Coordinator do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Stock
|
||||
RSpec.describe Estimator do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Stock::Package do
|
||||
context "base tests" do
|
||||
let(:variant) { build(:variant, weight: 25.0) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Stock
|
||||
RSpec.describe Packer do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Stock
|
||||
RSpec.describe Prioritizer do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Subscriptions
|
||||
RSpec.describe Count do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::Estimator do
|
||||
describe "estimating prices for subscription line items" do
|
||||
let!(:subscription) { create(:subscription, with_items: true) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::Form do
|
||||
describe "creating a new subscription" do
|
||||
let!(:shop) { create(:distributor_enterprise) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Subscriptions
|
||||
RSpec.describe PaymentSetup do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::ProxyOrderSyncer do
|
||||
describe "initialization" do
|
||||
let!(:subscription) { create(:subscription) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module OrderManagement
|
||||
module Subscriptions
|
||||
RSpec.describe StripePaymentSetup do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::Summarizer do
|
||||
let(:order) { create(:order) }
|
||||
let(:summarizer) { described_class.new }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::Summary do
|
||||
let(:summary) { described_class.new(123) }
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::Validator do
|
||||
let(:owner) { create(:user) }
|
||||
let(:shop) { create(:enterprise, name: "Shop", owner:) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe OrderManagement::Subscriptions::VariantsList do
|
||||
describe "variant eligibility for subscription" do
|
||||
let!(:shop) { create(:distributor_enterprise) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
module Web
|
||||
RSpec.describe CookiesPolicyHelper do
|
||||
# keeps global state unchanged
|
||||
|
||||
@@ -179,7 +179,7 @@ module.exports = {
|
||||
// transform: { "\\.[jt]sx?$": "babel-jest" },
|
||||
|
||||
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
|
||||
transformIgnorePatterns: ["/node_modules/(?!(stimulus.+)/)"],
|
||||
transformIgnorePatterns: ["/node_modules/(?!stimulus)/"],
|
||||
|
||||
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
|
||||
// unmockedModulePathPatterns: undefined,
|
||||
|
||||
@@ -392,9 +392,9 @@ module Reporting
|
||||
end
|
||||
end
|
||||
|
||||
def filter_scope(*args)
|
||||
def filter_scope(*)
|
||||
chain_to_scope do
|
||||
where(*args)
|
||||
where(*)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
36
package.json
36
package.json
@@ -7,12 +7,21 @@
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/plugin-transform-runtime": "^7.28.5",
|
||||
"@babel/preset-env": "^7.28.5",
|
||||
"@babel/runtime": "^7.28.4",
|
||||
"@floating-ui/dom": "*",
|
||||
"@hotwired/stimulus": "*",
|
||||
"@hotwired/turbo": "*",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
"@stimulus-components/rails-nested-form": "*",
|
||||
"babel-loader": "^8.2.2",
|
||||
"cable_ready": "5.0.6",
|
||||
"coffee-loader": "^5.0.0",
|
||||
"coffeescript": "^2.7.0",
|
||||
"compression-webpack-plugin": "^9.0.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"css-minimizer-webpack-plugin": "^7.0.4",
|
||||
"flatpickr": "*",
|
||||
"foundation-sites": "5.5.3",
|
||||
"hotkeys-js": "*",
|
||||
@@ -21,19 +30,40 @@
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-geosearch": "4.2.2",
|
||||
"leaflet-providers": "3.0.0",
|
||||
"mini-css-extract-plugin": "^2.9.4",
|
||||
"moment": "*",
|
||||
"mrujs": "*",
|
||||
"pnp-webpack-plugin": "^1.7.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-flexbugs-fixes": "^5.0.2",
|
||||
"postcss-import": "^16.1.1",
|
||||
"postcss-loader": "^8.2.0",
|
||||
"postcss-preset-env": "^10.5.0",
|
||||
"regenerator-transform": "^0.15.2",
|
||||
"sass-embedded": "^1.96.0",
|
||||
"sass-loader": "^16.0.6",
|
||||
"select2": "*",
|
||||
"shakapacker": "6.6.0",
|
||||
"shortcut-buttons-flatpickr": "*",
|
||||
"stimulus": "*",
|
||||
"stimulus-autocomplete": "*",
|
||||
"stimulus-flatpickr": "*",
|
||||
"stimulus_reflex": "3.5.5",
|
||||
"style-loader": "^4.0.0",
|
||||
"terser-webpack-plugin": "^5.3.16",
|
||||
"tom-select": "*",
|
||||
"trix": "*",
|
||||
"turbo_power": "*",
|
||||
"webpack": "~4"
|
||||
"webpack": "^5.104.0",
|
||||
"webpack-assets-manifest": "^5.0.6",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"webpack-sources": "^3.3.3"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults",
|
||||
"not IE 11"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@testing-library/dom": "<11.0.0",
|
||||
"jasmine-core": "~5.12.1",
|
||||
@@ -44,6 +74,6 @@
|
||||
"karma-coffee-preprocessor": "~1.0.1",
|
||||
"karma-jasmine": "~0.3.8",
|
||||
"prettier": "*",
|
||||
"webpack-dev-server": "~3"
|
||||
"webpack-dev-server": "^4.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
22
script/bump-ruby.sh
Executable file
22
script/bump-ruby.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Usage: $0 <new-version>"
|
||||
echo "Example: $0 3.4.8"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
OLD_VERSION=$(cat .ruby-version)
|
||||
NEW_VERSION=$1
|
||||
PATTERN="$(echo "$OLD_VERSION" | sed 's:[]\[^$.*/]:\\&:g')"
|
||||
|
||||
sed -i "s/\<$PATTERN\>/$NEW_VERSION/" .ruby-version Dockerfile
|
||||
|
||||
script/rbenv-install.sh
|
||||
|
||||
# Update bundler to the version shipped with Ruby:
|
||||
bundle update --bundler
|
||||
|
||||
git commit -a -m "Bump Ruby from $OLD_VERSION to $NEW_VERSION"
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This shell script looks for the last used Bundler version in Gemfile.lock and
|
||||
# installs exactly that version, removing all other versions.
|
||||
|
||||
# Command line arguments are passed on to `gem install`. So you can call this
|
||||
# script with with arguments:
|
||||
#
|
||||
# ./script/install-bundler --no-ri --no-rdoc
|
||||
|
||||
# This script is used by ofn-install and can by handy in your development
|
||||
# environment.
|
||||
|
||||
# Fail if a single command fails.
|
||||
set -e
|
||||
|
||||
# `grep`: find the occurrences of "BUNDLED WITH" (-m is unnecessary and behaves different on macOS)
|
||||
# `-A`: print the next line after "BUNDLED WITH" as well
|
||||
# `-F`: find exactly that string
|
||||
# `tail -n 1`: take the last line, the version line
|
||||
# `tr -d`: delete all spaces, the indent before the version
|
||||
version="$(grep -A 1 -F "BUNDLED WITH" Gemfile.lock | tail -n 1 | tr -d '[:space:]')"
|
||||
|
||||
# if the length of $version is zero
|
||||
if [ -z "$version" ]; then
|
||||
echo >&2 "No bundler version in Gemfile.lock."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the currently used bundler version.
|
||||
# We ignore all errors with `2>/dev/null || true` in case there is no bundler
|
||||
# or only an orphaned shim installed.
|
||||
current="$(bundler --version 2>/dev/null || true)"
|
||||
|
||||
if [ "$current" = "Bundler version $version" ]; then
|
||||
echo >&2 "Already up-to-date: $current"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Passing on all arguments of this script with "$@".
|
||||
gem install bundler -v "$version" "$@"
|
||||
gem uninstall bundler -v "!= $version" 2>/dev/null || true
|
||||
@@ -10,6 +10,12 @@ set -e
|
||||
|
||||
if ! command -v nodenv > /dev/null; then
|
||||
printf "Please install https://github.com/nodenv/nodenv.\n"
|
||||
printf '```'"\n"
|
||||
printf "git clone https://github.com/nodenv/nodenv.git ~/.nodenv\n"
|
||||
printf "git clone https://github.com/nodenv/node-build.git ~/.nodenv/plugins/node-build\n"
|
||||
printf "nodenv init\n"
|
||||
printf 'eval "$(nodenv init -)"'"\n"
|
||||
printf '```'"\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -24,7 +24,13 @@ if rbenv install --skip-existing; then
|
||||
echo "Ruby is installed."
|
||||
else
|
||||
echo "Upgrading rbenv's ruby-build:"
|
||||
git -C "$(rbenv root)"/plugins/ruby-build pull
|
||||
# If installed with homebrew, use that to update
|
||||
if (command -v brew && brew list --versions ruby-build); then
|
||||
brew update && brew upgrade ruby-build
|
||||
else
|
||||
# Update with git
|
||||
git -C "$(rbenv root)"/plugins/ruby-build pull
|
||||
fi
|
||||
|
||||
rbenv install
|
||||
fi
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# This file defines configurations that are universal to all spec types (feature, system, etc)
|
||||
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
|
||||
# for full configuration, see .simplecov
|
||||
require 'simplecov' if ENV["COVERAGE"]
|
||||
|
||||
require 'pry' unless ENV['CI']
|
||||
require 'view_component/test_helpers'
|
||||
|
||||
require_relative "../config/environment"
|
||||
require 'rspec/rails'
|
||||
require 'rspec/retry'
|
||||
require 'capybara'
|
||||
require 'paper_trail/frameworks/rspec'
|
||||
require "factory_bot_rails"
|
||||
|
||||
require 'shoulda/matchers'
|
||||
Shoulda::Matchers.configure do |config|
|
||||
config.integrate do |with|
|
||||
with.test_framework :rspec
|
||||
with.library :rails
|
||||
end
|
||||
end
|
||||
|
||||
require 'knapsack_pro'
|
||||
KnapsackPro::Adapters::RSpecAdapter.bind
|
||||
|
||||
if ENV["COVERAGE"] && defined?(SimpleCov)
|
||||
KnapsackPro::Hooks::Queue.before_queue do
|
||||
SimpleCov.command_name("rspec_ci_node_#{KnapsackPro::Config::Env.ci_node_index}")
|
||||
end
|
||||
end
|
||||
|
||||
# Allow connections to selenium whilst raising errors when connecting to external sites
|
||||
require 'webmock/rspec'
|
||||
WebMock.enable!
|
||||
WebMock.disable_net_connect!(
|
||||
allow_localhost: true,
|
||||
allow: ['chromedriver.storage.googleapis.com']
|
||||
)
|
||||
|
||||
# Requires supporting ruby files with custom matchers and macros, etc,
|
||||
# in spec/support/ and its subdirectories.
|
||||
Rails.root.glob("spec/support/**/*.rb").sort.each { |f| require f }
|
||||
|
||||
Capybara.server = :puma, { Silent: true }
|
||||
Capybara.disable_animation = true
|
||||
|
||||
Capybara.configure do |config|
|
||||
config.match = :prefer_exact
|
||||
config.ignore_hidden_elements = true
|
||||
end
|
||||
|
||||
FactoryBot.use_parent_strategy = false
|
||||
FactoryBot::SyntaxRunner.include FileHelper
|
||||
|
||||
# raise I18n exception handler
|
||||
I18n.exception_handler = proc do |exception, *_|
|
||||
raise exception.to_exception
|
||||
end
|
||||
|
||||
# Disable timestamp check for test environment
|
||||
InvisibleCaptcha.timestamp_enabled = false
|
||||
|
||||
InvisibleCaptcha.spinner_enabled = false
|
||||
|
||||
RSpec.configure do |config|
|
||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
||||
# examples within a transaction, remove the following line or assign false
|
||||
# instead of true.
|
||||
#
|
||||
# Setting this to true keeps the database clean by rolling back any changes.
|
||||
config.use_transactional_fixtures = true
|
||||
|
||||
# Some tests don't work within a transaction. Then we use DatabaseCleaner.
|
||||
config.before(:each, concurrency: true) do
|
||||
config.use_transactional_fixtures = false
|
||||
DatabaseCleaner.strategy = :deletion, { except: ['spree_countries', 'spree_states'] }
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
config.append_after(:each, concurrency: true) do
|
||||
DatabaseCleaner.clean
|
||||
config.use_transactional_fixtures = true
|
||||
end
|
||||
|
||||
# If true, the base class of anonymous controllers will be inferred
|
||||
# automatically. This will be the default behavior in future versions of
|
||||
# rspec-rails.
|
||||
config.infer_base_class_for_anonymous_controllers = false
|
||||
|
||||
# Show retries in test output
|
||||
config.verbose_retry = true
|
||||
|
||||
# Force colored output, whether or not the output is a TTY
|
||||
config.color_mode = :on
|
||||
|
||||
# Force use of expect (over should)
|
||||
config.expect_with :rspec do |expectations|
|
||||
expectations.syntax = :expect
|
||||
|
||||
# This option will default to `true` in RSpec 4. It makes the `description`
|
||||
# and `failure_message` of custom matchers include text for helper methods
|
||||
# defined using `chain`, e.g.:
|
||||
# be_bigger_than(2).and_smaller_than(4).description
|
||||
# # => "be bigger than 2 and smaller than 4"
|
||||
# ...rather than:
|
||||
# # => "be bigger than 2"
|
||||
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
||||
end
|
||||
|
||||
# rspec-mocks config goes here. You can use an alternate test double
|
||||
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
||||
config.mock_with :rspec do |mocks|
|
||||
# We use too many mocks at the moment. Activating the following
|
||||
# feature fails a lot of specs. We should clean it up over time.
|
||||
#
|
||||
# Prevents you from mocking or stubbing a method that does not exist on
|
||||
# a real object. This is generally recommended, and will default to
|
||||
# `true` in RSpec 4.
|
||||
# mocks.verify_partial_doubles = true
|
||||
end
|
||||
|
||||
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will
|
||||
# have no way to turn it off -- the option exists only for backwards
|
||||
# compatibility in RSpec 3). It causes shared context metadata to be
|
||||
# inherited by the metadata hash of host groups and examples, rather than
|
||||
# triggering implicit auto-inclusion in groups with matching metadata.
|
||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
||||
|
||||
# Limits the available syntax to the non-monkey patched syntax that is
|
||||
# recommended. For more details, see:
|
||||
# https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
|
||||
config.disable_monkey_patching!
|
||||
|
||||
# Many RSpec users commonly either run the entire suite or an individual
|
||||
# file, and it's useful to allow more verbose output when running an
|
||||
# individual spec file.
|
||||
if config.files_to_run.one?
|
||||
# Use the documentation formatter for detailed output,
|
||||
# unless a formatter has already been configured
|
||||
# (e.g. via a command-line flag).
|
||||
config.default_formatter = "doc"
|
||||
end
|
||||
|
||||
config.define_derived_metadata(file_path: %r{/spec/lib/tasks/}) do |metadata|
|
||||
metadata[:type] = :rake
|
||||
end
|
||||
|
||||
# Reset locale for all specs.
|
||||
config.around(:each) do |example|
|
||||
locale = ENV.fetch('LOCALE', 'en_TST')
|
||||
I18n.with_locale(locale) { example.run }
|
||||
end
|
||||
|
||||
# Reset all feature toggles to prevent leaking.
|
||||
config.before(:each) do
|
||||
Flipper.features.each(&:remove)
|
||||
OpenFoodNetwork::FeatureToggle.setup!
|
||||
end
|
||||
|
||||
config.before(:each, :feature) do |example|
|
||||
feature = example.metadata[:feature].to_s
|
||||
|
||||
unless OpenFoodNetwork::FeatureToggle::CURRENT_FEATURES.key?(feature)
|
||||
raise "Unkown feature: #{feature}"
|
||||
end
|
||||
|
||||
Flipper.enable(feature)
|
||||
end
|
||||
|
||||
# Enable caching in any specs tagged with `caching: true`.
|
||||
config.around(:each, :caching) do |example|
|
||||
caching = ActionController::Base.perform_caching
|
||||
ActionController::Base.perform_caching = example.metadata[:caching]
|
||||
example.run
|
||||
ActionController::Base.perform_caching = caching
|
||||
end
|
||||
|
||||
# Show javascript errors in test output with `js_debug: true`
|
||||
config.after(:each, :js_debug) do
|
||||
errors = page.driver.browser.manage.logs.get(:browser)
|
||||
if errors.present?
|
||||
message = errors.map(&:message).join("\n")
|
||||
puts message
|
||||
end
|
||||
end
|
||||
|
||||
# Appends Stripe gem version to VCR cassette directory with ':stripe_version' flag
|
||||
#
|
||||
# When the Stripe gem is updated, we should re-record these cassettes:
|
||||
#
|
||||
# ./script/test-stripe-live
|
||||
#
|
||||
config.around(:each, :stripe_version) do |example|
|
||||
stripe_version = "Stripe-v#{Stripe::VERSION}"
|
||||
cassette_library_dir, default_cassette_options = nil, nil
|
||||
|
||||
VCR.configure do |vcr_config|
|
||||
cassette_library_dir = vcr_config.cassette_library_dir
|
||||
default_cassette_options = vcr_config.default_cassette_options
|
||||
vcr_config.cassette_library_dir += "/#{stripe_version}"
|
||||
vcr_config.default_cassette_options = { record: :none } if ENV["CI"]
|
||||
end
|
||||
|
||||
example.run
|
||||
|
||||
VCR.configure do |vcr_config|
|
||||
vcr_config.cassette_library_dir = cassette_library_dir
|
||||
vcr_config.default_cassette_options = default_cassette_options
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure we start with consistent config settings
|
||||
config.before(:each) do
|
||||
reset_spree_preferences do |spree_config|
|
||||
# These are all settings that differ from Spree's defaults
|
||||
spree_config.shipping_instructions = true
|
||||
end
|
||||
CurrentConfig.clear_all
|
||||
end
|
||||
|
||||
# Don't validate our invalid test data with expensive network requests.
|
||||
config.before(:each) do
|
||||
allow_any_instance_of(ValidEmail2::Address).to receive_messages(
|
||||
valid_mx?: true,
|
||||
valid_strict_mx?: true,
|
||||
mx_server_is_in?: false
|
||||
)
|
||||
end
|
||||
|
||||
# Webmock raises errors that inherit directly from Exception (not StandardError).
|
||||
# The messages contain useful information for debugging stubbed requests to external
|
||||
# services (in tests), but they normally don't appear in the test output.
|
||||
config.before(:all) do
|
||||
ApplicationController.class_eval do
|
||||
rescue_from WebMock::NetConnectNotAllowedError, with: :handle_webmock_error
|
||||
|
||||
def handle_webmock_error(exception)
|
||||
raise exception.message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
config.infer_spec_type_from_file_location!
|
||||
|
||||
# You can use `rspec -n` to run only failed specs.
|
||||
config.example_status_persistence_file_path = "tmp/rspec-status.txt"
|
||||
|
||||
config.include_context "rake", type: :rake
|
||||
|
||||
# Helpers
|
||||
config.include FactoryBot::Syntax::Methods
|
||||
config.include JsonSpec::Helpers
|
||||
|
||||
config.include Rails.application.routes.url_helpers
|
||||
config.include Spree::UrlHelpers
|
||||
config.include Spree::MoneyHelper
|
||||
config.include Spree::PaymentHelper
|
||||
config.include PreferencesHelper
|
||||
config.include OpenFoodNetwork::FiltersHelper
|
||||
config.include OpenFoodNetwork::EnterpriseGroupsHelper
|
||||
config.include OpenFoodNetwork::HtmlHelper
|
||||
config.include ActiveSupport::Testing::TimeHelpers
|
||||
config.include ActionView::Helpers::DateHelper
|
||||
config.include OpenFoodNetwork::PerformanceHelper
|
||||
config.include ActiveJob::TestHelper
|
||||
config.include ReportsHelper
|
||||
config.include TomSelectHelper, type: :system
|
||||
|
||||
config.include ViewComponent::TestHelpers, type: :component
|
||||
|
||||
config.include ControllerRequestsHelper, type: :controller
|
||||
config.include Devise::Test::ControllerHelpers, type: :controller
|
||||
config.include OpenFoodNetwork::ApiHelper, type: :controller
|
||||
config.include OpenFoodNetwork::ControllerHelper, type: :controller
|
||||
|
||||
config.include Devise::Test::IntegrationHelpers, type: :request
|
||||
|
||||
config.include Features::DatepickerHelper, type: :system
|
||||
config.include Features::TrixEditorHelper, type: :system
|
||||
config.include DownloadsHelper, type: :system
|
||||
config.include ReportsHelper, type: :system
|
||||
config.include ProductsHelper, type: :system
|
||||
end
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe AdminTooltipComponent, type: :component do
|
||||
it "displays the tooltip link" do
|
||||
render_inline(described_class.new(text: "Tooltip description", link_text: "Hover here"))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe DistributorTitleComponent, type: :component do
|
||||
it "displays distributor title with its name" do
|
||||
render_inline(described_class.new(name: "Freddy's Farm Shop"))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe ExampleComponent, type: :component do
|
||||
it "displays the h1 with the given parameter" do
|
||||
render_inline(described_class.new(title: "Hello"))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe ModalComponent, type: :component do
|
||||
it "renders default 'data-action' and 'data-controller'" do
|
||||
render_inline(described_class.new(id: "test-id"))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe VerticalEllipsisMenuComponent, type: :component do
|
||||
it "displays the included links" do
|
||||
content = "<a href>Edit</a>"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe FeatureToggleConstraint do
|
||||
subject { described_class.new("baking") }
|
||||
let(:request) { double(env:) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::BulkLineItemsController do
|
||||
describe '#index' do
|
||||
render_views
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::ColumnPreferencesController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::CustomersController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::EnterpriseFeesController do
|
||||
before do
|
||||
allow(controller).to receive_messages spree_current_user: super_admin
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: false
|
||||
|
||||
require 'spec_helper'
|
||||
require 'open_food_network/order_cycle_permissions'
|
||||
|
||||
RSpec.describe Admin::EnterprisesController do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::InventoryItemsController do
|
||||
describe "create" do
|
||||
context "json" do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::InvoiceSettingsController do
|
||||
describe "#update" do
|
||||
let(:params) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::MatomoSettingsController do
|
||||
describe "#update" do
|
||||
let(:params) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::OrderCyclesController do
|
||||
let!(:distributor_owner) { create(:user) }
|
||||
let(:datetime_confirmation_attrs) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::ProductImportController do
|
||||
describe "#import" do
|
||||
context "when importing into inventory with inventory disabled" do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::ProxyOrdersController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::ReportsController do
|
||||
# Given two distributors and two suppliers
|
||||
let(:bill_address) { create(:address) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::SchedulesController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::StripeAccountsController do
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::StripeConnectSettingsController do
|
||||
let(:user) { create(:user) }
|
||||
let(:admin) { create(:admin_user) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::SubscriptionLineItemsController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::SubscriptionsController do
|
||||
include AuthenticationHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::TagRulesController do
|
||||
let(:format) { :turbo_stream }
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::TermsOfServiceFilesController do
|
||||
context "a non-admin user" do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Admin::VariantOverridesController do
|
||||
describe "index" do
|
||||
context "not logged in" do
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Api::V0::BaseController do
|
||||
render_views
|
||||
controller(Api::V0::BaseController) do
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user