mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-12 18:36:49 +00:00
Compare commits
130 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bf2dad343 | ||
|
|
05b3417f77 | ||
|
|
403aa6ac6f | ||
|
|
fbad3ee9f4 | ||
|
|
ddb8b2d08f | ||
|
|
42c9ee033a | ||
|
|
524634b4ea | ||
|
|
0b97171bb0 | ||
|
|
b0c7e29b0d | ||
|
|
3d7799df19 | ||
|
|
5f02d88a86 | ||
|
|
bdae8e6478 | ||
|
|
053ef05baf | ||
|
|
7fcb31d563 | ||
|
|
31a7374808 | ||
|
|
e5ce06ae39 | ||
|
|
5f64204d51 | ||
|
|
94b75540e4 | ||
|
|
6e489d7770 | ||
|
|
81b1169e77 | ||
|
|
4b558b4820 | ||
|
|
e224b8f63b | ||
|
|
80bb0606b4 | ||
|
|
499fcc791e | ||
|
|
30dae3c3ea | ||
|
|
af247c32a3 | ||
|
|
6f9dcf7e27 | ||
|
|
2d064bab64 | ||
|
|
b69eb9bdff | ||
|
|
f79c1879bd | ||
|
|
646d538a3d | ||
|
|
90288b8cbf | ||
|
|
c821b0a285 | ||
|
|
b95d798a27 | ||
|
|
e1e4aeac1f | ||
|
|
c7ae47053e | ||
|
|
5892ae1800 | ||
|
|
c37376d67e | ||
|
|
74368f939b | ||
|
|
cb02cd39fe | ||
|
|
49ec5b2089 | ||
|
|
92ef5fe3d5 | ||
|
|
ae477b7e52 | ||
|
|
0e191e5fca | ||
|
|
64f9ea6fc0 | ||
|
|
058c6749da | ||
|
|
2d15ec4458 | ||
|
|
56eaa8bb98 | ||
|
|
1e1f1e1e1b | ||
|
|
1d2115766a | ||
|
|
6814ef43f4 | ||
|
|
c9e8294561 | ||
|
|
82d0e1bf68 | ||
|
|
b16e541a81 | ||
|
|
c12d494de3 | ||
|
|
9be27842e1 | ||
|
|
2a7754edbf | ||
|
|
cfeafbfc51 | ||
|
|
1f8a9f9c76 | ||
|
|
b1893942ac | ||
|
|
ad59ed4d40 | ||
|
|
8491a167ed | ||
|
|
05b00f16ad | ||
|
|
78fdaa68c8 | ||
|
|
59277292fb | ||
|
|
e8813833fa | ||
|
|
354a7ab687 | ||
|
|
a5a1ee9bd9 | ||
|
|
ad3f78ef69 | ||
|
|
e02497b163 | ||
|
|
7d2d94398f | ||
|
|
0ecf004ff2 | ||
|
|
444f448207 | ||
|
|
d9381b23d7 | ||
|
|
6a9a2884d6 | ||
|
|
70edd4b898 | ||
|
|
b57a2befd9 | ||
|
|
fef9a78198 | ||
|
|
dd86736170 | ||
|
|
0d8c7ef118 | ||
|
|
20730b8768 | ||
|
|
ad7c69189b | ||
|
|
a5f44cb9b2 | ||
|
|
97d21d8cbe | ||
|
|
7afdd13b64 | ||
|
|
54c446f0a3 | ||
|
|
4454c90575 | ||
|
|
dd3a61acdf | ||
|
|
6d8ddd1eda | ||
|
|
b8e8ab15d1 | ||
|
|
bf1d2f3620 | ||
|
|
43026ddc6a | ||
|
|
18b83d2423 | ||
|
|
3a72aefc1c | ||
|
|
e855ea0dbd | ||
|
|
1eba950e19 | ||
|
|
9cd04c087e | ||
|
|
459d25e533 | ||
|
|
b06e562425 | ||
|
|
2936cfebca | ||
|
|
b8ad428b5d | ||
|
|
ca34d24847 | ||
|
|
6e581fce75 | ||
|
|
66041061fb | ||
|
|
e54c27c900 | ||
|
|
b3d3d6bf06 | ||
|
|
5876c52318 | ||
|
|
842f4ae40e | ||
|
|
342ef4e9eb | ||
|
|
210201514e | ||
|
|
2d3f18a71b | ||
|
|
9d284b7110 | ||
|
|
994f1ca6c6 | ||
|
|
f65e4797cf | ||
|
|
52aeec5ac4 | ||
|
|
7032b3f463 | ||
|
|
c26686b430 | ||
|
|
60c8f4ee20 | ||
|
|
25f396c126 | ||
|
|
0166abcd2a | ||
|
|
4cd0071dd4 | ||
|
|
1ec570375f | ||
|
|
75c33b29d5 | ||
|
|
3750898c44 | ||
|
|
d34f8900d7 | ||
|
|
910ded1a8c | ||
|
|
2555a9e710 | ||
|
|
f532c4712e | ||
|
|
addf36a304 | ||
|
|
6a912b7d8c |
14
.simplecov
14
.simplecov
@@ -2,13 +2,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
SimpleCov.start 'rails' do
|
||||
# The rails profile contains some filters already:
|
||||
#
|
||||
# - "/test/"
|
||||
# - "/features/"
|
||||
# - "/spec/"
|
||||
# - "/autotest/"
|
||||
# - /^\/config\//
|
||||
# - /^\/db\//
|
||||
add_filter '/bin/'
|
||||
add_filter '/config/'
|
||||
add_filter '/config/' # to include engine config
|
||||
add_filter '/script'
|
||||
add_filter '/db'
|
||||
|
||||
# We haven't managed to make simplecov recognise rake coverage accurately.
|
||||
add_filter '/lib/tasks/'
|
||||
|
||||
formatter SimpleCov::Formatter::SimpleFormatter
|
||||
end
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#!/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
-c master
|
||||
--compare master
|
||||
|
||||
# This shouldn't be needed in undercover > 0.7.4
|
||||
#
|
||||
# * https://github.com/grodowski/undercover/issues/233
|
||||
--exclude-files "bin/*,db/*,config/*,spec/*,engines/*/config/*,engines/*/spec/*"
|
||||
|
||||
@@ -2,7 +2,9 @@ FROM ruby:3.1.4-alpine3.19 AS base
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Europe/London \
|
||||
RAILS_ROOT=/usr/src/app
|
||||
RAILS_ROOT=/usr/src/app \
|
||||
BUNDLE_PATH=/bundles \
|
||||
BUNDLE_APP_CONFIG=/bundles
|
||||
RUN apk --no-cache upgrade && \
|
||||
apk add --no-cache tzdata postgresql-client imagemagick imagemagick-jpeg && \
|
||||
apk add --no-cache --virtual wkhtmltopdf
|
||||
@@ -14,7 +16,7 @@ FROM base AS development-base
|
||||
RUN apk add --no-cache --virtual .build-deps \
|
||||
build-base postgresql-dev git nodejs yarn && \
|
||||
apk add --no-cache --virtual .dev-utils \
|
||||
bash curl less vim chromium-chromedriver zlib-dev openssl-dev \
|
||||
bash curl less vim chromium-chromedriver zlib-dev openssl-dev cmake\
|
||||
readline-dev yaml-dev sqlite-dev libxml2-dev libxslt-dev libffi-dev vips-dev && \
|
||||
curl -o /usr/local/bin/wait-for-it https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh && \
|
||||
chmod +x /usr/local/bin/wait-for-it
|
||||
|
||||
@@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y \
|
||||
libjemalloc-dev \
|
||||
libssl-dev \
|
||||
ca-certificates \
|
||||
gnupg
|
||||
gnupg \
|
||||
cmake
|
||||
|
||||
# Setup ENV variables
|
||||
ENV PATH /usr/local/src/rbenv/shims:/usr/local/src/rbenv/bin:/usr/local/src/nodenv/shims:/usr/local/src/nodenv/bin:$PATH
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -152,6 +152,7 @@ end
|
||||
group :test, :development do
|
||||
gem 'bullet'
|
||||
gem 'capybara'
|
||||
gem 'capybara-shadowdom'
|
||||
gem 'cuprite'
|
||||
gem 'database_cleaner', require: false
|
||||
gem 'debug', '>= 1.0.0'
|
||||
@@ -166,7 +167,6 @@ group :test, :development do
|
||||
gem 'rswag'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'stimulus_reflex_testing', github: "podia/stimulus_reflex_testing", branch: :main
|
||||
gem 'timecop'
|
||||
end
|
||||
|
||||
group :test do
|
||||
|
||||
166
Gemfile.lock
166
Gemfile.lock
@@ -48,36 +48,36 @@ PATH
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
Ascii85 (1.1.0)
|
||||
actioncable (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
Ascii85 (2.0.1)
|
||||
actioncable (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
zeitwerk (~> 2.6)
|
||||
actionmailbox (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
activejob (= 7.1.5.1)
|
||||
activerecord (= 7.1.5.1)
|
||||
activestorage (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
actionmailbox (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
actionview (= 7.1.5.1)
|
||||
activejob (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
actionmailer (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.2)
|
||||
actionpack (7.1.5.1)
|
||||
actionview (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
actionpack (7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
nokogiri (>= 1.8.5)
|
||||
racc
|
||||
rack (>= 2.2.4)
|
||||
@@ -87,15 +87,15 @@ GEM
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
actionpack-action_caching (1.2.2)
|
||||
actionpack (>= 4.0.0)
|
||||
actiontext (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
activerecord (= 7.1.5.1)
|
||||
activestorage (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
actiontext (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
actionview (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.11)
|
||||
rails-dom-testing (~> 2.2)
|
||||
@@ -107,8 +107,8 @@ GEM
|
||||
activemodel (>= 5.2.0)
|
||||
activestorage (>= 5.2.0)
|
||||
activesupport (>= 5.2.0)
|
||||
activejob (7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
activejob (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
globalid (>= 0.3.6)
|
||||
activemerchant (1.133.0)
|
||||
activesupport (>= 4.2)
|
||||
@@ -116,11 +116,11 @@ GEM
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
rexml (~> 3.2.5)
|
||||
activemodel (7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
activerecord (7.1.5.1)
|
||||
activemodel (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
activemodel (7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
activerecord (7.1.5.2)
|
||||
activemodel (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
timeout (>= 0.4.0)
|
||||
activerecord-import (1.6.0)
|
||||
activerecord (>= 4.2)
|
||||
@@ -133,13 +133,13 @@ GEM
|
||||
multi_json (~> 1.11, >= 1.11.2)
|
||||
rack (>= 2.0.8, < 4)
|
||||
railties (>= 6.1)
|
||||
activestorage (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
activejob (= 7.1.5.1)
|
||||
activerecord (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
activestorage (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
marcel (~> 1.0)
|
||||
activesupport (7.1.5.1)
|
||||
activesupport (7.1.5.2)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
bigdecimal
|
||||
@@ -189,7 +189,7 @@ GEM
|
||||
aws-sigv4 (~> 1.8)
|
||||
aws-sigv4 (1.8.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
base64 (0.2.0)
|
||||
base64 (0.3.0)
|
||||
bcp47_spec (0.2.1)
|
||||
bcrypt (3.1.20)
|
||||
benchmark (0.4.1)
|
||||
@@ -201,7 +201,7 @@ GEM
|
||||
bugsnag (6.26.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
builder (3.2.4)
|
||||
bullet (7.1.6)
|
||||
bullet (8.0.8)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.11)
|
||||
cable_ready (5.0.6)
|
||||
@@ -221,12 +221,14 @@ GEM
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
capybara-shadowdom (0.3.0)
|
||||
capybara
|
||||
caxlsx (3.3.0)
|
||||
htmlentities (~> 4.3, >= 4.3.4)
|
||||
marcel (~> 1.0)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
rubyzip (>= 1.3.0, < 3)
|
||||
cgi (0.3.6)
|
||||
cgi (0.3.7)
|
||||
childprocess (5.0.0)
|
||||
choice (0.2.0)
|
||||
chronic (0.10.2)
|
||||
@@ -241,8 +243,8 @@ GEM
|
||||
combine_pdf (1.0.26)
|
||||
matrix
|
||||
ruby-rc4 (>= 0.1.5)
|
||||
concurrent-ruby (1.3.1)
|
||||
connection_pool (2.4.1)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.3)
|
||||
cookiejar (0.3.4)
|
||||
crack (1.0.0)
|
||||
bigdecimal
|
||||
@@ -262,7 +264,7 @@ GEM
|
||||
database_cleaner-core (2.0.1)
|
||||
datafoodconsortium-connector (1.1.0)
|
||||
virtual_assembly-semantizer (~> 1.0, >= 1.0.5)
|
||||
date (3.3.4)
|
||||
date (3.4.1)
|
||||
debug (1.9.2)
|
||||
irb (~> 1.10)
|
||||
reline (>= 0.3.8)
|
||||
@@ -298,7 +300,7 @@ GEM
|
||||
email_validator (2.2.4)
|
||||
activemodel
|
||||
erubi (1.12.0)
|
||||
et-orbi (1.2.7)
|
||||
et-orbi (1.3.0)
|
||||
tzinfo
|
||||
eventmachine (1.2.7)
|
||||
eventmachine_httpserver (0.2.1)
|
||||
@@ -351,8 +353,8 @@ GEM
|
||||
nokogiri (>= 1.5.11, < 2.0.0)
|
||||
foreman (0.88.1)
|
||||
formatador (0.2.5)
|
||||
fugit (1.8.1)
|
||||
et-orbi (~> 1, >= 1.2.7)
|
||||
fugit (1.11.1)
|
||||
et-orbi (~> 1, >= 1.2.11)
|
||||
raabro (~> 1.4)
|
||||
fuubar (2.5.1)
|
||||
rspec-core (~> 3.0)
|
||||
@@ -450,7 +452,7 @@ GEM
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
logger (1.7.0)
|
||||
loofah (2.22.0)
|
||||
loofah (2.24.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.12.0)
|
||||
mail (2.8.1)
|
||||
@@ -470,7 +472,7 @@ GEM
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.23.1)
|
||||
minitest (5.25.5)
|
||||
monetize (1.13.0)
|
||||
money (~> 6.12)
|
||||
money (6.16.0)
|
||||
@@ -481,7 +483,7 @@ GEM
|
||||
mutex_m (0.3.0)
|
||||
net-http (0.4.1)
|
||||
uri
|
||||
net-imap (0.4.10)
|
||||
net-imap (0.4.20)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
@@ -492,7 +494,7 @@ GEM
|
||||
net-protocol
|
||||
newrelic_rpm (9.9.0)
|
||||
nio4r (2.7.1)
|
||||
nokogiri (1.16.5)
|
||||
nokogiri (1.18.9)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nokogiri-html5-inference (0.3.0)
|
||||
@@ -544,9 +546,9 @@ GEM
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.117.2)
|
||||
paypal-sdk-core (~> 0.3.0)
|
||||
pdf-reader (2.12.0)
|
||||
Ascii85 (~> 1.0)
|
||||
afm (~> 0.2.1)
|
||||
pdf-reader (2.15.0)
|
||||
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
|
||||
afm (>= 0.2.1, < 2)
|
||||
hashery (~> 2.0)
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
@@ -573,7 +575,7 @@ GEM
|
||||
railties (>= 4.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (2.2.11)
|
||||
rack (2.2.14)
|
||||
rack-mini-profiler (2.3.4)
|
||||
rack (>= 1.2.0)
|
||||
rack-oauth2 (2.2.1)
|
||||
@@ -597,20 +599,20 @@ GEM
|
||||
rackup (1.0.1)
|
||||
rack (< 3)
|
||||
webrick
|
||||
rails (7.1.5.1)
|
||||
actioncable (= 7.1.5.1)
|
||||
actionmailbox (= 7.1.5.1)
|
||||
actionmailer (= 7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
actiontext (= 7.1.5.1)
|
||||
actionview (= 7.1.5.1)
|
||||
activejob (= 7.1.5.1)
|
||||
activemodel (= 7.1.5.1)
|
||||
activerecord (= 7.1.5.1)
|
||||
activestorage (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
rails (7.1.5.2)
|
||||
actioncable (= 7.1.5.2)
|
||||
actionmailbox (= 7.1.5.2)
|
||||
actionmailer (= 7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
actiontext (= 7.1.5.2)
|
||||
actionview (= 7.1.5.2)
|
||||
activejob (= 7.1.5.2)
|
||||
activemodel (= 7.1.5.2)
|
||||
activerecord (= 7.1.5.2)
|
||||
activestorage (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.1.5.1)
|
||||
railties (= 7.1.5.2)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
@@ -624,16 +626,16 @@ GEM
|
||||
activesupport (>= 4.2)
|
||||
choice (~> 0.2.0)
|
||||
ruby-graphviz (~> 1.2)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
rails-html-sanitizer (1.6.1)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||
rails-i18n (7.0.9)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
rails_safe_tasks (1.0.0)
|
||||
railties (7.1.5.1)
|
||||
actionpack (= 7.1.5.1)
|
||||
activesupport (= 7.1.5.1)
|
||||
railties (7.1.5.2)
|
||||
actionpack (= 7.1.5.2)
|
||||
activesupport (= 7.1.5.2)
|
||||
irb
|
||||
rackup (>= 1.0.0)
|
||||
rake (>= 12.2)
|
||||
@@ -837,12 +839,12 @@ GEM
|
||||
temple (0.8.2)
|
||||
terminal-table (4.0.0)
|
||||
unicode-display_width (>= 1.1.1, < 4)
|
||||
thor (1.3.1)
|
||||
thor (1.4.0)
|
||||
thread-local (1.1.0)
|
||||
tilt (2.3.0)
|
||||
timecop (0.9.8)
|
||||
timeout (0.4.1)
|
||||
ttfunk (1.7.0)
|
||||
timeout (0.4.3)
|
||||
ttfunk (1.8.0)
|
||||
bigdecimal (~> 3.1)
|
||||
turbo-rails (2.0.5)
|
||||
actionpack (>= 6.0.0)
|
||||
activejob (>= 6.0.0)
|
||||
@@ -860,8 +862,8 @@ GEM
|
||||
simplecov
|
||||
simplecov_json_formatter
|
||||
unicode-display_width (2.5.0)
|
||||
uniform_notifier (1.16.0)
|
||||
uri (0.13.0)
|
||||
uniform_notifier (1.17.0)
|
||||
uri (0.13.2)
|
||||
valid_email2 (5.2.3)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
@@ -901,7 +903,7 @@ GEM
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.1)
|
||||
webrick (1.8.2)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
@@ -909,7 +911,7 @@ GEM
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (2.8.1)
|
||||
activesupport
|
||||
wkhtmltopdf-binary (0.12.6.7)
|
||||
wkhtmltopdf-binary (0.12.6.10)
|
||||
xml-simple (1.1.8)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
@@ -941,6 +943,7 @@ DEPENDENCIES
|
||||
cable_ready
|
||||
cancancan (~> 1.15.0)
|
||||
capybara
|
||||
capybara-shadowdom
|
||||
catalog!
|
||||
coffee-rails (~> 5.0.0)
|
||||
combine_pdf
|
||||
@@ -1045,7 +1048,6 @@ DEPENDENCIES
|
||||
stimulus_reflex_testing!
|
||||
stringex (~> 2.8.5)
|
||||
stripe
|
||||
timecop
|
||||
turbo-rails
|
||||
turbo_power
|
||||
undercover
|
||||
|
||||
@@ -15,4 +15,4 @@ angular.module("admin.paymentMethods").controller "StripeController", ($scope, $
|
||||
permalink = shops.filter((shop) ->
|
||||
shop.id == $scope.paymentMethod.preferred_enterprise_id
|
||||
)[0].permalink
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods"
|
||||
"/admin/enterprises/#{permalink}/edit#/payment_methods_panel"
|
||||
|
||||
@@ -80,8 +80,6 @@ class CheckoutController < BaseController
|
||||
|
||||
@order.customer.touch :terms_and_conditions_accepted_at
|
||||
|
||||
return true if redirect_to_payment_gateway
|
||||
|
||||
# Redeem VINE voucher
|
||||
vine_voucher_redeemer = Vine::VoucherRedeemerService.new(order: @order)
|
||||
unless vine_voucher_redeemer.redeem
|
||||
@@ -94,6 +92,9 @@ class CheckoutController < BaseController
|
||||
return false
|
||||
# rubocop:enable Rails/DeprecatedActiveModelErrorsMethods
|
||||
end
|
||||
|
||||
return true if redirect_to_payment_gateway
|
||||
|
||||
@order.process_payments!
|
||||
@order.confirm!
|
||||
BackorderJob.check_stock(@order)
|
||||
|
||||
@@ -26,8 +26,8 @@ module Admin
|
||||
show_enterprise_fees = can?(:manage_enterprise_fees,
|
||||
enterprise) && (is_shop || enterprise.is_primary_producer)
|
||||
show_connected_apps = can?(:manage_connected_apps, enterprise) &&
|
||||
feature?(:connected_apps, spree_current_user, enterprise) &&
|
||||
Spree::Config.connected_apps_enabled.present?
|
||||
(connected_apps_enabled(enterprise).present? ||
|
||||
dfc_platforms_available?)
|
||||
show_inventory_settings = feature?(:inventory, spree_current_user.enterprises) && is_shop
|
||||
|
||||
show_options = {
|
||||
@@ -42,11 +42,19 @@ module Admin
|
||||
build_enterprise_side_menu_items(is_shop:, show_options:)
|
||||
end
|
||||
|
||||
def connected_apps_enabled
|
||||
def connected_apps_enabled(enterprise)
|
||||
return [] unless feature?(:connected_apps, spree_current_user, enterprise)
|
||||
|
||||
connected_apps_enabled = Spree::Config.connected_apps_enabled&.split(',') || []
|
||||
ConnectedApp::TYPES & connected_apps_enabled
|
||||
end
|
||||
|
||||
def dfc_platforms_available?
|
||||
DfcProvider::PlatformsController::PLATFORM_IDS.keys.any? do |id|
|
||||
feature?(id, spree_current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def enterprise_attachment_removal_modal_id
|
||||
attachment_removal_parameter # remove_logo|remove_promo_image|remove_white_label_logo
|
||||
end
|
||||
@@ -63,6 +71,11 @@ module Admin
|
||||
"#{enterprise_attachment_removal_panel}_panel"
|
||||
end
|
||||
|
||||
def enterprise_sells_options
|
||||
scope = "admin.enterprises.admin_index.sells_options"
|
||||
Enterprise::SELLS.map { |s| [I18n.t(s, scope:), s] }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_enterprise_side_menu_items(is_shop:, show_options: ) # rubocop:disable Metrics/MethodLength
|
||||
|
||||
@@ -9,6 +9,7 @@ class ApplicationRecord < ActiveRecord::Base
|
||||
include ArelHelpers::JoinAssociation
|
||||
|
||||
self.abstract_class = true
|
||||
self.include_root_in_json = true
|
||||
|
||||
def self.image_service
|
||||
ENV["S3_BUCKET"].present? ? :amazon_public : :local
|
||||
|
||||
15
app/models/dfc_permission.rb
Normal file
15
app/models/dfc_permission.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authorisations of a user allowing a platform to access to data.
|
||||
class DfcPermission < ApplicationRecord
|
||||
SCOPES = %w[
|
||||
ReadEnterprise ReadProducts ReadOrders
|
||||
WriteEnterprise WriteProducts WriteOrders
|
||||
].freeze
|
||||
|
||||
belongs_to :user, class_name: "Spree::User"
|
||||
belongs_to :enterprise
|
||||
|
||||
validates :grantee, presence: true
|
||||
validates :scope, presence: true, inclusion: { in: SCOPES }
|
||||
end
|
||||
@@ -75,6 +75,7 @@ class Enterprise < ApplicationRecord
|
||||
has_one :stripe_account, dependent: :destroy
|
||||
has_many :vouchers, dependent: :restrict_with_exception
|
||||
has_many :connected_apps, dependent: :destroy
|
||||
has_many :dfc_permissions, dependent: :destroy
|
||||
has_one :custom_tab, dependent: :destroy
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, to: :address
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
= enterprise_form.check_box :is_primary_producer
|
||||
= t('.producer')
|
||||
- if spree_current_user.admin?
|
||||
%td= enterprise_form.select :sells, Enterprise::SELLS, {}, class: 'select2 fullwidth'
|
||||
%td= enterprise_form.select :sells, enterprise_sells_options, {}, class: 'select2 fullwidth'
|
||||
%td= enterprise_form.check_box :visible, {}, 'public', 'hidden'
|
||||
- if spree_current_user.admin?
|
||||
%td= enterprise_form.select :owner_id, enterprise.users.map{ |e| [ e.email, e.id ] }, {}, class: "select2 fullwidth"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
- connected_apps_enabled.each do |type|
|
||||
- connected_apps_enabled(enterprise).each do |type|
|
||||
= render partial: "/admin/enterprises/form/connected_apps/#{type}",
|
||||
locals: { enterprise:, connected_app: enterprise.connected_apps.public_send(type).first }
|
||||
|
||||
= render partial: "/admin/enterprises/form/dfc_permissions" if dfc_platforms_available?
|
||||
|
||||
30
app/views/admin/enterprises/form/_dfc_permissions.html.haml
Normal file
30
app/views/admin/enterprises/form/_dfc_permissions.html.haml
Normal file
@@ -0,0 +1,30 @@
|
||||
%script{type: "module", src: "https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/index.js"}
|
||||
%script{type: "module"}
|
||||
:plain
|
||||
window.orbit = {
|
||||
client: {
|
||||
name: "Orbit",
|
||||
logo: "https://cdn.startinblox.com/logos/ACME.svg",
|
||||
},
|
||||
components: [],
|
||||
getRoute: (route) => route,
|
||||
getDefaultRoute: () => "",
|
||||
getComponent: () => undefined,
|
||||
getComponentFromRoute: () => undefined,
|
||||
Swal: () => {},
|
||||
defaultRoute: "",
|
||||
federations: {},
|
||||
componentSet: new Set(["routing", "menu", "menu-top", "autoLogin", "solid-permissioning"]),
|
||||
};
|
||||
|
||||
:plain
|
||||
<solid-permissioning
|
||||
data-src="#{DfcProvider::Engine.routes.url_helpers.enterprise_platforms_url(@enterprise.id)}"
|
||||
scopes-uri="https://cdn.startinblox.com/owl/dfc/taxonomies/scopes.jsonld"
|
||||
noRouter
|
||||
auto-lang
|
||||
lang="en"
|
||||
auth-token="#{form_authenticity_token}">
|
||||
</solid-permissioning>
|
||||
|
||||
%script{type: "module", src: "https://cdn.jsdelivr.net/npm/@startinblox/solid-data-permissioning@latest/dist/index.js"}
|
||||
@@ -1,20 +1,5 @@
|
||||
// import Flatpickr
|
||||
import Flatpickr from "stimulus-flatpickr";
|
||||
import { ar } from "flatpickr/dist/l10n/ar";
|
||||
import { cat } from "flatpickr/dist/l10n/cat";
|
||||
import { cy } from "flatpickr/dist/l10n/cy";
|
||||
import { de } from "flatpickr/dist/l10n/de";
|
||||
import { fi } from "flatpickr/dist/l10n/fi";
|
||||
import { fr } from "flatpickr/dist/l10n/fr";
|
||||
import { it } from "flatpickr/dist/l10n/it";
|
||||
import { nl } from "flatpickr/dist/l10n/nl";
|
||||
import { pl } from "flatpickr/dist/l10n/pl";
|
||||
import { pt } from "flatpickr/dist/l10n/pt";
|
||||
import { ru } from "flatpickr/dist/l10n/ru";
|
||||
import { sv } from "flatpickr/dist/l10n/sv";
|
||||
import { tr } from "flatpickr/dist/l10n/tr";
|
||||
import { en } from "flatpickr/dist/l10n/default.js";
|
||||
import { hu } from "flatpickr/dist/l10n/hu";
|
||||
import ShortcutButtonsPlugin from "shortcut-buttons-flatpickr";
|
||||
import labelPlugin from "flatpickr/dist/plugins/labelPlugin/labelPlugin";
|
||||
|
||||
@@ -24,28 +9,11 @@ export default class extends Flatpickr {
|
||||
*/
|
||||
static values = { enableTime: Boolean, mode: String, defaultDate: String };
|
||||
static targets = ["start", "end"];
|
||||
locales = {
|
||||
ar: ar,
|
||||
cat: cat,
|
||||
cy: cy,
|
||||
de: de,
|
||||
fi: fi,
|
||||
fr: fr,
|
||||
it: it,
|
||||
nl: nl,
|
||||
pl: pl,
|
||||
pt: pt,
|
||||
ru: ru,
|
||||
sv: sv,
|
||||
tr: tr,
|
||||
en: en,
|
||||
hu: hu,
|
||||
};
|
||||
|
||||
initialize() {
|
||||
const datetimepicker = this.enableTimeValue === true;
|
||||
const mode = this.modeValue === "range" ? "range" : "single";
|
||||
// sets your language (you can also set some global setting for all time pickers)
|
||||
// configure flatpickr options (locale set dynamically in connect())
|
||||
this.config = {
|
||||
altInput: true,
|
||||
altFormat: datetimepicker
|
||||
@@ -54,13 +22,18 @@ export default class extends Flatpickr {
|
||||
dateFormat: datetimepicker ? "Y-m-d H:i" : "Y-m-d",
|
||||
enableTime: datetimepicker,
|
||||
time_24hr: datetimepicker,
|
||||
locale: I18n.base_locale,
|
||||
plugins: this.plugins(mode, datetimepicker),
|
||||
mode,
|
||||
};
|
||||
}
|
||||
|
||||
connect() {
|
||||
async connect() {
|
||||
const locale = await this.importFlatpickrLocale(I18n.base_locale);
|
||||
this.config = {
|
||||
...this.config,
|
||||
locale,
|
||||
};
|
||||
|
||||
super.connect();
|
||||
window.addEventListener("flatpickr:change", this.onChangeEvent);
|
||||
window.addEventListener("flatpickr:clear", this.clear);
|
||||
@@ -164,4 +137,16 @@ export default class extends Flatpickr {
|
||||
this.fp.setDate(moment().add(1, "days").startOf("day").format());
|
||||
}
|
||||
}
|
||||
|
||||
async importFlatpickrLocale(localeCode) {
|
||||
// null tells flatpickr to fall back to its built-in english locale
|
||||
if (!localeCode || localeCode === "en") return null;
|
||||
|
||||
try {
|
||||
const localeModule = await import(`flatpickr/dist/l10n/${localeCode}.js`);
|
||||
return localeModule.default?.[localeCode] ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
83
compose.yaml
83
compose.yaml
@@ -5,20 +5,36 @@ services:
|
||||
environment:
|
||||
POSTGRES_PASSWORD: f00d
|
||||
POSTGRES_USER: ofn
|
||||
POSTGRES_DB: open_food_network_dev
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- 'postgres:/var/lib/postgresql/data'
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "PGPASSWORD=$$POSTGRES_PASSWORD pg_isready -q -h 127.0.0.1 -p 5432 -U $$POSTGRES_USER || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 10s
|
||||
retries: 10
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
|
||||
bundler:
|
||||
build: .
|
||||
# Runs once: installs gems into /bundles, writes a checksum sentinel, then exits
|
||||
command: >
|
||||
sh -lc 'bundle install --jobs 4 --retry 3 --quiet;
|
||||
sha256sum Gemfile.lock > /bundles/.Gemfile.lock.sha'
|
||||
volumes:
|
||||
- .:/usr/src/app
|
||||
- gems:/bundles
|
||||
restart: "no"
|
||||
|
||||
web:
|
||||
tty: true
|
||||
stdin_open: true
|
||||
build: .
|
||||
ports:
|
||||
- 3000:3000
|
||||
- 3035:3035
|
||||
volumes:
|
||||
- .:/usr/src/app
|
||||
- gems:/bundles
|
||||
@@ -26,20 +42,69 @@ services:
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_started
|
||||
webpack:
|
||||
condition: service_started
|
||||
environment:
|
||||
DOCKER: true
|
||||
DEV_CACHING: true
|
||||
OFN_DB_HOST: db
|
||||
OFN_REDIS_URL: redis://redis/
|
||||
OFN_REDIS_JOBS_URL: redis://redis
|
||||
OFN_REDIS_TEST_URL: redis://redis/3
|
||||
WEBPACKER_DEV_SERVER_HOST: webpack
|
||||
WEBPACKER_DEV_SERVER_PORT: 3035
|
||||
WEBPACKER_DEV_SERVER_PUBLIC: localhost:3035
|
||||
|
||||
command: >
|
||||
bash -c "rm -f tmp/pids/server.pid &&
|
||||
(bundle check || bundle install) &&
|
||||
bundle exec rake db:create &&
|
||||
yarn install &&
|
||||
bundle exec foreman start -f Procfile.docker"
|
||||
sh -lc 'rm -f tmp/pids/server.pid;
|
||||
until [ -f /bundles/.Gemfile.lock.sha ] && sha256sum -c /bundles/.Gemfile.lock.sha >/dev/null 2>&1; do sleep 0.5; done;
|
||||
bundle exec rails db:prepare &&
|
||||
yarn install &&
|
||||
exec bundle exec rails s -b 0.0.0.0 -p 3000'
|
||||
|
||||
sidekiq:
|
||||
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 bundle exec sidekiq'
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_started
|
||||
volumes:
|
||||
- .:/usr/src/app
|
||||
- gems:/bundles
|
||||
environment:
|
||||
DOCKER: true
|
||||
DEV_CACHING: true
|
||||
OFN_DB_HOST: db
|
||||
OFN_REDIS_URL: redis://redis/
|
||||
OFN_REDIS_JOBS_URL: redis://redis
|
||||
OFN_REDIS_TEST_URL: redis://redis/3
|
||||
|
||||
webpack:
|
||||
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'
|
||||
ports:
|
||||
- "3035:3035"
|
||||
volumes:
|
||||
- .:/usr/src/app
|
||||
- gems:/bundles
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://localhost:3035/webpack-dev-server >/dev/null || wget -qO- http://localhost:3035/sockjs-node/info >/dev/null"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
|
||||
environment:
|
||||
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
|
||||
volumes:
|
||||
gems:
|
||||
postgres:
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
require_relative 'boot'
|
||||
require_relative "boot"
|
||||
|
||||
require "rails"
|
||||
[
|
||||
"active_record/railtie",
|
||||
"active_storage/engine",
|
||||
"action_controller/railtie",
|
||||
"action_view/railtie",
|
||||
"action_mailer/railtie",
|
||||
"active_job/railtie",
|
||||
"action_cable/engine",
|
||||
# "action_mailbox/engine",
|
||||
# "action_text/engine",
|
||||
"rails/test_unit/railtie",
|
||||
"sprockets/railtie" # Disable this after migrating to Webpacker
|
||||
].each do |railtie|
|
||||
begin
|
||||
require railtie
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
# Pick the frameworks you want:
|
||||
require "active_model/railtie"
|
||||
require "active_job/railtie"
|
||||
require "active_record/railtie"
|
||||
require "active_storage/engine"
|
||||
require "action_controller/railtie"
|
||||
require "action_mailer/railtie"
|
||||
# require "action_mailbox/engine"
|
||||
# require "action_text/engine"
|
||||
require "action_view/railtie"
|
||||
require "action_cable/engine"
|
||||
require "rails/test_unit/railtie"
|
||||
require "sprockets/railtie" # Disable this after migrating to Webpacker
|
||||
|
||||
require_relative "../lib/open_food_network/i18n_config"
|
||||
require_relative '../lib/spree/core/environment'
|
||||
@@ -26,15 +21,34 @@ require_relative '../lib/spree/core/mail_interceptor'
|
||||
require_relative "../lib/i18n_digests"
|
||||
require_relative "../lib/git_utils"
|
||||
|
||||
if defined?(Bundler)
|
||||
# If you precompile assets before deploying to production, use this line
|
||||
Bundler.require(*Rails.groups(:assets => %w(development test)))
|
||||
# If you want your assets lazily compiled in production, use this line
|
||||
# Bundler.require(:default, :assets, Rails.env)
|
||||
end
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups(:assets => %w(development test)))
|
||||
|
||||
module Openfoodnetwork
|
||||
class Application < Rails::Application
|
||||
# Initialize configuration defaults for originally generated Rails version.
|
||||
config.load_defaults 6.1
|
||||
config.action_view.form_with_generates_remote_forms = false
|
||||
config.active_record.cache_versioning = false
|
||||
config.active_record.has_many_inversing = false
|
||||
config.active_record.yaml_column_permitted_classes = [BigDecimal, Symbol, Time,
|
||||
ActiveSupport::TimeWithZone,
|
||||
ActiveSupport::TimeZone]
|
||||
|
||||
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
||||
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
||||
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
||||
# config.autoload_lib(ignore: %w(assets tasks))
|
||||
|
||||
# Configuration for the application, engines, and railties goes here.
|
||||
#
|
||||
# These settings can be overridden in specific environments using the files
|
||||
# in config/environments, which are processed later.
|
||||
#
|
||||
config.time_zone = ENV["TIMEZONE"]
|
||||
# config.eager_load_paths << Rails.root.join("extras")
|
||||
|
||||
# Store a description of the current version
|
||||
config.x.git_version = GitUtils::git_version
|
||||
|
||||
@@ -71,16 +85,6 @@ module Openfoodnetwork
|
||||
end
|
||||
end
|
||||
|
||||
# filter sensitive information during logging
|
||||
initializer "spree.params.filter" do |app|
|
||||
app.config.filter_parameters += [
|
||||
:password,
|
||||
:password_confirmation,
|
||||
:number,
|
||||
:verification_value
|
||||
]
|
||||
end
|
||||
|
||||
initializer "load_spree_calculators" do |app|
|
||||
# Register Spree calculators
|
||||
Rails.application.reloader.to_prepare do
|
||||
@@ -161,10 +165,6 @@ module Openfoodnetwork
|
||||
# Activate observers that should always be running.
|
||||
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
config.time_zone = ENV["TIMEZONE"]
|
||||
|
||||
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
config.i18n.default_locale = OpenFoodNetwork::I18nConfig.default_locale
|
||||
@@ -184,38 +184,14 @@ module Openfoodnetwork
|
||||
|
||||
# Enable the asset pipeline
|
||||
config.assets.enabled = true
|
||||
|
||||
# Version of your assets, change this if you want to expire all your assets
|
||||
config.assets.version = '1.2'
|
||||
config.assets.initialize_on_precompile = true
|
||||
|
||||
# Unset X-Frame-Options header for embedded pages.
|
||||
config.action_dispatch.default_headers.except! "X-Frame-Options"
|
||||
|
||||
# css and js files other than application.* are not precompiled by default
|
||||
# Instead, they must be explicitly included below
|
||||
# http://stackoverflow.com/questions/8012434/what-is-the-purpose-of-config-assets-precompile
|
||||
config.assets.initialize_on_precompile = true
|
||||
config.assets.precompile += ['admin/*.js', 'admin/**/*.js', 'admin_minimal.js']
|
||||
config.assets.precompile += ['web/all.js']
|
||||
config.assets.precompile += ['darkswarm/all.js']
|
||||
config.assets.precompile += ['shared/*']
|
||||
config.assets.precompile += ['mail.scss']
|
||||
config.assets.precompile += ['*.jpg', '*.jpeg', '*.png', '*.gif' '*.svg']
|
||||
|
||||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = ENV.fetch("VERBOSE_QUERY_LOGS", false)
|
||||
|
||||
# Apply framework defaults. New recommended defaults are successively added with each Rails version and
|
||||
# include the defaults from previous versions. For more info see:
|
||||
# https://guides.rubyonrails.org/configuring.html#results-of-config-load-defaults
|
||||
config.load_defaults 6.1
|
||||
config.action_view.form_with_generates_remote_forms = false
|
||||
config.active_record.cache_versioning = false
|
||||
config.active_record.has_many_inversing = false
|
||||
config.active_record.yaml_column_permitted_classes = [BigDecimal, Symbol, Time,
|
||||
ActiveSupport::TimeWithZone,
|
||||
ActiveSupport::TimeZone]
|
||||
|
||||
config.active_support.escape_html_entities_in_json = true
|
||||
|
||||
config.active_job.queue_adapter = :sidekiq
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
require 'rubygems'
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
||||
|
||||
# Set up gems listed in the Gemfile.
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
|
||||
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
||||
require 'bootsnap/setup'
|
||||
require "bundler/setup" # Set up gems listed in the Gemfile.
|
||||
require "bootsnap/setup" # Speed up boot time by caching expensive operations.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Load the rails application
|
||||
require_relative 'application'
|
||||
# Load the Rails application.
|
||||
require_relative "application"
|
||||
|
||||
# Initialize the rails application
|
||||
Openfoodnetwork::Application.initialize!
|
||||
|
||||
ActiveRecord::Base.include_root_in_json = true
|
||||
# Initialize the Rails application.
|
||||
Rails.application.initialize!
|
||||
|
||||
@@ -1,40 +1,87 @@
|
||||
Openfoodnetwork::Application.configure do
|
||||
config.action_controller.default_url_options = {host: "localhost", port: 3000}
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
#
|
||||
require "active_support/core_ext/integer/time"
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# PROFILE switches several settings to a more "production-like" value
|
||||
# for profiling and benchmarking the application locally. All changes you
|
||||
# make to the app will require restart.
|
||||
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# In the development environment your application's code is reloaded any time
|
||||
# it changes. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = !!ENV["PROFILE"]
|
||||
|
||||
config.action_controller.default_url_options = {host: "localhost", port: 3000}
|
||||
# Do not eager load code on boot.
|
||||
config.eager_load = false
|
||||
|
||||
# Show full error reports.
|
||||
config.consider_all_requests_local = true
|
||||
|
||||
# Enable server timing
|
||||
config.server_timing = true
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
#
|
||||
# To override this, set the appropriate locale in .env[.*] file.
|
||||
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
|
||||
|
||||
config.log_level = ENV.fetch("DEV_LOG_LEVEL", :debug)
|
||||
|
||||
# Enable/disable caching. By default caching is disabled.
|
||||
# Run rails dev:cache to toggle caching.
|
||||
if Rails.root.join("tmp/caching-dev.txt").exist? || !ENV["PROFILE"] || !!ENV["DEV_CACHING"]
|
||||
config.action_controller.perform_caching = true
|
||||
config.action_controller.enable_fragment_cache_logging = true
|
||||
|
||||
# :file_store is used by default when no cache store is specifically configured.
|
||||
if !!ENV["PROFILE"] || !!ENV["DEV_CACHING"]
|
||||
config.cache_store = :redis_cache_store, {
|
||||
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6379/1"),
|
||||
expires_in: 90.minutes
|
||||
}
|
||||
config.public_file_server.headers = {
|
||||
"Cache-Control" => "public, max-age=#{2.days.to_i}"
|
||||
}
|
||||
else
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
config.cache_store = :null_store
|
||||
end
|
||||
|
||||
config.eager_load = false
|
||||
config.action_controller.default_url_options = {host: "localhost", port: 3000}
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = !!ENV["PROFILE"] || !!ENV["DEV_CACHING"]
|
||||
# Store uploaded files on the local file system (see config/storage.yml for options).
|
||||
# config.active_storage.service = :local
|
||||
|
||||
# Don't care if the mailer can't send
|
||||
# Don't care if the mailer can't send.
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Print deprecation notices to the Rails logger
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Show emails using Letter Opener
|
||||
config.action_mailer.delivery_method = :letter_opener
|
||||
config.action_mailer.default_url_options = { host: "localhost:3000" }
|
||||
|
||||
# Print deprecation notices to the Rails logger.
|
||||
config.active_support.deprecation = :log
|
||||
|
||||
# Only use best-standards-support built into browsers
|
||||
config.action_dispatch.best_standards_support = :builtin
|
||||
# Raise exceptions for disallowed deprecations.
|
||||
config.active_support.disallowed_deprecation = :raise
|
||||
|
||||
# Tell Active Support which deprecation messages to disallow.
|
||||
config.active_support.disallowed_deprecation_warnings = []
|
||||
|
||||
# Raise an error on page load if there are pending migrations.
|
||||
config.active_record.migration_error = :page_load
|
||||
|
||||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = true
|
||||
|
||||
# Highlight code that enqueued background job in logs.
|
||||
config.active_job.verbose_enqueue_logs = true
|
||||
|
||||
# Suppress logger output for asset requests.
|
||||
config.assets.quiet = true
|
||||
|
||||
# Do not compress assets
|
||||
config.assets.compress = false
|
||||
@@ -59,17 +106,17 @@ Openfoodnetwork::Application.configure do
|
||||
# $ bundle exec rake assets:clean
|
||||
config.assets.debug = !!ENV["DEBUG_ASSETS"]
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
#
|
||||
# To override this, set the appropriate locale in .env[.*] file.
|
||||
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
|
||||
# Raises error for missing translations.
|
||||
# config.i18n.raise_on_missing_translations = true
|
||||
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Show emails using Letter Opener
|
||||
config.action_mailer.delivery_method = :letter_opener
|
||||
config.action_mailer.default_url_options = { host: "localhost:3000" }
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||
|
||||
config.log_level = ENV.fetch("DEV_LOG_LEVEL", :debug)
|
||||
# Uncomment if you wish to allow Action Cable access from any origin.
|
||||
# config.action_cable.disable_request_forgery_protection = true
|
||||
|
||||
# Raise error when a before_action's only/except options reference missing actions
|
||||
# config.action_controller.raise_on_missing_callback_actions = true
|
||||
end
|
||||
|
||||
@@ -1,69 +1,113 @@
|
||||
Openfoodnetwork::Application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
require "active_support/core_ext/integer/time"
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# Code is not reloaded between requests.
|
||||
config.enable_reloading = false
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both threaded web servers
|
||||
# and those relying on copy on write to perform better.
|
||||
# Rake tasks automatically ignore this option for performance.
|
||||
config.eager_load = true
|
||||
|
||||
# Code is not reloaded between requests
|
||||
config.cache_classes = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.consider_all_requests_local = false
|
||||
# Full error reports are disabled and caching is turned on.
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this)
|
||||
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
|
||||
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
|
||||
# config.require_master_key = true
|
||||
|
||||
# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
|
||||
config.public_file_server.enabled = false
|
||||
|
||||
# Compress CSS using a preprocessor.
|
||||
# config.assets.css_compressor = :sass
|
||||
|
||||
# Do not fall back to assets pipeline if a precompiled asset is missed.
|
||||
config.assets.compile = false
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
# config.asset_host = "http://assets.example.com"
|
||||
|
||||
# Compress JavaScripts and CSS
|
||||
config.assets.compress = true
|
||||
|
||||
# Don't fallback to assets pipeline if a precompiled asset is missed
|
||||
config.assets.compile = false
|
||||
|
||||
# Generate digests for assets URLs
|
||||
config.assets.digest = true
|
||||
|
||||
# Defaults to Rails.root.join("public/assets")
|
||||
# config.assets.manifest = YOUR_PATH
|
||||
# Specifies the header that your server uses for sending files.
|
||||
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
|
||||
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
|
||||
|
||||
# Specifies the header that your server uses for sending files
|
||||
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
|
||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
||||
# Store uploaded files on the local file system (see config/storage.yml for options).
|
||||
# We set it in application.rb.
|
||||
# config.active_storage.service = :local
|
||||
|
||||
# Mount Action Cable outside main process or domain.
|
||||
# config.action_cable.mount_path = nil
|
||||
# config.action_cable.url = "wss://example.com/cable"
|
||||
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
|
||||
config.action_cable.url = "#{ENV['OFN_URL']}/cable"
|
||||
config.action_cable.allowed_request_origins = [/http:\/\/#{ENV['OFN_URL']}\/*/, /https:\/\/#{ENV['OFN_URL']}\/*/]
|
||||
|
||||
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
|
||||
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
|
||||
# config.assume_ssl = true
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
config.force_ssl = true
|
||||
|
||||
# Use https in email links
|
||||
config.action_mailer.default_url_options = { protocol: 'https' }
|
||||
# Log to STDOUT by default
|
||||
config.logger = ActiveSupport::Logger.new(STDOUT)
|
||||
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
|
||||
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
|
||||
|
||||
# Set log level (default is :debug in Rails 4)
|
||||
config.log_level = :info
|
||||
|
||||
# Configure logging:
|
||||
config.log_formatter = Logger::Formatter.new.tap { |f| f.datetime_format = "%Y-%m-%d %H:%M:%S" }
|
||||
# Prepend all log lines with the following tags.
|
||||
config.log_tags = [:request_id]
|
||||
|
||||
# Use a different cache store in production
|
||||
# "info" includes generic and useful information about system operation, but avoids logging too much
|
||||
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
|
||||
# want to log everything, set the level to "debug".
|
||||
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
|
||||
|
||||
# Use a different cache store in production.
|
||||
# config.cache_store = :mem_cache_store
|
||||
config.cache_store = :redis_cache_store, {
|
||||
url: ENV.fetch("OFN_REDIS_URL", "redis://localhost:6380/0"),
|
||||
reconnect_attempts: 1
|
||||
}
|
||||
|
||||
config.action_cable.url = "#{ENV['OFN_URL']}/cable"
|
||||
config.action_cable.allowed_request_origins = [/http:\/\/#{ENV['OFN_URL']}\/*/, /https:\/\/#{ENV['OFN_URL']}\/*/]
|
||||
# Use a real queuing backend for Active Job (and separate queues per environment).
|
||||
# config.active_job.queue_adapter = :resque
|
||||
# config.active_job.queue_name_prefix = "openfoodnetwork_production"
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
||||
# config.action_controller.asset_host = "http://assets.example.com"
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Disable delivery errors, bad email addresses will be ignored
|
||||
# Ignore bad email addresses and do not raise email delivery errors.
|
||||
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Enable threaded mode
|
||||
# config.threadsafe!
|
||||
# Use https in email links
|
||||
config.action_mailer.default_url_options = { protocol: 'https' }
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# the I18n.default_locale when a translation can not be found)
|
||||
# the I18n.default_locale when a translation cannot be found).
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Send deprecation notices to registered listeners
|
||||
config.active_support.deprecation = :notify
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
||||
# Enable DNS rebinding protection and other `Host` header attacks.
|
||||
# config.hosts = [
|
||||
# "example.com", # Allow requests from example.com
|
||||
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
||||
# ]
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
end
|
||||
|
||||
@@ -1,17 +1,38 @@
|
||||
Openfoodnetwork::Application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb
|
||||
require "active_support/core_ext/integer/time"
|
||||
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# While tests run files are not watched, reloading is not necessary.
|
||||
config.enable_reloading = false
|
||||
|
||||
# StimulusReflex requires caching to be enabled.
|
||||
config.cache_classes = false
|
||||
|
||||
# Eager loading loads your entire application. When running a single test locally,
|
||||
# this is usually not necessary, and can slow down your test suite. However, it's
|
||||
# recommended that you enable it in continuous integration systems to ensure eager
|
||||
# loading is working properly before deploying your code.
|
||||
# config.eager_load = ENV["CI"].present?
|
||||
config.eager_load = false
|
||||
|
||||
# Configure static asset server for tests with Cache-Control for performance
|
||||
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
|
||||
|
||||
# Configure public file server for tests with Cache-Control for performance.
|
||||
config.public_file_server.enabled = true
|
||||
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
|
||||
config.public_file_server.headers = {
|
||||
"Cache-Control" => "public, max-age=#{1.hour.to_i}"
|
||||
}
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
# config.cache_store = :null_store
|
||||
|
||||
# Separate cache stores when running in parallel
|
||||
config.cache_store = :redis_cache_store, {
|
||||
@@ -20,25 +41,61 @@ Openfoodnetwork::Application.configure do
|
||||
reconnect_attempts: 1
|
||||
}
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
# Render exception templates for rescuable exceptions and raise for other exceptions.
|
||||
config.action_dispatch.show_exceptions = :rescuable
|
||||
|
||||
# Raise exceptions instead of rendering exception templates
|
||||
config.action_dispatch.show_exceptions = false
|
||||
# Disable request forgery protection in test environment.
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
||||
# Disable request forgery protection in test environment
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
# Store uploaded files on the local file system in a temporary directory.
|
||||
# config.active_storage.service = :test
|
||||
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Tell Action Mailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
|
||||
# Tests should fail when translations are missing.
|
||||
config.i18n.raise_on_missing_translations = true
|
||||
# Print deprecation notices to the stderr.
|
||||
# config.active_support.deprecation = :stderr
|
||||
|
||||
config.time_zone = ENV.fetch("TIMEZONE", "UTC")
|
||||
# Raise exceptions for disallowed deprecations.
|
||||
config.active_support.disallowed_deprecation = :raise
|
||||
|
||||
# Tell Active Support which deprecation messages to disallow.
|
||||
config.active_support.disallowed_deprecation_warnings = []
|
||||
|
||||
# Fail tests on deprecated code unless it's a known case to solve.
|
||||
Rails.application.deprecators.behavior = ->(message, callstack, deprecator) do
|
||||
allowed_warnings = [
|
||||
# List strings here to allow matching deprecations.
|
||||
#
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
|
||||
"config.active_support.cache_format_version",
|
||||
|
||||
# `Rails.application.secrets` is deprecated in favor of `Rails.application.credentials` and will be removed in Rails 7.2
|
||||
"Rails.application.secrets",
|
||||
|
||||
"Passing the class as positional argument",
|
||||
|
||||
# Spree::Order model aliases `bill_address`, but `bill_address` is not an attribute. Starting in Rails 7.2, alias_attribute with non-attribute targets will raise. Use `alias_method :billing_address, :bill_address` or define the method manually. (called from initialize at app/models/spree/order.rb:188)
|
||||
"alias_attribute with non-attribute targets will raise",
|
||||
|
||||
# Spree::CreditCard model aliases `cc_type` and has a method called `cc_type=` defined. Starting in Rails 7.2 `brand=` will not be calling `cc_type=` anymore. You may want to additionally define `brand=` to preserve the current behavior.
|
||||
"model aliases",
|
||||
|
||||
# Setting action_dispatch.show_exceptions to true is deprecated. Set to :all instead.
|
||||
# spec/requests/errors_spec.rb
|
||||
"action_dispatch.show_exceptions",
|
||||
]
|
||||
unless allowed_warnings.any? { |pattern| message.match(pattern) }
|
||||
ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:raise].call(message, callstack, deprecator)
|
||||
end
|
||||
end
|
||||
|
||||
# Raises error for missing translations.
|
||||
config.i18n.raise_on_missing_translations = true
|
||||
|
||||
# Tests assume English text on the site.
|
||||
config.i18n.default_locale = "en"
|
||||
@@ -46,13 +103,11 @@ Openfoodnetwork::Application.configure do
|
||||
config.i18n.fallbacks = [:en]
|
||||
I18n.locale = config.i18n.locale = config.i18n.default_locale
|
||||
|
||||
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
||||
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
||||
# like if you have constraints or database-specific column types
|
||||
# config.active_record.schema_format = :sql
|
||||
# Annotate rendered view with file names.
|
||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||
|
||||
# Print deprecation notices to the stderr
|
||||
# config.active_support.deprecation = :stderr
|
||||
# Raise error when a before_action's only/except options reference missing actions
|
||||
# config.action_controller.raise_on_missing_callback_actions = true
|
||||
|
||||
config.active_job.queue_adapter = :test
|
||||
end
|
||||
|
||||
@@ -1 +1,24 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Version of your assets, change this if you want to expire all your assets.
|
||||
Rails.application.config.assets.version = "1.2"
|
||||
|
||||
# Add additional assets to the asset load path.
|
||||
Rails.application.config.assets.paths << Rails.root.join('node_modules')
|
||||
|
||||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in the app/assets
|
||||
# folder are already added.
|
||||
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
|
||||
|
||||
# css and js files other than application.* are not precompiled by default
|
||||
# Instead, they must be explicitly included below
|
||||
# http://stackoverflow.com/questions/8012434/what-is-the-purpose-of-config-assets-precompile
|
||||
Rails.application.config.assets.precompile += [
|
||||
'admin/*.js', 'admin/**/*.js', 'admin_minimal.js',
|
||||
'web/all.js',
|
||||
'darkswarm/all.js',
|
||||
'shared/*',
|
||||
'mail.scss',
|
||||
'*.jpg', '*.jpeg', '*.png', '*.gif' '*.svg',
|
||||
]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Define an application-wide content security policy
|
||||
# For further information see the following documentation
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||
# Define an application-wide content security policy.
|
||||
# See the Securing Rails Applications Guide for more information:
|
||||
# https://guides.rubyonrails.org/security.html#content-security-policy-header
|
||||
|
||||
Rails.application.config.content_security_policy do |policy|
|
||||
policy.default_src :self, :https
|
||||
@@ -23,15 +23,11 @@ Rails.application.config.content_security_policy do |policy|
|
||||
|
||||
# Specify URI for violation reports
|
||||
# policy.report_uri "/csp-violation-report-endpoint"
|
||||
|
||||
# Generate session nonces for permitted importmap, inline scripts, and inline styles.
|
||||
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
|
||||
# config.content_security_policy_nonce_directives = %w(script-src style-src)
|
||||
|
||||
# Report violations without enforcing the policy.
|
||||
# config.content_security_policy_report_only = true
|
||||
end
|
||||
|
||||
# If you are using UJS then enable automatic nonce generation
|
||||
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
||||
|
||||
# Set the nonce only to specific directives
|
||||
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
|
||||
|
||||
# Report CSP violations to a specified URI
|
||||
# For further information see the following documentation:
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
|
||||
# Rails.application.config.content_security_policy_report_only = true
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [:password, :vine_api_key, :vine_secret]
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
|
||||
# Use this to limit dissemination of sensitive information.
|
||||
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
|
||||
Rails.application.config.filter_parameters += [
|
||||
:passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn,
|
||||
:number, :verification_value,
|
||||
:vine_api_key, :vine_secret,
|
||||
]
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new inflection rules using the following format
|
||||
# (all these examples are active by default):
|
||||
# ActiveSupport::Inflector.inflections do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# Add new inflection rules using the following format. Inflections
|
||||
# are locale specific, and you may define rules for as many different
|
||||
# locales as you wish. All of these examples are active by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.plural /^(ox)$/i, "\\1en"
|
||||
# inflect.singular /^(ox)en/i, "\\1"
|
||||
# inflect.irregular "person", "people"
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.acronym "RESTful"
|
||||
# end
|
||||
|
||||
Rails.autoloaders.each do |autoloader|
|
||||
autoloader.inflector.inflect(
|
||||
"stripe_sca" => "StripeSCA"
|
||||
|
||||
143
config/initializers/new_framework_defaults_7_0.rb
Normal file
143
config/initializers/new_framework_defaults_7_0.rb
Normal file
@@ -0,0 +1,143 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
#
|
||||
# This file eases your Rails 7.0 framework defaults upgrade.
|
||||
#
|
||||
# Uncomment each configuration one by one to switch to the new default.
|
||||
# Once your application is ready to run with all new defaults, you can remove
|
||||
# this file and set the `config.load_defaults` to `7.0`.
|
||||
#
|
||||
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
||||
|
||||
# `button_to` view helper will render `<button>` element, regardless of whether
|
||||
# or not the content is passed as the first argument or as a block.
|
||||
# Rails.application.config.action_view.button_to_generates_button_tag = true
|
||||
|
||||
# `stylesheet_link_tag` view helper will not render the media attribute by default.
|
||||
# Rails.application.config.action_view.apply_stylesheet_media_default = false
|
||||
|
||||
# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
|
||||
# Changing this default means invalidate all encrypted messages generated by
|
||||
# your application and, all the encrypted cookies. Only change this after you
|
||||
# rotated all the messages using the key rotator.
|
||||
#
|
||||
# See upgrading guide for more information on how to build a rotator.
|
||||
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
|
||||
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
|
||||
|
||||
# Change the digest class for ActiveSupport::Digest.
|
||||
# Changing this default means that for example Etags change and
|
||||
# various cache keys leading to cache invalidation.
|
||||
# Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
|
||||
|
||||
# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
|
||||
# implementation.
|
||||
# Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
|
||||
|
||||
# Calls `Rails.application.executor.wrap` around test cases.
|
||||
# This makes test cases behave closer to an actual request or job.
|
||||
# Several features that are normally disabled in test, such as Active Record query cache
|
||||
# and asynchronous queries will then be enabled.
|
||||
# Rails.application.config.active_support.executor_around_test_case = true
|
||||
|
||||
# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
|
||||
# Rails.application.config.action_mailer.smtp_timeout = 5
|
||||
|
||||
# The ActiveStorage video previewer will now use scene change detection to generate
|
||||
# better preview images (rather than the previous default of using the first frame
|
||||
# of the video).
|
||||
# Rails.application.config.active_storage.video_preview_arguments =
|
||||
# "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1' -frames:v 1 -f image2"
|
||||
|
||||
# Automatically infer `inverse_of` for associations with a scope.
|
||||
# Rails.application.config.active_record.automatic_scope_inversing = true
|
||||
|
||||
# Raise when running tests if fixtures contained foreign key violations
|
||||
# Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
|
||||
|
||||
# Disable partial inserts.
|
||||
# This default means that all columns will be referenced in INSERT queries
|
||||
# regardless of whether they have a default or not.
|
||||
# Rails.application.config.active_record.partial_inserts = false
|
||||
|
||||
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
|
||||
# Rails.application.config.action_controller.raise_on_open_redirects = true
|
||||
|
||||
# Change the variant processor for Active Storage.
|
||||
# Changing this default means updating all places in your code that
|
||||
# generate variants to use image processing macros and ruby-vips
|
||||
# operations. See the upgrading guide for detail on the changes required.
|
||||
# The `:mini_magick` option is not deprecated; it's fine to keep using it.
|
||||
# Rails.application.config.active_storage.variant_processor = :vips
|
||||
|
||||
# Enable parameter wrapping for JSON.
|
||||
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
|
||||
# To disable parameter wrapping entirely, set this config to `false`.
|
||||
# Rails.application.config.action_controller.wrap_parameters_by_default = true
|
||||
|
||||
# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
|
||||
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
|
||||
#
|
||||
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
|
||||
# more information.
|
||||
# Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
|
||||
|
||||
# Change the default headers to disable browsers' flawed legacy XSS protection.
|
||||
# Rails.application.config.action_dispatch.default_headers = {
|
||||
# "X-Frame-Options" => "SAMEORIGIN",
|
||||
# "X-XSS-Protection" => "0",
|
||||
# "X-Content-Type-Options" => "nosniff",
|
||||
# "X-Download-Options" => "noopen",
|
||||
# "X-Permitted-Cross-Domain-Policies" => "none",
|
||||
# "Referrer-Policy" => "strict-origin-when-cross-origin"
|
||||
# }
|
||||
|
||||
|
||||
# ** Please read carefully, this must be configured in config/application.rb **
|
||||
# Change the format of the cache entry.
|
||||
# Changing this default means that all new cache entries added to the cache
|
||||
# will have a different format that is not supported by Rails 6.1 applications.
|
||||
# Only change this value after your application is fully deployed to Rails 7.0
|
||||
# and you have no plans to rollback.
|
||||
# When you're ready to change format, add this to `config/application.rb` (NOT this file):
|
||||
# config.active_support.cache_format_version = 7.0
|
||||
|
||||
|
||||
# Cookie serializer: 2 options
|
||||
#
|
||||
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
|
||||
# is `:marshal`. The default for new apps is `:json`.
|
||||
#
|
||||
# Rails.application.config.action_dispatch.cookies_serializer = :json
|
||||
#
|
||||
#
|
||||
# To migrate an existing application to the `:json` serializer, use the `:hybrid` option.
|
||||
#
|
||||
# Rails transparently deserializes existing (Marshal-serialized) cookies on read and
|
||||
# re-writes them in the JSON format.
|
||||
#
|
||||
# It is fine to use `:hybrid` long term; you should do that until you're confident *all* your cookies
|
||||
# have been converted to JSON. To keep using `:hybrid` long term, move this config to its own
|
||||
# initializer or to `config/application.rb`.
|
||||
#
|
||||
# Rails.application.config.action_dispatch.cookies_serializer = :hybrid
|
||||
#
|
||||
#
|
||||
# If your cookies can't yet be serialized to JSON, keep using `:marshal` for backward-compatibility.
|
||||
#
|
||||
# If you have configured the serializer elsewhere, you can remove this section of the file.
|
||||
#
|
||||
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
|
||||
|
||||
# Change the return value of `ActionDispatch::Request#content_type` to the Content-Type header without modification.
|
||||
# Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type = false
|
||||
|
||||
# Active Storage `has_many_attached` relationships will default to replacing the current collection instead of appending to it.
|
||||
# Thus, to support submitting an empty collection, the `file_field` helper will render an hidden field `include_hidden` by default when `multiple_file_field_include_hidden` is set to `true`.
|
||||
# See https://guides.rubyonrails.org/configuring.html#config-active-storage-multiple-file-field-include-hidden for more information.
|
||||
# Rails.application.config.active_storage.multiple_file_field_include_hidden = true
|
||||
|
||||
# ** Please read carefully, this must be configured in config/application.rb (NOT this file) **
|
||||
# Disables the deprecated #to_s override in some Ruby core classes
|
||||
# See https://guides.rubyonrails.org/configuring.html#config-active-support-disable-to-s-conversion for more information.
|
||||
# config.active_support.disable_to_s_conversion = true
|
||||
280
config/initializers/new_framework_defaults_7_1.rb
Normal file
280
config/initializers/new_framework_defaults_7_1.rb
Normal file
@@ -0,0 +1,280 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
#
|
||||
# This file eases your Rails 7.1 framework defaults upgrade.
|
||||
#
|
||||
# Uncomment each configuration one by one to switch to the new default.
|
||||
# Once your application is ready to run with all new defaults, you can remove
|
||||
# this file and set the `config.load_defaults` to `7.1`.
|
||||
#
|
||||
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
||||
|
||||
###
|
||||
# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able
|
||||
# to manually require files that are managed by the autoloader, which you shouldn't do anyway.
|
||||
#
|
||||
# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size
|
||||
# of the bootsnap cache if you use it.
|
||||
#
|
||||
# To set this configuration, add the following line to `config/application.rb` (NOT this file):
|
||||
# config.add_autoload_paths_to_load_path = false
|
||||
|
||||
###
|
||||
# Remove the default X-Download-Options headers since it is used only by Internet Explorer.
|
||||
# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`.
|
||||
#++
|
||||
# Rails.application.config.action_dispatch.default_headers = {
|
||||
# "X-Frame-Options" => "SAMEORIGIN",
|
||||
# "X-XSS-Protection" => "0",
|
||||
# "X-Content-Type-Options" => "nosniff",
|
||||
# "X-Permitted-Cross-Domain-Policies" => "none",
|
||||
# "Referrer-Policy" => "strict-origin-when-cross-origin"
|
||||
# }
|
||||
|
||||
###
|
||||
# Do not treat an `ActionController::Parameters` instance
|
||||
# as equal to an equivalent `Hash` by default.
|
||||
#++
|
||||
# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false
|
||||
|
||||
###
|
||||
# Active Record Encryption now uses SHA-256 as its hash digest algorithm.
|
||||
#
|
||||
# There are 3 scenarios to consider.
|
||||
#
|
||||
# 1. If you have data encrypted with previous Rails versions, and you have
|
||||
# +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default
|
||||
# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too:
|
||||
#++
|
||||
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
|
||||
#
|
||||
# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default
|
||||
# in 7.0), then you need to configure SHA-256 for Active Record Encryption:
|
||||
#++
|
||||
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
|
||||
#
|
||||
# 3. If you don't currently have data encrypted with Active Record encryption, you can disable this setting to
|
||||
# configure the default behavior starting 7.1+:
|
||||
#++
|
||||
# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false
|
||||
|
||||
###
|
||||
# No longer run after_commit callbacks on the first of multiple Active Record
|
||||
# instances to save changes to the same database row within a transaction.
|
||||
# Instead, run these callbacks on the instance most likely to have internal
|
||||
# state which matches what was committed to the database, typically the last
|
||||
# instance to save.
|
||||
#++
|
||||
# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
|
||||
|
||||
###
|
||||
# Configures SQLite with a strict strings mode, which disables double-quoted string literals.
|
||||
#
|
||||
# SQLite has some quirks around double-quoted string literals.
|
||||
# It first tries to consider double-quoted strings as identifier names, but if they don't exist
|
||||
# it then considers them as string literals. Because of this, typos can silently go unnoticed.
|
||||
# For example, it is possible to create an index for a non existing column.
|
||||
# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details.
|
||||
#++
|
||||
# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true
|
||||
|
||||
###
|
||||
# Disable deprecated singular associations names.
|
||||
#++
|
||||
# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false
|
||||
|
||||
###
|
||||
# Enable the Active Job `BigDecimal` argument serializer, which guarantees
|
||||
# roundtripping. Without this serializer, some queue adapters may serialize
|
||||
# `BigDecimal` arguments as simple (non-roundtrippable) strings.
|
||||
#
|
||||
# When deploying an application with multiple replicas, old (pre-Rails 7.1)
|
||||
# replicas will not be able to deserialize `BigDecimal` arguments from this
|
||||
# serializer. Therefore, this setting should only be enabled after all replicas
|
||||
# have been successfully upgraded to Rails 7.1.
|
||||
#++
|
||||
# Rails.application.config.active_job.use_big_decimal_serializer = true
|
||||
|
||||
###
|
||||
# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or
|
||||
# `write` are given an invalid `expires_at` or `expires_in` time.
|
||||
# Options are `true`, and `false`. If `false`, the exception will be reported
|
||||
# as `handled` and logged instead.
|
||||
#++
|
||||
# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true
|
||||
|
||||
###
|
||||
# Specify whether Query Logs will format tags using the SQLCommenter format
|
||||
# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format.
|
||||
# Options are `:legacy` and `:sqlcommenter`.
|
||||
#++
|
||||
# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter
|
||||
|
||||
###
|
||||
# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier`
|
||||
# instances.
|
||||
#
|
||||
# The legacy default is `:marshal`, which is a potential vector for
|
||||
# deserialization attacks in cases where a message signing secret has been
|
||||
# leaked.
|
||||
#
|
||||
# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and
|
||||
# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing
|
||||
# with `Marshal` so that legacy messages can still be read.
|
||||
#
|
||||
# In Rails 7.2, the default will become `:json` which serializes and
|
||||
# deserializes with `ActiveSupport::JSON` only.
|
||||
#
|
||||
# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`,
|
||||
# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack`
|
||||
# can roundtrip some Ruby types that are not supported by JSON, and may provide
|
||||
# improved performance, but it requires the `msgpack` gem.
|
||||
#
|
||||
# For more information, see
|
||||
# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer
|
||||
#
|
||||
# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers
|
||||
# that have not yet been upgraded must be able to read messages from upgraded
|
||||
# servers, first deploy without changing the serializer, then set the serializer
|
||||
# in a subsequent deploy.
|
||||
#++
|
||||
# Rails.application.config.active_support.message_serializer = :json_allow_marshal
|
||||
|
||||
###
|
||||
# Enable a performance optimization that serializes message data and metadata
|
||||
# together. This changes the message format, so messages serialized this way
|
||||
# cannot be read by older versions of Rails. However, messages that use the old
|
||||
# format can still be read, regardless of whether this optimization is enabled.
|
||||
#
|
||||
# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have
|
||||
# not yet been upgraded must be able to read messages from upgraded servers,
|
||||
# leave this optimization off on the first deploy, then enable it on a
|
||||
# subsequent deploy.
|
||||
#++
|
||||
# Rails.application.config.active_support.use_message_serializer_for_metadata = true
|
||||
|
||||
###
|
||||
# Set the maximum size for Rails log files.
|
||||
#
|
||||
# `config.load_defaults 7.1` does not set this value for environments other than
|
||||
# development and test.
|
||||
#++
|
||||
# if Rails.env.local?
|
||||
# Rails.application.config.log_file_size = 100 * 1024 * 1024
|
||||
# end
|
||||
|
||||
###
|
||||
# Enable raising on assignment to attr_readonly attributes. The previous
|
||||
# behavior would allow assignment but silently not persist changes to the
|
||||
# database.
|
||||
#++
|
||||
# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true
|
||||
|
||||
###
|
||||
# Enable validating only parent-related columns for presence when the parent is mandatory.
|
||||
# The previous behavior was to validate the presence of the parent record, which performed an extra query
|
||||
# to get the parent every time the child record was updated, even when parent has not changed.
|
||||
#++
|
||||
# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false
|
||||
|
||||
###
|
||||
# Enable precompilation of `config.filter_parameters`. Precompilation can
|
||||
# improve filtering performance, depending on the quantity and types of filters.
|
||||
#++
|
||||
# Rails.application.config.precompile_filter_parameters = true
|
||||
|
||||
###
|
||||
# Enable before_committed! callbacks on all enrolled records in a transaction.
|
||||
# The previous behavior was to only run the callbacks on the first copy of a record
|
||||
# if there were multiple copies of the same record enrolled in the transaction.
|
||||
#++
|
||||
# Rails.application.config.active_record.before_committed_on_all_records = true
|
||||
|
||||
###
|
||||
# Disable automatic column serialization into YAML.
|
||||
# To keep the historic behavior, you can set it to `YAML`, however it is
|
||||
# recommended to explicitly define the serialization method for each column
|
||||
# rather than to rely on a global default.
|
||||
#++
|
||||
# Rails.application.config.active_record.default_column_serializer = nil
|
||||
|
||||
###
|
||||
# Enable a performance optimization that serializes Active Record models
|
||||
# in a faster and more compact way.
|
||||
#
|
||||
# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have
|
||||
# not yet been upgraded must be able to read caches from upgraded servers,
|
||||
# leave this optimization off on the first deploy, then enable it on a
|
||||
# subsequent deploy.
|
||||
#++
|
||||
# Rails.application.config.active_record.marshalling_format_version = 7.1
|
||||
|
||||
###
|
||||
# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model.
|
||||
# This matches the behaviour of all other callbacks.
|
||||
# In previous versions of Rails, they ran in the inverse order.
|
||||
#++
|
||||
# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true
|
||||
|
||||
###
|
||||
# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`.
|
||||
#++
|
||||
# Rails.application.config.active_record.commit_transaction_on_non_local_return = true
|
||||
|
||||
###
|
||||
# Controls when to generate a value for <tt>has_secure_token</tt> declarations.
|
||||
#++
|
||||
# Rails.application.config.active_record.generate_secure_token_on = :initialize
|
||||
|
||||
###
|
||||
# ** Please read carefully, this must be configured in config/application.rb **
|
||||
#
|
||||
# Change the format of the cache entry.
|
||||
#
|
||||
# Changing this default means that all new cache entries added to the cache
|
||||
# will have a different format that is not supported by Rails 7.0
|
||||
# applications.
|
||||
#
|
||||
# Only change this value after your application is fully deployed to Rails 7.1
|
||||
# and you have no plans to rollback.
|
||||
# When you're ready to change format, add this to `config/application.rb` (NOT
|
||||
# this file):
|
||||
# config.active_support.cache_format_version = 7.1
|
||||
|
||||
###
|
||||
# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your
|
||||
# platform.
|
||||
#
|
||||
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant
|
||||
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
|
||||
#
|
||||
# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor.
|
||||
#++
|
||||
# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
|
||||
|
||||
###
|
||||
# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your
|
||||
# platform.
|
||||
#
|
||||
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant
|
||||
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
|
||||
#
|
||||
# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor.
|
||||
#++
|
||||
# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
|
||||
|
||||
###
|
||||
# Configure the log level used by the DebugExceptions middleware when logging
|
||||
# uncaught exceptions during requests.
|
||||
#++
|
||||
# Rails.application.config.action_dispatch.debug_exception_log_level = :error
|
||||
|
||||
###
|
||||
# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5
|
||||
# parsers.
|
||||
#
|
||||
# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4.
|
||||
#
|
||||
# In previous versions of Rails, these test helpers always used an HTML4 parser.
|
||||
#++
|
||||
# Rails.application.config.dom_testing_default_html_version = :html5
|
||||
13
config/initializers/permissions_policy.rb
Normal file
13
config/initializers/permissions_policy.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Define an application-wide HTTP permissions policy. For further
|
||||
# information see: https://developers.google.com/web/updates/2018/06/feature-policy
|
||||
|
||||
# Rails.application.config.permissions_policy do |policy|
|
||||
# policy.camera :none
|
||||
# policy.gyroscope :none
|
||||
# policy.microphone :none
|
||||
# policy.usb :none
|
||||
# policy.fullscreen :self
|
||||
# policy.payment :self, "https://secure.example.com"
|
||||
# end
|
||||
@@ -1446,6 +1446,8 @@ cy:
|
||||
visible: Gweladwy?
|
||||
owner: Perchennog
|
||||
producer: Cynhyrchydd
|
||||
sells_options:
|
||||
none: dim
|
||||
change_type_form:
|
||||
producer_profile: Proffil Cynhyrchydd
|
||||
connect_ofn: Cysylltu trwy'r Open Food Network
|
||||
|
||||
@@ -1518,6 +1518,11 @@ en:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
unspecified: unspecified
|
||||
none: none
|
||||
own: own
|
||||
any: any
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
|
||||
@@ -1447,6 +1447,8 @@ en_CA:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
none: none
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
@@ -3618,7 +3620,7 @@ en_CA:
|
||||
removed_terms_and_conditions_successfully: "Terms and Conditions file removed successfully"
|
||||
insufficient_stock: "Insufficient stock available, only %{on_hand} remaining"
|
||||
out_of_stock:
|
||||
reduced_stock_available: Reduced stock available
|
||||
reduced_stock_available: 'Reduced stock '
|
||||
out_of_stock_text: >
|
||||
While you've been shopping, the stock levels for one or more of the products
|
||||
in your cart have reduced. Here's what's changed:
|
||||
|
||||
@@ -1447,6 +1447,8 @@ en_FR:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
none: none
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
|
||||
@@ -1447,6 +1447,8 @@ en_GB:
|
||||
visible: Visible?
|
||||
owner: Owner
|
||||
producer: Producer
|
||||
sells_options:
|
||||
none: none
|
||||
change_type_form:
|
||||
producer_profile: Producer Profile
|
||||
connect_ofn: Connect through OFN
|
||||
|
||||
@@ -1445,6 +1445,8 @@ fi:
|
||||
visible: Näkyvissä?
|
||||
owner: Omistaja
|
||||
producer: Tuottaja
|
||||
sells_options:
|
||||
none: ei yhtään
|
||||
change_type_form:
|
||||
producer_profile: Tuottajan profiili
|
||||
connect_ofn: Yhdistä OFN:n kautta
|
||||
|
||||
@@ -1449,6 +1449,8 @@ fr:
|
||||
visible: Visible?
|
||||
owner: Gestionnaire principal
|
||||
producer: Producteur
|
||||
sells_options:
|
||||
none: aucun
|
||||
change_type_form:
|
||||
producer_profile: Profil simple
|
||||
connect_ofn: Pour apparaître sur la carte et la liste des producteurs
|
||||
|
||||
@@ -1451,6 +1451,8 @@ fr_CA:
|
||||
visible: Visible?
|
||||
owner: Gérant
|
||||
producer: Producteur
|
||||
sells_options:
|
||||
none: aucun
|
||||
change_type_form:
|
||||
producer_profile: Profil producteur
|
||||
connect_ofn: Gagnez en visibilité via OFN
|
||||
|
||||
@@ -1383,6 +1383,8 @@ hu:
|
||||
visible: Látható?
|
||||
owner: Tulajdonos
|
||||
producer: Termelő
|
||||
sells_options:
|
||||
none: n.a.
|
||||
change_type_form:
|
||||
producer_profile: Termelői Profil
|
||||
connect_ofn: Csatlakozás OFN-en keresztül
|
||||
|
||||
16
db/migrate/20250515050349_create_dfc_permissions.rb
Normal file
16
db/migrate/20250515050349_create_dfc_permissions.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateDfcPermissions < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :dfc_permissions do |t|
|
||||
t.references :user, null: false, foreign_key: { to_table: :spree_users }
|
||||
t.references :enterprise, null: false, foreign_key: true
|
||||
t.string :grantee, null: false
|
||||
t.string :scope, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :dfc_permissions, :grantee
|
||||
add_index :dfc_permissions, :scope
|
||||
end
|
||||
end
|
||||
15
db/schema.rb
15
db/schema.rb
@@ -111,6 +111,19 @@ ActiveRecord::Schema[7.0].define(version: 2025_07_09_012346) do
|
||||
t.index ["user_id"], name: "index_customers_on_user_id"
|
||||
end
|
||||
|
||||
create_table "dfc_permissions", force: :cascade do |t|
|
||||
t.bigint "user_id", null: false
|
||||
t.bigint "enterprise_id", null: false
|
||||
t.string "grantee", null: false
|
||||
t.string "scope", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["enterprise_id"], name: "index_dfc_permissions_on_enterprise_id"
|
||||
t.index ["grantee"], name: "index_dfc_permissions_on_grantee"
|
||||
t.index ["scope"], name: "index_dfc_permissions_on_scope"
|
||||
t.index ["user_id"], name: "index_dfc_permissions_on_user_id"
|
||||
end
|
||||
|
||||
create_table "distributors_payment_methods", force: :cascade do |t|
|
||||
t.integer "distributor_id", null: false
|
||||
t.integer "payment_method_id", null: false
|
||||
@@ -1144,6 +1157,8 @@ ActiveRecord::Schema[7.0].define(version: 2025_07_09_012346) do
|
||||
add_foreign_key "customers", "spree_addresses", column: "bill_address_id", name: "customers_bill_address_id_fk"
|
||||
add_foreign_key "customers", "spree_addresses", column: "ship_address_id", name: "customers_ship_address_id_fk"
|
||||
add_foreign_key "customers", "spree_users", column: "user_id", name: "customers_user_id_fk"
|
||||
add_foreign_key "dfc_permissions", "enterprises"
|
||||
add_foreign_key "dfc_permissions", "spree_users", column: "user_id"
|
||||
add_foreign_key "distributors_payment_methods", "enterprises", column: "distributor_id", name: "distributors_payment_methods_distributor_id_fk"
|
||||
add_foreign_key "distributors_payment_methods", "spree_payment_methods", column: "payment_method_id", name: "distributors_payment_methods_payment_method_id_fk"
|
||||
add_foreign_key "distributors_shipping_methods", "enterprises", column: "distributor_id", name: "distributors_shipping_methods_distributor_id_fk"
|
||||
|
||||
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
||||
s.authors = ["developers@ofn"]
|
||||
s.summary = "Catalog domain of the OFN solution."
|
||||
|
||||
s.required_ruby_version = File.read(File.expand_path("../../.ruby-version", __dir__)).chomp
|
||||
s.required_ruby_version = ">= 1.0.0" # rubocop:disable Gemspec/RequiredRubyVersion
|
||||
|
||||
s.files = Dir["{app,config,db,lib}/**/*"] + ["LICENSE.txt", "Rakefile", "README.rdoc"]
|
||||
s.metadata['rubygems_mfa_required'] = 'true'
|
||||
|
||||
@@ -30,8 +30,7 @@ module DfcProvider
|
||||
# - Spree::Shipment
|
||||
# - Subscription
|
||||
def authorized(address)
|
||||
current_user.ship_address_id == address.id ||
|
||||
current_user.bill_address_id == address.id ||
|
||||
user_address(address) ||
|
||||
[
|
||||
customer_address(address),
|
||||
public_enterprise_group_address(address),
|
||||
@@ -40,6 +39,13 @@ module DfcProvider
|
||||
].any?(&:exists?)
|
||||
end
|
||||
|
||||
def user_address(address)
|
||||
return false if current_user.is_a? ApiUser
|
||||
|
||||
current_user.ship_address_id == address.id ||
|
||||
current_user.bill_address_id == address.id
|
||||
end
|
||||
|
||||
def customer_address(address)
|
||||
current_user.customers.where(bill_address: address).or(
|
||||
current_user.customers.where(ship_address: address)
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
# Controller used to provide the API products for the DFC application
|
||||
module DfcProvider
|
||||
class ApplicationController < ActionController::Base
|
||||
class Unauthorized < StandardError; end
|
||||
|
||||
include ActiveStorage::SetCurrent
|
||||
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from CanCan::AccessDenied, with: :unauthorized
|
||||
rescue_from Unauthorized, with: :unauthorized
|
||||
|
||||
before_action :check_authorization
|
||||
|
||||
@@ -16,6 +19,13 @@ module DfcProvider
|
||||
|
||||
private
|
||||
|
||||
def require_permission(scope)
|
||||
return if current_user.is_a? Spree::User
|
||||
return if current_user.permissions(scope).where(enterprise: current_enterprise).exists?
|
||||
|
||||
raise Unauthorized
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
unauthorized if current_user.nil?
|
||||
end
|
||||
@@ -63,5 +73,10 @@ module DfcProvider
|
||||
def import
|
||||
DfcIo.import(request.body)
|
||||
end
|
||||
|
||||
# Checks weather a feature is enabled for any of the given actors.
|
||||
def feature?(feature, *actors)
|
||||
OpenFoodNetwork::FeatureToggle.enabled?(feature, *actors)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,16 +7,14 @@ module DfcProvider
|
||||
before_action :check_enterprise
|
||||
|
||||
def index
|
||||
person = PersonBuilder.person(current_user)
|
||||
require_permission "ReadProducts"
|
||||
|
||||
enterprises = current_user.enterprises.map do |enterprise|
|
||||
EnterpriseBuilder.enterprise(enterprise)
|
||||
end
|
||||
person.affiliatedOrganizations = enterprises
|
||||
catalog_items = enterprises.flat_map(&:catalogItems)
|
||||
|
||||
render json: DfcIo.export(
|
||||
person,
|
||||
*enterprises,
|
||||
*catalog_items,
|
||||
*catalog_items.map(&:product),
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module DfcProvider
|
||||
class PlatformsController < DfcProvider::ApplicationController
|
||||
# List of platform identifiers.
|
||||
# local ID => semantic ID
|
||||
PLATFORM_IDS = {
|
||||
'cqcm-dev' => "https://api.proxy-dev.cqcm.startinblox.com/profile",
|
||||
}.freeze
|
||||
|
||||
prepend_before_action :move_authenticity_token
|
||||
before_action :check_enterprise
|
||||
|
||||
def index
|
||||
render json: platforms
|
||||
end
|
||||
|
||||
def show
|
||||
render json: platform(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
key = params[:id]
|
||||
requested_platform = JSON.parse(request.body.read)
|
||||
requested_scopes = requested_platform
|
||||
.dig("dfc-t:hasAssignedScopes", "@list")
|
||||
.pluck("@id")
|
||||
.map { |uri| uri[/[a-zA-Z]+\z/] } # return last part like ReadEnterprise
|
||||
current_scopes = granted_scopes(key)
|
||||
scopes_to_delete = current_scopes - requested_scopes
|
||||
scopes_to_create = requested_scopes - current_scopes
|
||||
|
||||
DfcPermission.where(
|
||||
user: current_user,
|
||||
enterprise: current_enterprise,
|
||||
scope: scopes_to_delete,
|
||||
grantee: key,
|
||||
).delete_all
|
||||
|
||||
scopes_to_create.each do |scope|
|
||||
DfcPermission.create!(
|
||||
user: current_user,
|
||||
enterprise: current_enterprise,
|
||||
scope:,
|
||||
grantee: key,
|
||||
)
|
||||
end
|
||||
render json: platform(key)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def platforms
|
||||
id = DfcProvider::Engine.routes.url_helpers.enterprise_platforms_url(current_enterprise.id)
|
||||
platforms = available_platforms.map(&method(:platform))
|
||||
|
||||
{
|
||||
'@context': "https://cdn.startinblox.com/owl/context-bis.jsonld",
|
||||
'@id': id,
|
||||
'dfc-t:platforms': {
|
||||
'@type': "rdf:List",
|
||||
'@list': platforms,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def available_platforms
|
||||
PLATFORM_IDS.keys.select(&method(:feature?))
|
||||
end
|
||||
|
||||
def platform(key)
|
||||
{
|
||||
'@type': "dfc-t:Platform",
|
||||
'@id': PLATFORM_IDS[key],
|
||||
localId: key,
|
||||
'dfc-t:hasAssignedScopes': {
|
||||
'@type': "rdf:List",
|
||||
'@list': scopes(key),
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def scopes(platform_id)
|
||||
granted_scopes(platform_id).map do |scope|
|
||||
{
|
||||
'@id': "https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf##{scope}",
|
||||
'@type': "dfc-t:Scope",
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def granted_scopes(platform_id)
|
||||
DfcPermission.where(
|
||||
user: current_user,
|
||||
enterprise: current_enterprise,
|
||||
grantee: platform_id,
|
||||
).pluck(:scope)
|
||||
end
|
||||
|
||||
# The DFC Permission Module is sending tokens in the Authorization header.
|
||||
# It assumes that it's an OIDC access token but we are passing the Rails
|
||||
# CSRF token to the component to allow POST request with cookie auth.
|
||||
def move_authenticity_token
|
||||
token = request.delete_header('HTTP_AUTHORIZATION').to_s.split.last
|
||||
request.headers['X-CSRF-Token'] = token if token
|
||||
end
|
||||
end
|
||||
end
|
||||
36
engines/dfc_provider/app/services/api_user.rb
Normal file
36
engines/dfc_provider/app/services/api_user.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authorised user or client using the API
|
||||
class ApiUser
|
||||
CLIENT_MAP = {
|
||||
"https://waterlooregionfood.ca/portal/profile" => "cqcm-dev",
|
||||
}.freeze
|
||||
|
||||
def self.from_client_id(client_id)
|
||||
id = CLIENT_MAP[client_id]
|
||||
|
||||
new(id) if id
|
||||
end
|
||||
|
||||
attr_reader :id
|
||||
|
||||
def initialize(id)
|
||||
@id = id
|
||||
end
|
||||
|
||||
def admin?
|
||||
false
|
||||
end
|
||||
|
||||
def customers
|
||||
Customer.none
|
||||
end
|
||||
|
||||
def enterprises
|
||||
Enterprise.where(dfc_permissions: permissions("ReadEnterprise"))
|
||||
end
|
||||
|
||||
def permissions(scope)
|
||||
DfcPermission.where(grantee: id, scope:)
|
||||
end
|
||||
end
|
||||
@@ -1,17 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Service used to authorize the user on DCF Provider API
|
||||
# Authorize the user on the DFC API
|
||||
#
|
||||
# It controls an OICD Access token and an enterprise.
|
||||
class AuthorizationControl
|
||||
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
|
||||
LES_COMMUNES_PUBLIC_KEY = <<~KEY
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
PUBLIC_KEYS = {
|
||||
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
|
||||
"https://login.lescommuns.org/auth/realms/data-food-consortium" => <<~KEY,
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
|
||||
def self.public_key
|
||||
OpenSSL::PKey::RSA.new(LES_COMMUNES_PUBLIC_KEY)
|
||||
# Copied from: https://kc.cqcm.startinblox.com/realms/startinblox
|
||||
"https://kc.cqcm.startinblox.com/realms/startinblox" => <<~KEY,
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtvdb3BdHoLnNeMLaWd7nugPwdRAJJpdSySTtttEQY2/v1Q3byJ/kReSNGrUNkPVkOeDN3milgN5Apz+sNCwbtzOCulyFMmvuIOZFBqz5tcgwjZinSwpGBXpn6ehXyCET2LlcfLYAPA9axtaNg9wBLIHoxIPWpa2LcZstogyZY/yKUZXQTDqM5B5TyUkPN89xHFdq8SQuXPasbpYl7mGhZHkTDHiKZ9VK7K5tqsEZTD9dCuTGMKsthbOrlDnc9bAJ3PyKLRdib21Y1GGlTozo4Y/1q448E/DFp5rVC6jG6JFnsEnP0WVn+6qz7yxI7IfUU2YSAGgtGYaQkWtEfED0QIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
}.freeze
|
||||
|
||||
def self.public_key(token)
|
||||
unverified_payload = JWT.decode(token, nil, false, { algorithm: "RS256" }).first
|
||||
key = PUBLIC_KEYS[unverified_payload["iss"]]
|
||||
OpenSSL::PKey::RSA.new(key)
|
||||
end
|
||||
|
||||
def initialize(request)
|
||||
@@ -27,7 +39,11 @@ class AuthorizationControl
|
||||
private
|
||||
|
||||
def oidc_user
|
||||
find_ofn_user(decode_token) if access_token
|
||||
return unless access_token
|
||||
|
||||
payload = decode_token
|
||||
|
||||
find_ofn_user(payload) || client_user(payload)
|
||||
end
|
||||
|
||||
def ofn_api_user
|
||||
@@ -41,7 +57,7 @@ class AuthorizationControl
|
||||
def decode_token
|
||||
JWT.decode(
|
||||
access_token,
|
||||
self.class.public_key,
|
||||
self.class.public_key(access_token),
|
||||
true, { algorithm: "RS256" }
|
||||
).first
|
||||
end
|
||||
@@ -59,4 +75,8 @@ class AuthorizationControl
|
||||
|
||||
OidcAccount.find_by(uid: payload["email"])&.user
|
||||
end
|
||||
|
||||
def client_user(payload)
|
||||
ApiUser.from_client_id(payload["client_id"])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ DfcProvider::Engine.routes.draw do
|
||||
resources :enterprises, only: [:show] do
|
||||
resources :catalog_items, only: [:index, :show, :update]
|
||||
resources :offers, only: [:show, :update]
|
||||
resources :platforms, only: [:index, :show, :update]
|
||||
resources :supplied_products, only: [:create, :show, :update]
|
||||
resources :social_medias, only: [:show]
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
||||
spec.summary = 'Provides an API stack implementing DFC semantic ' \
|
||||
'specifications'
|
||||
|
||||
spec.required_ruby_version = File.read(File.expand_path("../../.ruby-version", __dir__)).chomp
|
||||
spec.required_ruby_version = ">= 1.0.0" # rubocop:disable Gemspec/RequiredRubyVersion
|
||||
|
||||
spec.files = Dir["{app,config,lib}/**/*"] + ['README.md']
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_relative "../swagger_helper"
|
||||
|
||||
RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
let(:Authorization) { nil }
|
||||
let(:user) { create(:oidc_user, id: 12_345) }
|
||||
let(:enterprise) {
|
||||
create(
|
||||
@@ -35,8 +36,15 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "List CatalogItems" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
|
||||
response "404", "not found" do
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
let(:enterprise_id) { 10_000 }
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without enterprises" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
@@ -53,6 +61,25 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
response "200", "success" do
|
||||
before { product }
|
||||
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
let(:enterprise_id) { 10_000 }
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadProducts", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "with default enterprise id" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
@@ -75,11 +102,31 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
end
|
||||
|
||||
response "401", "unauthorized" do
|
||||
let(:enterprise_id) { "default" }
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
before { login_as nil }
|
||||
let(:enterprise_id) { 10_000 }
|
||||
|
||||
run_test!
|
||||
before {
|
||||
product
|
||||
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
# But no ReadProducts permission.
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without authorisation" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
before { login_as nil }
|
||||
|
||||
run_test!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_relative "../swagger_helper"
|
||||
|
||||
RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
|
||||
let(:Authorization) { nil }
|
||||
let!(:user) { create(:oidc_user) }
|
||||
let!(:enterprise) do
|
||||
create(
|
||||
@@ -51,6 +52,21 @@ RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
|
||||
produces "application/json"
|
||||
|
||||
response "200", "successful" do
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
let(:id) { 10_000 }
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id: id,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without enterprise id" do
|
||||
let(:id) { "default" }
|
||||
|
||||
|
||||
102
engines/dfc_provider/spec/requests/platforms_spec.rb
Normal file
102
engines/dfc_provider/spec/requests/platforms_spec.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../swagger_helper"
|
||||
|
||||
RSpec.describe "Platforms", swagger_doc: "dfc.yaml" do
|
||||
let!(:user) { create(:oidc_user) }
|
||||
let!(:enterprise) do
|
||||
create(
|
||||
:distributor_enterprise,
|
||||
id: 10_000, owner: user, name: "Fred's Farm",
|
||||
)
|
||||
end
|
||||
|
||||
before { login_as user }
|
||||
|
||||
path "/api/dfc/enterprises/{enterprise_id}/platforms" do
|
||||
parameter name: :enterprise_id, in: :path, type: :string
|
||||
|
||||
get "List platforms with scopes" do
|
||||
produces "application/json"
|
||||
|
||||
response "200", "successful" do
|
||||
let(:enterprise_id) { enterprise.id }
|
||||
|
||||
run_test! do
|
||||
expect(json_response["@id"]).to eq "http://test.host/api/dfc/enterprises/10000/platforms"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
path "/api/dfc/enterprises/{enterprise_id}/platforms/{platform_id}" do
|
||||
parameter name: :enterprise_id, in: :path, type: :string
|
||||
parameter name: :platform_id, in: :path, type: :string
|
||||
|
||||
get "Show platform scopes" do
|
||||
produces "application/json"
|
||||
|
||||
response "200", "successful" do
|
||||
let(:enterprise_id) { enterprise.id }
|
||||
let(:platform_id) { "cqcm-dev" }
|
||||
|
||||
run_test! do
|
||||
expect(json_response["@id"]).to eq "https://api.proxy-dev.cqcm.startinblox.com/profile"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
put "Update authorized scopes of a platform" do
|
||||
consumes "application/json"
|
||||
produces "application/json"
|
||||
|
||||
parameter name: :platform, in: :body, schema: {
|
||||
example: {
|
||||
'@context': "https://cdn.startinblox.com/owl/context-bis.jsonld",
|
||||
'@id': "http://localhost:3000/api/dfc/enterprises/3/platforms/cqcm-dev",
|
||||
'dfc-t:hasAssignedScopes': {
|
||||
'@list': [
|
||||
{
|
||||
'@id': "https://example.com/scopes/ReadEnterprise",
|
||||
'@type': "dfc-t:Scope"
|
||||
},
|
||||
{
|
||||
'@id': "https://example.com/scopes/WriteEnterprise",
|
||||
'@type': "dfc-t:Scope"
|
||||
},
|
||||
{
|
||||
'@id': "https://example.com/scopes/ReadProducts",
|
||||
'@type': "dfc-t:Scope"
|
||||
},
|
||||
{
|
||||
'@id': "https://example.com/scopes/WriteProducts",
|
||||
'@type': "dfc-t:Scope"
|
||||
},
|
||||
{
|
||||
'@id': "https://example.com/scopes/ReadOrders",
|
||||
'@type': "dfc-t:Scope"
|
||||
},
|
||||
{
|
||||
'@id': "https://example.com/scopes/WriteOrders",
|
||||
'@type': "dfc-t:Scope"
|
||||
}
|
||||
],
|
||||
'@type': "rdf:List"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response "200", "successful" do
|
||||
let(:enterprise_id) { enterprise.id }
|
||||
let(:platform_id) { "cqcm-dev" }
|
||||
let(:platform) do |example|
|
||||
example.metadata[:operation][:parameters].first[:schema][:example]
|
||||
end
|
||||
|
||||
run_test! do
|
||||
expect(json_response["@id"]).to eq "https://api.proxy-dev.cqcm.startinblox.com/profile"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,6 +13,7 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
|
||||
variants: [variant]
|
||||
)
|
||||
}
|
||||
let(:Authorization) { nil }
|
||||
let(:variant) {
|
||||
build(:base_variant, id: 10_001, unit_value: 1, primary_taxon: taxon, supplier: enterprise)
|
||||
}
|
||||
@@ -34,10 +35,28 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "Show ProductGroup" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
|
||||
response "200", "success" do
|
||||
let(:id) { product.id }
|
||||
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadProducts", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
run_test! do
|
||||
expect(json_response["@id"]).to eq "http://test.host/api/dfc/product_groups/90000"
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ RSpec.describe AffiliateSalesQuery do
|
||||
let(:yesterday) { Time.zone.yesterday }
|
||||
let(:tomorrow) { Time.zone.tomorrow }
|
||||
|
||||
around do |example|
|
||||
before do
|
||||
# Query dates are interpreted as UTC while the spec runs in
|
||||
# Melbourne time. At noon in Melbourne, the date is the same.
|
||||
# That simplifies the spec.
|
||||
Timecop.travel(Time.zone.today.noon, &example)
|
||||
travel_to(Time.zone.today.noon)
|
||||
end
|
||||
|
||||
it "returns data" do
|
||||
|
||||
13
engines/dfc_provider/spec/services/api_user_spec.rb
Normal file
13
engines/dfc_provider/spec/services/api_user_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../spec_helper"
|
||||
|
||||
RSpec.describe ApiUser do
|
||||
subject(:user) { described_class.new("cqcm-dev") }
|
||||
|
||||
describe "#customers" do
|
||||
it "returns nothing" do
|
||||
expect(user.customers).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,6 +8,23 @@ RSpec.describe AuthorizationControl do
|
||||
let(:user) { create(:oidc_user) }
|
||||
|
||||
describe "with OIDC token" do
|
||||
it "accepts a token from Les Communs" do
|
||||
user.oidc_account.update!(uid: "testdfc@protonmail.com")
|
||||
lc_token = file_fixture("les_communs_access_token.jwt").read
|
||||
|
||||
travel_to(Date.parse("2025-06-13")) do
|
||||
expect(auth(oidc_token: lc_token).user).to eq user
|
||||
end
|
||||
end
|
||||
|
||||
it "accepts a token from Startin'Blox" do
|
||||
sib_token = file_fixture("startinblox_access_token.jwt").read
|
||||
|
||||
travel_to(Date.parse("2025-06-13")) do
|
||||
expect(auth(oidc_token: sib_token).user.id).to eq "cqcm-dev"
|
||||
end
|
||||
end
|
||||
|
||||
it "finds the right user" do
|
||||
create(:oidc_user) # another user
|
||||
token = allow_token_for(email: user.email)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authenticate via Authoriztion token
|
||||
RSpec.shared_context "authenticated as platform" do
|
||||
let(:Authorization) {
|
||||
"Bearer #{file_fixture('startinblox_access_token.jwt').read}"
|
||||
}
|
||||
|
||||
before do
|
||||
# Once upon a time when the access token hadn't expired yet...
|
||||
travel_to(Date.parse("2025-06-13"))
|
||||
|
||||
# Reset any login via session cookie.
|
||||
login_as nil
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
||||
s.authors = ["developers@ofn"]
|
||||
s.summary = "Order Management domain of the OFN solution."
|
||||
|
||||
s.required_ruby_version = File.read(File.expand_path("../../.ruby-version", __dir__)).chomp
|
||||
s.required_ruby_version = ">= 1.0.0" # rubocop:disable Gemspec/RequiredRubyVersion
|
||||
|
||||
s.files = Dir["{app,config,db,lib}/**/*"] + ["LICENSE.txt", "Rakefile", "README.rdoc"]
|
||||
s.metadata['rubygems_mfa_required'] = 'true'
|
||||
|
||||
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
||||
s.authors = ["developers@ofn"]
|
||||
s.summary = "Web domain of the OFN solution."
|
||||
|
||||
s.required_ruby_version = File.read(File.expand_path("../../.ruby-version", __dir__)).chomp
|
||||
s.required_ruby_version = ">= 1.0.0" # rubocop:disable Gemspec/RequiredRubyVersion
|
||||
|
||||
s.files = Dir["{app,config,db,lib}/**/*"] + ["LICENSE.txt", "Rakefile", "README.rdoc"]
|
||||
s.metadata['rubygems_mfa_required'] = 'true'
|
||||
|
||||
@@ -64,6 +64,9 @@ module OpenFoodNetwork
|
||||
"hub_address" => <<~DESC,
|
||||
Show the hub's address as shipping address on pickup orders.
|
||||
DESC
|
||||
"cqcm-dev" => <<~DESC,
|
||||
Show DFC Permissions interface to share data with CQCM dev platform.
|
||||
DESC
|
||||
}.merge(conditional_features).freeze;
|
||||
|
||||
# Features you would like to be enabled to start with.
|
||||
|
||||
@@ -113,7 +113,9 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def managed_enterprises
|
||||
@managed_enterprises ||= Enterprise.managed_by(@user)
|
||||
return Enterprise.all if admin?
|
||||
|
||||
@user.enterprises
|
||||
end
|
||||
|
||||
def coordinated_order_cycles
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace :simplecov do
|
||||
desc "Collates all result sets produced during parallel test runs"
|
||||
task :collate_results, # rubocop:disable Rails/RakeEnvironment doesn't need the full env
|
||||
[:path_to_results, :coverage_dir] do |_t, args|
|
||||
# This code is covered by a spec but trying to measure the code coverage of
|
||||
# the spec breaks the coverage report. We need to ignore it to avoid warnings.
|
||||
# :nocov:
|
||||
require "simplecov"
|
||||
require "undercover/simplecov_formatter"
|
||||
|
||||
@@ -19,5 +22,6 @@ namespace :simplecov do
|
||||
formatter(SimpleCov::Formatter::Undercover)
|
||||
coverage_dir(output_path)
|
||||
end
|
||||
# :nocov:
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"pretty-quick": "pretty-quick"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.7.3",
|
||||
"@floating-ui/dom": "^1.7.4",
|
||||
"@hotwired/stimulus": "^3.2",
|
||||
"@hotwired/turbo": "^8.0.13",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
|
||||
@@ -68,9 +68,6 @@ InvisibleCaptcha.timestamp_enabled = false
|
||||
InvisibleCaptcha.spinner_enabled = false
|
||||
|
||||
RSpec.configure do |config|
|
||||
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
||||
config.fixture_path = Rails.root.join('spec/fixtures').to_s
|
||||
|
||||
# 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.
|
||||
@@ -260,6 +257,7 @@ RSpec.configure do |config|
|
||||
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
|
||||
|
||||
@@ -142,7 +142,7 @@ RSpec.describe Admin::OrderCyclesController do
|
||||
select: {
|
||||
enterprise_fees: 3,
|
||||
enterprise_groups: 1,
|
||||
enterprises: 22,
|
||||
enterprises: 19,
|
||||
exchanges: 7,
|
||||
order_cycles: 6,
|
||||
proxy_orders: 1,
|
||||
|
||||
@@ -625,14 +625,30 @@ RSpec.describe CheckoutController do
|
||||
expect(flash[:error]).to match "There was an error while trying to redeem your voucher"
|
||||
end
|
||||
end
|
||||
|
||||
context "when an external payment gateway is used" do
|
||||
before do
|
||||
expect(payment_method).to receive(:external_gateway?) { true }
|
||||
expect(payment_method).to receive(:external_payment_url) { "https://example.com/pay" }
|
||||
mock_payment_method_fetcher(payment_method)
|
||||
end
|
||||
|
||||
it "redeems the voucher and redirect to the payment gateway's URL" do
|
||||
expect(vine_voucher_redeemer).to receive(:redeem).and_return(true)
|
||||
|
||||
put(:update, params:)
|
||||
|
||||
expect(response.body).to match("https://example.com/pay").and match("redirect")
|
||||
expect(order.reload.state).to eq "confirmation"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when an external payment gateway is used" do
|
||||
before do
|
||||
expect(Checkout::PaymentMethodFetcher).
|
||||
to receive_message_chain(:new, :call) { payment_method }
|
||||
expect(payment_method).to receive(:external_gateway?) { true }
|
||||
expect(payment_method).to receive(:external_payment_url) { "https://example.com/pay" }
|
||||
mock_payment_method_fetcher(payment_method)
|
||||
end
|
||||
|
||||
describe "confirming the order" do
|
||||
@@ -693,4 +709,9 @@ RSpec.describe CheckoutController do
|
||||
[{ "url" => "/checkout/details", "operation" => "redirectTo" }].to_json
|
||||
)
|
||||
end
|
||||
|
||||
def mock_payment_method_fetcher(payment_method)
|
||||
payment_method_fetcher = instance_double(Checkout::PaymentMethodFetcher, call: payment_method)
|
||||
expect(Checkout::PaymentMethodFetcher).to receive(:new).and_return(payment_method_fetcher)
|
||||
end
|
||||
end
|
||||
|
||||
1
spec/fixtures/files/les_communs_access_token.jwt
vendored
Normal file
1
spec/fixtures/files/les_communs_access_token.jwt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJKVjg1bVRtUmh1MGtSeGNNb0FGUFl5azJMbS1WTExYV25HOG9HbUxNUkowIn0.eyJleHAiOjE3NDk3ODkyMzYsImlhdCI6MTc0OTc4NzQzNiwiYXV0aF90aW1lIjoxNzQ5Nzg3NDMzLCJqdGkiOiJmM2Q2ZGNmMi1lNGMwLTQyNzItODQzNC00NWFhZDczOTllYzUiLCJpc3MiOiJodHRwczovL2xvZ2luLmxlc2NvbW11bnMub3JnL2F1dGgvcmVhbG1zL2RhdGEtZm9vZC1jb25zb3J0aXVtIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjVmZjNhZjc4LTk0YTItNGI1Yi04ZGFkLWE3YzFkZWE4ODE2YSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImNvb3BjaXJjdWl0cyIsIm5vbmNlIjoiMTZkNmM3OGZkNTcwOWRkMjVkNzNkYzYwMmViNDBiZGYiLCJzZXNzaW9uX3N0YXRlIjoiYmE4Y2M0ZWYtMDJmMC00ZjVmLWFiMWEtMDUyNGRiNGViNzI5IiwiYWxsb3dlZC1vcmlnaW5zIjpbIiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJzaWQiOiJiYThjYzRlZi0wMmYwLTRmNWYtYWIxYS0wNTI0ZGI0ZWI3MjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJ0ZXN0IGRmYyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20iLCJsb2NhbGUiOiJlbiIsImdpdmVuX25hbWUiOiJ0ZXN0IiwiZmFtaWx5X25hbWUiOiJkZmMiLCJlbWFpbCI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20ifQ.NTuzVgy8es0GHKqGPmHgVaV8Kzz9uuFAiWgixLubfh8fl2OccFDxccNKyiTczj4wHD4jItdHPIxz-x9ZX2Ao7lwMFLno69KWjAK2eLpA8Fnu4stftlswfHqD0W-wzG0Cx24H6jXZbsM5tm1FYgQYwrlZ-uqwQOabN_cA_cTrwHmMTNVCjwCisScq7Np7r1me-4YEABmTGR362_eJVn2bRppG_7s12yjEAH_mcTyALXqlXNaF0XihDCxjmK8ybJiGy6_QwhEJci6EWqJ-w9H6ckheq94xTM5WpanQ4-ZHEm2TZlq2MOfMBVsknhwnGI0b-GbtSJrs7urWsopQyWSuhw
|
||||
1
spec/fixtures/files/startinblox_access_token.jwt
vendored
Normal file
1
spec/fixtures/files/startinblox_access_token.jwt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRRlJES1daQ2hzMllQYnRqYl9yQUtwQzNzMFo0T2FCMEtFQ056NnlxWHQ0In0.eyJleHAiOjE3NDk3ODk3MDcsImlhdCI6MTc0OTc4OTQwNywianRpIjoiOWE4ODU4NDAtODhjNy00OTliLWIyOGUtMmE5ZmViM2EyNmU0IiwiaXNzIjoiaHR0cHM6Ly9rYy5jcWNtLnN0YXJ0aW5ibG94LmNvbS9yZWFsbXMvc3RhcnRpbmJsb3giLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNWZlM2MyNmMtMjczNi00OGE0LWI2Y2YtYTllM2JjZmNkZjAwIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiaHR0cHM6Ly93YXRlcmxvb3JlZ2lvbmZvb2QuY2EvcG9ydGFsL3Byb2ZpbGUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtc3RhcnRpbmJsb3giXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6IlJlYWRFbnRlcnByaXNlIFJlYWRQcm9kdWN0cyIsImNsaWVudEhvc3QiOiIxNzIuMTguMC4xIiwiY2xpZW50QWRkcmVzcyI6IjE3Mi4xOC4wLjEiLCJjbGllbnRfaWQiOiJodHRwczovL3dhdGVybG9vcmVnaW9uZm9vZC5jYS9wb3J0YWwvcHJvZmlsZSJ9.Ln7wY0_ptRAza7M8w3yXU02TvluH028uaoJ5VHiN9-PnakokzHve7SCuSd1hvVikYAivWFIBRP97vwfpb_DW-d9Afk_XcQqcA0L36ynUIZ69X5uQ2zakEW0kB6pwqd8AL8tlWVUg2PixBXJ6daJcgWNF7RlKXg6wgy4JYL_VxD3VJjST911-z4_TMuQ2OC-3SJNwNv3BspSmUXm7F6y8xGFN7wuCPjU90WIiZ_vxTbVdM0zNtBM0uMJFeFv2_ZzoJIIiNHYLWtD3LrKcXePLSejpo-DPVWR_lGdDdM7BmzOHPKZ9KMaV-oa3lYNYC5shhJOpoB3vHngtdYdv8jq7Cg
|
||||
54131
spec/fixtures/vcr_cassettes/DFC_Permissions/can_share_data_with_another_platform.yml
vendored
Normal file
54131
spec/fixtures/vcr_cassettes/DFC_Permissions/can_share_data_with_another_platform.yml
vendored
Normal file
File diff suppressed because one or more lines are too long
157
spec/fixtures/vcr_cassettes/DFC_Permissions/is_not_visible_when_no_platform_is_enabled.yml
vendored
Normal file
157
spec/fixtures/vcr_cassettes/DFC_Permissions/is_not_visible_when_no_platform_is_enabled.yml
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: http://clients2.google.com/time/1/current?cup2hreq=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&cup2key=9:xgNLAoOqba-lEGVM6YOjj7pIq8HoxNPpUp9EWljo6sc
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: ''
|
||||
headers:
|
||||
Proxy-Connection:
|
||||
- keep-alive
|
||||
Pragma:
|
||||
- no-cache
|
||||
Cache-Control:
|
||||
- no-cache
|
||||
User-Agent:
|
||||
- Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/138.0.0.0
|
||||
Safari/537.36
|
||||
Accept-Encoding:
|
||||
- ''
|
||||
Connection:
|
||||
- close
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Cup-Server-Proof:
|
||||
- 30460221009b0f46a5511673ea580081ce4e919d37745231029ab508ecbda5d9ee8e4c6a22022100e20234b939fd368c664f74624bab1cb2cefb9e966650a6a13f1b7fdf7a0c8549:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
Cache-Control:
|
||||
- no-cache, no-store, max-age=0, must-revalidate
|
||||
Pragma:
|
||||
- no-cache
|
||||
Expires:
|
||||
- Mon, 01 Jan 1990 00:00:00 GMT
|
||||
Date:
|
||||
- Tue, 29 Jul 2025 05:06:27 GMT
|
||||
Content-Disposition:
|
||||
- attachment; filename="json.txt"; filename*=UTF-8''json.txt
|
||||
Cross-Origin-Resource-Policy:
|
||||
- same-site
|
||||
Cross-Origin-Opener-Policy:
|
||||
- same-origin
|
||||
Server:
|
||||
- ESF
|
||||
X-Xss-Protection:
|
||||
- '0'
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
Accept-Ranges:
|
||||
- none
|
||||
Vary:
|
||||
- Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site,Accept-Encoding
|
||||
Connection:
|
||||
- close
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: |-
|
||||
)]}'
|
||||
{"current_time_millis":1753765587344,"server_nonce":4.706974222338465E-226}
|
||||
recorded_at: Tue, 29 Jul 2025 05:06:27 GMT
|
||||
- request:
|
||||
method: post
|
||||
uri: https://accounts.google.com/ListAccounts?gpsia=1&json=standard&source=ChromiumBrowser
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: " "
|
||||
headers:
|
||||
Connection:
|
||||
- close
|
||||
Content-Length:
|
||||
- '1'
|
||||
Origin:
|
||||
- https://www.google.com
|
||||
Content-Type:
|
||||
- application/x-www-form-urlencoded
|
||||
Sec-Fetch-Site:
|
||||
- none
|
||||
Sec-Fetch-Mode:
|
||||
- no-cors
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
User-Agent:
|
||||
- Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/138.0.0.0
|
||||
Safari/537.36
|
||||
Accept-Encoding:
|
||||
- ''
|
||||
Accept-Language:
|
||||
- en-US,en;q=0.9
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Access-Control-Allow-Origin:
|
||||
- https://www.google.com
|
||||
Access-Control-Allow-Credentials:
|
||||
- 'true'
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
Cache-Control:
|
||||
- no-cache, no-store, max-age=0, must-revalidate
|
||||
Pragma:
|
||||
- no-cache
|
||||
Expires:
|
||||
- Mon, 01 Jan 1990 00:00:00 GMT
|
||||
Date:
|
||||
- Tue, 29 Jul 2025 05:06:28 GMT
|
||||
Strict-Transport-Security:
|
||||
- max-age=31536000; includeSubDomains
|
||||
Cross-Origin-Opener-Policy:
|
||||
- same-origin
|
||||
Accept-Ch:
|
||||
- Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List,
|
||||
Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factors, Sec-CH-UA-Platform,
|
||||
Sec-CH-UA-Platform-Version
|
||||
Content-Security-Policy:
|
||||
- require-trusted-types-for 'script';report-uri /_/IdentityListAccountsHttp/cspreport
|
||||
- script-src 'report-sample' 'nonce-k53NvqeKlfwH5MjGJUn81Q' 'unsafe-inline';object-src
|
||||
'none';base-uri 'self';report-uri /_/IdentityListAccountsHttp/cspreport;worker-src
|
||||
'self'
|
||||
- 'script-src ''unsafe-inline'' ''unsafe-eval'' blob: data: ''self'' https://apis.google.com
|
||||
https://ssl.gstatic.com https://www.google.com https://www.googletagmanager.com
|
||||
https://www.gstatic.com https://www.google-analytics.com;report-uri /_/IdentityListAccountsHttp/cspreport/allowlist'
|
||||
- 'script-src ''unsafe-inline'' ''unsafe-eval'' blob: data:;report-uri /_/IdentityListAccountsHttp/cspreport/fine-allowlist'
|
||||
Permissions-Policy:
|
||||
- ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,
|
||||
ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factors=*, ch-ua-platform=*, ch-ua-platform-version=*
|
||||
Reporting-Endpoints:
|
||||
- default="/_/IdentityListAccountsHttp/web-reports?context=eJzjEtHikmJw05BiOHxtB5Meyy0mIyAW4uG4snbhETaBDxc-TmNS0k3KL4zPTEnNK8ksqczJLC5JTE7OL80rKS5OLSpLLYo3MjAyNTA3MtAzsIgvMAAAgSYcZg"
|
||||
Server:
|
||||
- ESF
|
||||
X-Xss-Protection:
|
||||
- '0'
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Accept-Ranges:
|
||||
- none
|
||||
Vary:
|
||||
- Origin,Accept-Encoding
|
||||
Connection:
|
||||
- close
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '["gaia.l.a.r",[]]'
|
||||
recorded_at: Tue, 29 Jul 2025 05:06:28 GMT
|
||||
recorded_with: VCR 6.2.0
|
||||
@@ -38,5 +38,22 @@ RSpec.describe Admin::EnterprisesHelper do
|
||||
expect(visible_items.pluck(:name)).to include "inventory_settings"
|
||||
end
|
||||
end
|
||||
|
||||
it "hides Connected Apps by default" do
|
||||
user.enterprises << enterprise
|
||||
expect(visible_items.pluck(:name)).not_to include "connected_apps"
|
||||
end
|
||||
|
||||
it "shows Connected Apps for specific user" do
|
||||
user.enterprises << enterprise
|
||||
Flipper.enable("cqcm-dev", user)
|
||||
expect(visible_items.pluck(:name)).to include "connected_apps"
|
||||
end
|
||||
end
|
||||
|
||||
describe '#enterprise_sells_options' do
|
||||
it 'returns sells options with translations' do
|
||||
expect(helper.enterprise_sells_options.map(&:first)).to eq %w[unspecified none own any]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
35
spec/javascripts/stimulus/flatpickr_controller_test.js
Normal file
35
spec/javascripts/stimulus/flatpickr_controller_test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { Application } from "stimulus";
|
||||
import FlatpickrController from "../../../app/webpacker/controllers/flatpickr_controller.js";
|
||||
|
||||
describe("FlatpickrController", () => {
|
||||
beforeAll(() => {
|
||||
const application = Application.start();
|
||||
application.register("flatpickr", FlatpickrController);
|
||||
});
|
||||
|
||||
describe("#importFlatpickrLocale", () => {
|
||||
describe("returns null to trigger flatpickr fallback to english", () => {
|
||||
test.each([
|
||||
["when no base_locale is set", {}],
|
||||
["when base_locale doesn't match a Flatpickr locale", { base_locale: "invalid-locale" }],
|
||||
["when base_locale is 'en'", { base_locale: "en" }],
|
||||
])("%s", async (_description, i18n) => {
|
||||
const controller = new FlatpickrController();
|
||||
const locale = await controller.importFlatpickrLocale(i18n.base_locale);
|
||||
expect(locale).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
it("returns locale object for a supported locale (fr)", async () => {
|
||||
const controller = new FlatpickrController();
|
||||
const locale = await controller.importFlatpickrLocale("fr");
|
||||
expect(locale).toBeInstanceOf(Object);
|
||||
expect(locale).toHaveProperty("weekAbbreviation");
|
||||
expect(locale.weekAbbreviation).toBe("Sem");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,8 +8,8 @@ RSpec.describe HeartbeatJob do
|
||||
|
||||
before { Spree::Config.last_job_queue_heartbeat_at = nil }
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze(run_time) { example.run }
|
||||
before do
|
||||
travel_to(run_time)
|
||||
end
|
||||
|
||||
it "updates the last_job_queue_heartbeat_at config var" do
|
||||
|
||||
@@ -7,8 +7,8 @@ RSpec.describe OpenOrderCycleJob do
|
||||
let(:order_cycle) { create(:simple_order_cycle, orders_open_at: now) }
|
||||
subject { OpenOrderCycleJob.perform_now(order_cycle.id) }
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze(now) { example.run }
|
||||
before do
|
||||
freeze_time
|
||||
end
|
||||
|
||||
it "marks as open" do
|
||||
|
||||
@@ -23,7 +23,7 @@ RSpec.describe WebhookDeliveryJob do
|
||||
end
|
||||
|
||||
it "delivers a payload" do
|
||||
Timecop.freeze do
|
||||
freeze_time do
|
||||
expected_body = {
|
||||
id: /.+/,
|
||||
at: at.to_s,
|
||||
|
||||
@@ -80,7 +80,7 @@ require "spec_helper"
|
||||
# end
|
||||
|
||||
# it "generates filename correctly" do
|
||||
# Timecop.freeze(Time.zone.local(2018, 10, 9, 7, 30, 0)) do
|
||||
# travel_to(Time.zone.local(2018, 10, 9, 7, 30, 0)) do
|
||||
# filename = renderer.__send__(:filename)
|
||||
# expect(filename).to eq("enterprise_fee_summary_20181009.csv")
|
||||
# end
|
||||
|
||||
@@ -13,7 +13,7 @@ module Reporting
|
||||
describe "option defaults" do
|
||||
let(:report) { Base.new user }
|
||||
|
||||
around { |example| Timecop.travel(Time.zone.local(2015, 5, 5, 14, 0, 0)) { example.run } }
|
||||
before { travel_to(Time.zone.local(2015, 5, 5, 14, 0, 0)) }
|
||||
|
||||
it "uses defaults when blank params are passed" do
|
||||
expect(report.params).to eq(invoice_date: Date.civil(2015, 5, 5),
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe 'truncate_data.rake' do
|
||||
include_context "rake"
|
||||
|
||||
describe ':truncate' do
|
||||
context 'when months_to_keep is specified' do
|
||||
it 'truncates order cycles closed earlier than months_to_keep months ago' do
|
||||
Rake.application.rake_require 'tasks/data/truncate_data'
|
||||
Rake::Task.define_task(:environment)
|
||||
|
||||
highline = instance_double(HighLine, agree: true)
|
||||
allow(HighLine).to receive(:new).and_return(highline)
|
||||
|
||||
@@ -27,7 +25,7 @@ RSpec.describe 'truncate_data.rake' do
|
||||
create(:order, order_cycle: recent_order_cycle)
|
||||
|
||||
months_to_keep = 6
|
||||
Rake.application.invoke_task "ofn:data:truncate[#{months_to_keep}]"
|
||||
invoke_task "ofn:data:truncate[#{months_to_keep}]"
|
||||
|
||||
expect(OrderCycle.all).to contain_exactly(recent_order_cycle)
|
||||
end
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe 'enterprises.rake' do
|
||||
before(:all) do
|
||||
Rake.application.rake_require("tasks/enterprises")
|
||||
Rake::Task.define_task(:environment)
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
describe ':remove_enterprise' do
|
||||
context 'when the enterprises exists' do
|
||||
@@ -15,7 +11,7 @@ RSpec.describe 'enterprises.rake' do
|
||||
enterprise = create(:enterprise)
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task "ofn:remove_enterprise[#{enterprise.id}]"
|
||||
invoke_task "ofn:remove_enterprise[#{enterprise.id}]"
|
||||
}.to change { Enterprise.count }.by(-1)
|
||||
end
|
||||
end
|
||||
@@ -32,7 +28,7 @@ RSpec.describe 'enterprises.rake' do
|
||||
enterprise_diff.connected_apps.create
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task(
|
||||
invoke_task(
|
||||
"ofn:enterprises:activate_connected_app_type[affiliate_sales_data]"
|
||||
)
|
||||
}.to change { ConnectedApps::AffiliateSalesData.count }.by(1)
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe 'ofn:import:product_images' do
|
||||
before(:all) do
|
||||
Rake.application.rake_require("tasks/import_product_images")
|
||||
Rake::Task.define_task(:environment)
|
||||
end
|
||||
|
||||
before do
|
||||
Rake::Task['ofn:import:product_images'].reenable
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
describe 'task' do
|
||||
context "filename is blank" do
|
||||
it 'raises an error' do
|
||||
expect {
|
||||
Rake.application.invoke_task('ofn:import:product_images')
|
||||
invoke_task('ofn:import:product_images')
|
||||
}.to raise_error(RuntimeError,
|
||||
'Filename required')
|
||||
end
|
||||
@@ -28,7 +20,7 @@ RSpec.describe 'ofn:import:product_images' do
|
||||
allow(CSV).to receive(:read).and_return(CSV::Table.new([]))
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task('ofn:import:product_images["path/to/csv/file.csv"]')
|
||||
invoke_task('ofn:import:product_images["path/to/csv/file.csv"]')
|
||||
}.to raise_error(RuntimeError, 'CSV columns reqired: ["producer", "name", "image_url"]')
|
||||
end
|
||||
end
|
||||
@@ -74,7 +66,7 @@ RSpec.describe 'ofn:import:product_images' do
|
||||
OUTPUT
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task('ofn:import:product_images["path/to/csv/file.csv"]')
|
||||
invoke_task('ofn:import:product_images["path/to/csv/file.csv"]')
|
||||
}.to output(expected_output).to_stdout
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe "reset.rake" do
|
||||
before(:all) do
|
||||
Rake.application.rake_require("tasks/reset")
|
||||
Rake::Task.define_task(:environment)
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
it "clears job queues" do
|
||||
job_class = Class.new do
|
||||
@@ -18,7 +14,7 @@ RSpec.describe "reset.rake" do
|
||||
queue = Sidekiq::Queue.all.first # rubocop:disable Rails/RedundantActiveRecordAllMethod
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task "ofn:reset_sidekiq"
|
||||
invoke_task "ofn:reset_sidekiq"
|
||||
}.to change {
|
||||
queue.count
|
||||
}.to(0)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe 'sample_data.rake' do
|
||||
before(:all) do
|
||||
Rake.application.rake_require 'tasks/sample_data'
|
||||
Rake::Task.define_task(:environment)
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
before do
|
||||
# Create seed data required by the sample data.
|
||||
@@ -16,7 +12,7 @@ RSpec.describe 'sample_data.rake' do
|
||||
end
|
||||
|
||||
it "creates some sample data to play with" do
|
||||
Rake.application.invoke_task "ofn:sample_data"
|
||||
invoke_task "ofn:sample_data"
|
||||
|
||||
expect(EnterpriseGroup.count).to eq 1
|
||||
expect(Customer.count).to eq 2
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe "simplecov.rake" do
|
||||
before(:all) do
|
||||
Rake.application.rake_require("tasks/simplecov")
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
describe "simplecov:collate_results" do
|
||||
context "when there are reports to merge" do
|
||||
@@ -16,10 +13,16 @@ RSpec.describe "simplecov.rake" do
|
||||
Dir.mktmpdir do |tmp_dir|
|
||||
output_dir = File.join(tmp_dir, "output")
|
||||
|
||||
task_name = "simplecov:collate_results[#{input_dir},#{output_dir}]"
|
||||
|
||||
expect {
|
||||
Rake.application.invoke_task(
|
||||
"simplecov:collate_results[#{input_dir},#{output_dir}]"
|
||||
)
|
||||
if ENV["COVERAGE"]
|
||||
# Start task in a new process to not mess with our coverage report.
|
||||
`bundle exec rake #{task_name}`
|
||||
else
|
||||
# Use the quick standard invocation in dev.
|
||||
invoke_task(task_name)
|
||||
end
|
||||
}.to change { Dir.exist?(output_dir) }.
|
||||
from(false).
|
||||
to(true).
|
||||
|
||||
@@ -4,18 +4,14 @@ require 'spec_helper'
|
||||
require 'rake'
|
||||
|
||||
RSpec.describe 'users.rake' do
|
||||
before do
|
||||
Rake.application.rake_require 'tasks/users'
|
||||
Rake::Task.define_task(:environment)
|
||||
Rake::Task['ofn:remove_enterprise_limit'].reenable
|
||||
end
|
||||
include_context "rake"
|
||||
|
||||
describe ':remove_enterprise_limit' do
|
||||
context 'when the user exists' do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'sets the enterprise_limit to the maximum integer' do
|
||||
Rake.application.invoke_task "ofn:remove_enterprise_limit[#{user.id}]"
|
||||
invoke_task "ofn:remove_enterprise_limit[#{user.id}]"
|
||||
|
||||
expect(user.reload.enterprise_limit).to eq(2_147_483_647)
|
||||
end
|
||||
@@ -24,7 +20,7 @@ RSpec.describe 'users.rake' do
|
||||
context 'when the user does not exist' do
|
||||
it 'raises' do
|
||||
expect {
|
||||
Rake.application.invoke_task "ofn:remove_enterprise_limit[123]"
|
||||
invoke_task "ofn:remove_enterprise_limit[123]"
|
||||
}.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
15
spec/models/dfc_permission_spec.rb
Normal file
15
spec/models/dfc_permission_spec.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe DfcPermission do
|
||||
it { is_expected.to belong_to :user }
|
||||
it { is_expected.to belong_to :enterprise }
|
||||
it { is_expected.to validate_presence_of :grantee }
|
||||
it { is_expected.to validate_presence_of :scope }
|
||||
it {
|
||||
is_expected.to validate_inclusion_of(:scope)
|
||||
.in_array(%w[ReadEnterprise ReadProducts ReadOrders])
|
||||
.in_array(%w[WriteEnterprise WriteProducts WriteOrders])
|
||||
}
|
||||
end
|
||||
@@ -149,6 +149,6 @@ RSpec.describe Enterprise do
|
||||
end
|
||||
|
||||
def later(&)
|
||||
Timecop.travel(1.day.from_now, &)
|
||||
travel(1.day, &)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -304,7 +304,7 @@ RSpec.describe OrderCycle do
|
||||
let(:oc) { build_stubbed(:simple_order_cycle) }
|
||||
|
||||
it "reports status when an order cycle is upcoming" do
|
||||
Timecop.freeze(oc.orders_open_at - 1.second) do
|
||||
travel_to(oc.orders_open_at - 1.second) do
|
||||
expect(oc).not_to be_undated
|
||||
expect(oc).to be_dated
|
||||
expect(oc).to be_upcoming
|
||||
@@ -322,7 +322,7 @@ RSpec.describe OrderCycle do
|
||||
end
|
||||
|
||||
it "reports status when an order cycle has closed" do
|
||||
Timecop.freeze(oc.orders_close_at + 1.second) do
|
||||
travel_to(oc.orders_close_at + 1.second) do
|
||||
expect(oc).not_to be_undated
|
||||
expect(oc).to be_dated
|
||||
expect(oc).not_to be_upcoming
|
||||
|
||||
@@ -7,10 +7,8 @@ RSpec.describe ProxyOrder do
|
||||
let(:order_cycle) { create(:simple_order_cycle) }
|
||||
let(:subscription) { create(:subscription) }
|
||||
|
||||
around do |example|
|
||||
# We are testing if database columns have been set to "now".
|
||||
Timecop.freeze(Time.zone.now) { example.run }
|
||||
end
|
||||
# We are testing if database columns have been set to "now".
|
||||
before { freeze_time }
|
||||
|
||||
context "when the order cycle is not yet closed" do
|
||||
let(:proxy_order) {
|
||||
@@ -94,9 +92,7 @@ RSpec.describe ProxyOrder do
|
||||
let(:proxy_order) { create(:proxy_order, order:, canceled_at: Time.zone.now) }
|
||||
let(:order_cycle) { proxy_order.order_cycle }
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze(Time.zone.now) { example.run }
|
||||
end
|
||||
before { freeze_time }
|
||||
|
||||
context "when the order cycle is not yet closed" do
|
||||
before { order_cycle.update(orders_open_at: 1.day.ago, orders_close_at: 3.days.from_now) }
|
||||
|
||||
@@ -40,7 +40,7 @@ RSpec.describe TermsOfServiceFile do
|
||||
let(:subject) { TermsOfServiceFile.updated_at }
|
||||
|
||||
it "gives the most conservative time if not known" do
|
||||
Timecop.freeze do
|
||||
freeze_time do
|
||||
expect(subject).to eq Time.zone.now
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,7 +21,7 @@ RSpec.describe Vine::JwtService do
|
||||
|
||||
it "includes issuing time" do
|
||||
generate_time = Time.zone.now
|
||||
Timecop.freeze(generate_time) do
|
||||
travel_to(generate_time) do
|
||||
token = subject.generate_token
|
||||
|
||||
payload = decode(token, vine_secret)
|
||||
@@ -32,7 +32,7 @@ RSpec.describe Vine::JwtService do
|
||||
|
||||
it "includes expirations time" do
|
||||
generate_time = Time.zone.now
|
||||
Timecop.freeze(generate_time) do
|
||||
travel_to(generate_time) do
|
||||
token = subject.generate_token
|
||||
|
||||
payload = decode(token, vine_secret)
|
||||
|
||||
35
spec/support/shared_contexts/rake.rb
Normal file
35
spec/support/shared_contexts/rake.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Let this context take care of Rake testing gotchas.
|
||||
#
|
||||
# ```rb
|
||||
# RSpec.describe "my_task.rake" do
|
||||
# include_context "rake"
|
||||
# # ..
|
||||
# ```
|
||||
#
|
||||
shared_context "rake" do
|
||||
before(:all) do
|
||||
# Make sure that Rake tasks are only loaded once.
|
||||
# Otherwise we lose code coverage data.
|
||||
if Rake::Task.tasks.empty?
|
||||
Openfoodnetwork::Application.load_tasks
|
||||
Rake::Task.define_task(:environment)
|
||||
end
|
||||
end
|
||||
|
||||
# Use the same task string as you would on the command line.
|
||||
#
|
||||
# ```rb
|
||||
# invoke_task "example:task[arg1,arg2]"
|
||||
# ```
|
||||
#
|
||||
# This helper makes sure that you can run a task multiple times,
|
||||
# even within the same test example.
|
||||
def invoke_task(task_string)
|
||||
Rake.application.invoke_task(task_string)
|
||||
ensure
|
||||
name, _args = Rake.application.parse_task_string(task_string)
|
||||
Rake::Task[name].reenable
|
||||
end
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Timecop.safe_mode = true
|
||||
88
spec/system/admin/enterprises/dfc_permissions_spec.rb
Normal file
88
spec/system/admin/enterprises/dfc_permissions_spec.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "system_helper"
|
||||
|
||||
RSpec.describe "DFC Permissions", feature: "cqcm-dev", vcr: true do
|
||||
let(:enterprise) { create(:enterprise) }
|
||||
|
||||
before do
|
||||
login_as enterprise.owner
|
||||
end
|
||||
|
||||
it "is not visible when no platform is enabled" do
|
||||
Flipper.disable("cqcm-dev")
|
||||
visit edit_admin_enterprise_path(enterprise)
|
||||
expect(page).not_to have_content "CONNECTED APPS"
|
||||
end
|
||||
|
||||
it "can share data with another platform" do
|
||||
visit edit_admin_enterprise_path(enterprise)
|
||||
|
||||
scroll_to :bottom
|
||||
click_link "Connected apps"
|
||||
|
||||
# The component displays something and then replaces it with the real
|
||||
# list. That leads to a race condition and we have to just wait until
|
||||
# the component is loaded. :-(
|
||||
wait_for_component_loaded
|
||||
|
||||
within(platform_list("without-permissions")) do
|
||||
expect(page).to have_content "Proxy Dev Portal"
|
||||
|
||||
# NotSupportedError: Failed to execute 'evaluate' on 'Document':
|
||||
# The node provided is '#document-fragment', which is not a valid context node type.
|
||||
#
|
||||
# click_on "Agree and share"
|
||||
|
||||
# This hack works
|
||||
find("button", text: "Agree and share").native.trigger("click")
|
||||
end
|
||||
|
||||
within_platform_list("approved") do
|
||||
expect(page).to have_content "Proxy Dev Portal"
|
||||
find("button", text: "Stop sharing").native.trigger("click")
|
||||
end
|
||||
|
||||
within_platform_list("without-permissions") do
|
||||
expect(page).to have_content "Proxy Dev Portal"
|
||||
find("button", text: "Agree and share").native.trigger("click")
|
||||
end
|
||||
|
||||
within_platform_list("approved") do
|
||||
expect(page).to have_content "Proxy Dev Portal"
|
||||
end
|
||||
end
|
||||
|
||||
def wait_for_component_loaded
|
||||
retry_expectations do
|
||||
within(page.find('solid-permissioning').shadow_root) do
|
||||
expect(page).to have_content "APPROVED PLATFORMS"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def within_platform_list(variant, &block)
|
||||
retry_expectations(on: Ferrum::JavaScriptError) do
|
||||
within(platform_list(variant), &block)
|
||||
end
|
||||
end
|
||||
|
||||
# Handy helper adopted from CERES Fair Food and modified.
|
||||
# We may want to share this but don't have a need for it now.
|
||||
def retry_expectations(on: RSpec::Expectations::ExpectationNotMetError)
|
||||
start = Time.now.utc
|
||||
finish = start + Capybara.default_max_wait_time
|
||||
|
||||
yield
|
||||
rescue on
|
||||
raise if Time.now.utc > finish
|
||||
|
||||
sleep 0.1
|
||||
retry
|
||||
end
|
||||
|
||||
def platform_list(variant)
|
||||
page.find('solid-permissioning').shadow_root
|
||||
.find("platform-block[variant='#{variant}']").shadow_root
|
||||
end
|
||||
end
|
||||
@@ -34,7 +34,7 @@ RSpec.describe "Uploading Terms and Conditions PDF" do
|
||||
attach_file "enterprise[terms_and_conditions]", original_terms, make_visible: true
|
||||
|
||||
time = Time.zone.local(2002, 4, 13, 0, 0, 0)
|
||||
Timecop.freeze(run_time = time) do
|
||||
travel_to(run_time = time) do
|
||||
click_button "Update"
|
||||
expect(distributor.reload.terms_and_conditions_blob.created_at).to eq run_time
|
||||
end
|
||||
|
||||
@@ -73,10 +73,24 @@ RSpec.describe '
|
||||
select2_select "Missing", from: "payment_method_preferred_enterprise_id"
|
||||
expect(page).to have_selector "#stripe-account-status .alert-box.error",
|
||||
text: 'No Stripe account exists for this enterprise.'
|
||||
connect_one = 'Connect One'
|
||||
expect(page).to have_link connect_one,
|
||||
href: edit_admin_enterprise_path(missing_account_enterprise,
|
||||
anchor: "/payment_methods")
|
||||
click_link 'Connect One' # opens in new tab
|
||||
|
||||
new_window = windows.last
|
||||
page.within_window new_window do
|
||||
expect(page).to have_content "Settings: Missing"
|
||||
# we should be on the Payment Methods tab already
|
||||
expect(page).to have_content "Use the button to the right to get started."
|
||||
page.find("a", text: "Connect with Stripe").click # it's not a proper link without href
|
||||
|
||||
expect(page).to have_content "connect your Stripe account to the OFN."
|
||||
href = connect_admin_stripe_accounts_path(enterprise_id: missing_account_enterprise)
|
||||
expect(page).to have_link "I Agree", href:
|
||||
|
||||
# Blocked by capybara. probably don't need to test this.
|
||||
# click_link "I Agree"
|
||||
# expect(page).to have_current_path("https://connect.stripe.com/", url: true)
|
||||
end
|
||||
new_window.close
|
||||
|
||||
select2_select "Revoked", from: "payment_method_preferred_enterprise_id"
|
||||
expect(page).to have_selector "#stripe-account-status .alert-box.error",
|
||||
|
||||
@@ -13,10 +13,6 @@ RSpec.describe "Orders And Distributors" do
|
||||
let!(:distributor2) { create(:distributor_enterprise, name: "By Moto") }
|
||||
let!(:completed_at) { Time.zone.now.to_fs(:db) }
|
||||
|
||||
around do |example|
|
||||
Timecop.travel(completed_at) { example.run }
|
||||
end
|
||||
|
||||
let!(:order) {
|
||||
create(:order_ready_to_ship, distributor_id: distributor.id, completed_at:)
|
||||
}
|
||||
@@ -25,6 +21,10 @@ RSpec.describe "Orders And Distributors" do
|
||||
}
|
||||
let(:variant) { order.variants.first }
|
||||
|
||||
before do
|
||||
travel_to(completed_at)
|
||||
end
|
||||
|
||||
context "as an enterprise user" do
|
||||
let(:header) {
|
||||
["Order date", "Order Id", "Customer Name", "Customer Email", "Customer Phone",
|
||||
|
||||
@@ -116,9 +116,10 @@ RSpec.describe "Orders And Fulfillment" do
|
||||
let(:datetime_start1) { 1600.hours.ago } # 1600 hours in the past
|
||||
let(:datetime_start2) { 1800.hours.ago } # 1600 hours in the past
|
||||
let(:datetime_end) { 1400.hours.ago } # 1400 hours in the past
|
||||
|
||||
before do
|
||||
Timecop.travel(completed_at1) { order1.finalize! }
|
||||
Timecop.travel(completed_at2) { order2.finalize! }
|
||||
travel_to(completed_at1) { order1.finalize! }
|
||||
travel_to(completed_at2) { order2.finalize! }
|
||||
end
|
||||
|
||||
it "is precise to time of day, not just date" do
|
||||
|
||||
@@ -6,8 +6,8 @@ RSpec.describe "Packing Reports" do
|
||||
include AuthenticationHelper
|
||||
include WebHelper
|
||||
|
||||
around do |example|
|
||||
Timecop.freeze(Time.zone.now.strftime("%Y-%m-%d 00:00")) { example.run }
|
||||
before do
|
||||
travel_to(Time.zone.now.strftime("%Y-%m-%d 00:00"))
|
||||
end
|
||||
|
||||
let!(:open_datetime) { 1.month.ago.strftime("%Y-%m-%d 00:00") }
|
||||
|
||||
@@ -102,13 +102,13 @@ RSpec.describe '
|
||||
expect(content).to match "<th>\nFirst Name\n</th>"
|
||||
|
||||
# Let's also check the expiry of the emailed link:
|
||||
Timecop.travel(3.days.from_now) do
|
||||
travel(3.days) do
|
||||
content = URI.parse(report_link).read
|
||||
expect(content).to match "<th>\nFirst Name\n</th>"
|
||||
end
|
||||
|
||||
# The link should still expire though:
|
||||
Timecop.travel(3.months.from_now) do
|
||||
travel(3.months) do
|
||||
expect { URI.parse(report_link).read }
|
||||
.to raise_error OpenURI::HTTPError, "404 Not Found"
|
||||
end
|
||||
@@ -625,15 +625,13 @@ RSpec.describe '
|
||||
order1.update_order!
|
||||
order1.update!(email: 'customer@email.com')
|
||||
order1.shipment.update(included_tax_total: 10.06)
|
||||
Timecop.travel(Time.zone.local(2021, 4, 25, 14, 0, 0)) { order1.finalize! }
|
||||
travel_to(Time.zone.local(2021, 4, 25, 14, 0, 0)) { order1.finalize! }
|
||||
order1.reload
|
||||
order1.create_tax_charge!
|
||||
end
|
||||
|
||||
around do |example|
|
||||
Timecop.travel(Time.zone.local(2021, 4, 26, 14, 0, 0)) do
|
||||
example.run
|
||||
end
|
||||
before do
|
||||
travel_to(Time.zone.local(2021, 4, 26, 14, 0, 0))
|
||||
end
|
||||
|
||||
context "summary report" do
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user