diff --git a/.github/workflows/ci-features-admin.yml b/.github/workflows/ci-features-admin.yml index b3315a5f6..870e6942c 100644 --- a/.github/workflows/ci-features-admin.yml +++ b/.github/workflows/ci-features-admin.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-comments.yml b/.github/workflows/ci-features-comments.yml index ec5486d2e..aa14b2078 100644 --- a/.github/workflows/ci-features-comments.yml +++ b/.github/workflows/ci-features-comments.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-conversations.yml b/.github/workflows/ci-features-conversations.yml index 7ce8cd1d6..1548c4ebb 100644 --- a/.github/workflows/ci-features-conversations.yml +++ b/.github/workflows/ci-features-conversations.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-crops.yml b/.github/workflows/ci-features-crops.yml index 752df28a2..182cbe9b6 100644 --- a/.github/workflows/ci-features-crops.yml +++ b/.github/workflows/ci-features-crops.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-gardens.yml b/.github/workflows/ci-features-gardens.yml index 05a7c8265..cc96d742e 100644 --- a/.github/workflows/ci-features-gardens.yml +++ b/.github/workflows/ci-features-gardens.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-harvests.yml b/.github/workflows/ci-features-harvests.yml index 6435017e1..c3047c533 100644 --- a/.github/workflows/ci-features-harvests.yml +++ b/.github/workflows/ci-features-harvests.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-home.yml b/.github/workflows/ci-features-home.yml index 586d1b993..43c72a922 100644 --- a/.github/workflows/ci-features-home.yml +++ b/.github/workflows/ci-features-home.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-members.yml b/.github/workflows/ci-features-members.yml index 17281f688..c542c93e9 100644 --- a/.github/workflows/ci-features-members.yml +++ b/.github/workflows/ci-features-members.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-places.yml b/.github/workflows/ci-features-places.yml new file mode 100644 index 000000000..6a4cd4256 --- /dev/null +++ b/.github/workflows/ci-features-places.yml @@ -0,0 +1,102 @@ +name: CI Features - Admin + +on: [pull_request] + +jobs: + rspec: + runs-on: ubuntu-latest + services: + db: + image: postgres + env: + ## + # The Postgres service fails its docker health check unless you + # specify these environment variables + # + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: growstuff_test + ports: ['5432:5432'] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + APP_DOMAIN_NAME: localhost:3000 + APP_PROTOCOL: http + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test + DEVISE_SECRET_KEY: secret + ELASTIC_SEARCH_VERSION: "7.5.1-amd64" + GROWSTUFF_EMAIL: "noreply@test.growstuff.org" + GROWSTUFF_FLICKR_KEY: secretkey" + GROWSTUFF_FLICKR_SECRET: secretsecret + GROWSTUFF_SITE_NAME: "Growstuff (travis)" + RAILS_ENV: test + RAILS_SECRET_TOKEN: supersecret + + steps: + - name: Checkout this repo + uses: actions/checkout@v5 + + - name: Configure sysctl limits + run: | + sudo swapoff -a + sudo sysctl -w vm.swappiness=1 + sudo sysctl -w fs.file-max=262144 + sudo sysctl -w vm.max_map_count=262144 + + - name: Start Elasticsearch + uses: elastic/elastic-github-actions/elasticsearch@master + with: + stack-version: 7.5.1 + + ## + # Cache Yarn modules + # + # See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details + # + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Setup yarn cache + uses: actions/cache@v4 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install required OS packages + run: | + sudo apt-get -y install libpq-dev google-chrome-stable + + - name: Install NodeJS + uses: actions/setup-node@v4 + with: + node-version: '12' + + - name: Install Ruby (version given by .ruby-version) and Bundler + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Install required JS packages + run: yarn install + + - name: install chrome + run: sudo apt-get install google-chrome-stable + + - name: Prepare database for testing + run: bundle exec rails db:prepare + + - name: precompile assets + run: bundle exec rails assets:precompile + + - name: index into elastic search + run: bundle exec rails search:reindex + + - name: Run rspec (places/) + run: bundle exec rspec spec/features/places/ -fd diff --git a/.github/workflows/ci-features-plantings.yml b/.github/workflows/ci-features-plantings.yml index 72f7e2b62..6a7e50146 100644 --- a/.github/workflows/ci-features-plantings.yml +++ b/.github/workflows/ci-features-plantings.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-posts.yml b/.github/workflows/ci-features-posts.yml new file mode 100644 index 000000000..1353c891f --- /dev/null +++ b/.github/workflows/ci-features-posts.yml @@ -0,0 +1,102 @@ +name: CI Features - Admin + +on: [pull_request] + +jobs: + rspec: + runs-on: ubuntu-latest + services: + db: + image: postgres + env: + ## + # The Postgres service fails its docker health check unless you + # specify these environment variables + # + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: growstuff_test + ports: ['5432:5432'] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + APP_DOMAIN_NAME: localhost:3000 + APP_PROTOCOL: http + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + DATABASE_URL: postgres://postgres:postgres@localhost:5432/growstuff_test + DEVISE_SECRET_KEY: secret + ELASTIC_SEARCH_VERSION: "7.5.1-amd64" + GROWSTUFF_EMAIL: "noreply@test.growstuff.org" + GROWSTUFF_FLICKR_KEY: secretkey" + GROWSTUFF_FLICKR_SECRET: secretsecret + GROWSTUFF_SITE_NAME: "Growstuff (travis)" + RAILS_ENV: test + RAILS_SECRET_TOKEN: supersecret + + steps: + - name: Checkout this repo + uses: actions/checkout@v5 + + - name: Configure sysctl limits + run: | + sudo swapoff -a + sudo sysctl -w vm.swappiness=1 + sudo sysctl -w fs.file-max=262144 + sudo sysctl -w vm.max_map_count=262144 + + - name: Start Elasticsearch + uses: elastic/elastic-github-actions/elasticsearch@master + with: + stack-version: 7.5.1 + + ## + # Cache Yarn modules + # + # See https://github.com/actions/cache/blob/master/examples.md#node---yarn for details + # + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + - name: Setup yarn cache + uses: actions/cache@v4 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install required OS packages + run: | + sudo apt-get -y install libpq-dev google-chrome-stable + + - name: Install NodeJS + uses: actions/setup-node@v4 + with: + node-version: '12' + + - name: Install Ruby (version given by .ruby-version) and Bundler + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Install required JS packages + run: yarn install + + - name: install chrome + run: sudo apt-get install google-chrome-stable + + - name: Prepare database for testing + run: bundle exec rails db:prepare + + - name: precompile assets + run: bundle exec rails assets:precompile + + - name: index into elastic search + run: bundle exec rails search:reindex + + - name: Run rspec (posts/) + run: bundle exec rspec spec/features/posts/ -fd diff --git a/.github/workflows/ci-features-seeds.yml b/.github/workflows/ci-features-seeds.yml index 85dc5d4be..41bbecbf2 100644 --- a/.github/workflows/ci-features-seeds.yml +++ b/.github/workflows/ci-features-seeds.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features-timeline.yml b/.github/workflows/ci-features-timeline.yml index fe390d7de..3560dbd81 100644 --- a/.github/workflows/ci-features-timeline.yml +++ b/.github/workflows/ci-features-timeline.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/.github/workflows/ci-features.yml b/.github/workflows/ci-features.yml index 693c6521c..4f0e1ad2f 100644 --- a/.github/workflows/ci-features.yml +++ b/.github/workflows/ci-features.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | @@ -107,14 +107,5 @@ jobs: - name: Run rspec (photos/) run: bundle exec rspec spec/features/photos/ -fd - - name: Run rspec (places/) - run: bundle exec rspec spec/features/places/ -fd - - - name: Run rspec (plantings/) - run: bundle exec rspec spec/features/plantings/ -fd - - - name: Run rspec (posts/) - run: bundle exec rspec spec/features/posts/ -fd - - name: Run rspec (rss/) run: bundle exec rspec spec/features/rss/ -fd \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b1f9659fc..eaed8103e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: contributors: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Install ruby version specified in .ruby-version uses: ruby/setup-ruby@v1 with: @@ -53,7 +53,7 @@ jobs: steps: - name: Checkout this repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Configure sysctl limits run: | diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0f860bec3..e2d7259f0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,6 +12,7 @@ submit the change with your pull request. - Miles Gould / [pozorvlak](https://github.com/pozorvlak) - Mackenzie Morgan / [maco](https://github.com/maco) - Brenda Wallace / [br3nda](https://github.com/br3nda) +- Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX) ## Contributors @@ -68,7 +69,6 @@ submit the change with your pull request. - Jym Paul Carandang / [jacarandang](https://github.com/jacarandang) - Anthony Atkinson / [sha1sum](https://github.com/sha1sum) - Terence Conquest / [twconquest](https://github.com/twconquest) -- Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX) - DV Dasari / [dv2](https://github.com/dv2) - Eric Tillberg / [Thrillberg](https://github.com/Thrillberg) - Lucas Nogueira / [lucasnogueira](https://github.com/lucasnogueira) @@ -95,10 +95,11 @@ submit the change with your pull request. - Ítalo Pires / [italopires](https://github.com/italopires) - Bennett Zink / [bennett-zink](https://github.com/bennett-zink) - Dominick Thornton / [domthor](https://github.com/domthor) - + ## Bots ### Security and Dependency Updates - `codefactor-io[bot]` - DeppBot / [deppbot](https://github.com/deppbot) - `dependabot[bot]` [dependabot](https://github.com/dependabot-bot) / [dependabot-preview](https://github.com/apps/dependabot-preview) +- [google-labs-jules[bot]](https://github.com/apps/google-labs-jules) diff --git a/Gemfile b/Gemfile index 06d4cc318..28de94c3b 100644 --- a/Gemfile +++ b/Gemfile @@ -193,10 +193,12 @@ group :test do gem 'selenium-webdriver' gem 'timecop' gem 'vcr' + gem "rspec-rebound" + gem "percy-capybara", "~> 5.0.0" end group :travis do gem 'platform-api' end -gem "percy-capybara", "~> 5.0.0" + diff --git a/Gemfile.lock b/Gemfile.lock index 6ce46e85f..a0bd14c00 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,29 +33,29 @@ GEM GEM remote: https://rubygems.org/ specs: - actioncable (7.2.2.1) - actionpack (= 7.2.2.1) - activesupport (= 7.2.2.1) + actioncable (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.2.1) - actionpack (= 7.2.2.1) - activejob (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionmailbox (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) mail (>= 2.8.0) - actionmailer (7.2.2.1) - actionpack (= 7.2.2.1) - actionview (= 7.2.2.1) - activejob (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionmailer (7.2.2.2) + actionpack (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activesupport (= 7.2.2.2) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.2.1) - actionview (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionpack (7.2.2.2) + actionview (= 7.2.2.2) + activesupport (= 7.2.2.2) nokogiri (>= 1.8.5) racc rack (>= 2.2.4, < 3.2) @@ -64,15 +64,15 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.2.1) - actionpack (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + actiontext (7.2.2.2) + actionpack (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.2.1) - activesupport (= 7.2.2.1) + actionview (7.2.2.2) + activesupport (= 7.2.2.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -87,22 +87,22 @@ GEM active_utils (3.5.0) activesupport (>= 4.2) i18n - activejob (7.2.2.1) - activesupport (= 7.2.2.1) + activejob (7.2.2.2) + activesupport (= 7.2.2.2) globalid (>= 0.3.6) - activemodel (7.2.2.1) - activesupport (= 7.2.2.1) - activerecord (7.2.2.1) - activemodel (= 7.2.2.1) - activesupport (= 7.2.2.1) + activemodel (7.2.2.2) + activesupport (= 7.2.2.2) + activerecord (7.2.2.2) + activemodel (= 7.2.2.2) + activesupport (= 7.2.2.2) timeout (>= 0.4.0) - activestorage (7.2.2.1) - actionpack (= 7.2.2.1) - activejob (= 7.2.2.1) - activerecord (= 7.2.2.1) - activesupport (= 7.2.2.1) + activestorage (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activesupport (= 7.2.2.2) marcel (~> 1.0) - activesupport (7.2.2.1) + activesupport (7.2.2.2) base64 benchmark (>= 0.3) bigdecimal @@ -156,7 +156,7 @@ GEM actionpack (>= 6.1) activemodel (>= 6.1) builder (3.3.0) - bullet (8.0.7) + bullet (8.0.8) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) byebug (12.0.0) @@ -251,7 +251,7 @@ GEM elasticsearch-transport (7.0.0) faraday multi_json - erb (5.0.1) + erb (5.0.2) erubi (1.13.1) erubis (2.7.0) excon (1.2.5) @@ -262,9 +262,9 @@ GEM factory_bot_rails (6.5.0) factory_bot (~> 6.5) railties (>= 6.1.0) - faker (3.5.1) + faker (3.5.2) i18n (>= 1.8.11, < 2) - faraday (2.13.2) + faraday (2.13.4) faraday-net_http (>= 2.0, < 3.5) json logger @@ -351,7 +351,7 @@ GEM image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - io-console (0.8.0) + io-console (0.8.1) irb (1.15.2) pp (>= 0.6.0) rdoc (>= 4.0.0) @@ -423,14 +423,14 @@ GEM bigdecimal (~> 3.1) net-http (0.6.0) uri - net-imap (0.4.20) + net-imap (0.5.9) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.5.0) + net-smtp (0.5.1) net-protocol netrc (0.11.0) nio4r (2.7.4) @@ -482,7 +482,7 @@ GEM date stringio public_suffix (6.0.1) - puma (6.6.0) + puma (6.6.1) nio4r (~> 2.0) query_diet (0.7.2) racc (1.8.1) @@ -499,20 +499,20 @@ GEM rackup (1.0.1) rack (< 3) webrick - rails (7.2.2.1) - actioncable (= 7.2.2.1) - actionmailbox (= 7.2.2.1) - actionmailer (= 7.2.2.1) - actionpack (= 7.2.2.1) - actiontext (= 7.2.2.1) - actionview (= 7.2.2.1) - activejob (= 7.2.2.1) - activemodel (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + rails (7.2.2.2) + actioncable (= 7.2.2.2) + actionmailbox (= 7.2.2.2) + actionmailer (= 7.2.2.2) + actionpack (= 7.2.2.2) + actiontext (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activemodel (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) bundler (>= 1.15.0) - railties (= 7.2.2.1) + railties (= 7.2.2.2) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -532,9 +532,9 @@ GEM rails_stdout_logging rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) - railties (7.2.2.1) - actionpack (= 7.2.2.1) - activesupport (= 7.2.2.1) + railties (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -542,7 +542,7 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) raindrops (0.20.1) - rake (13.2.1) + rake (13.3.0) rate_throttle_client (0.1.2) rb-fsevent (0.11.2) rb-inotify (0.10.1) @@ -550,11 +550,11 @@ GEM rdoc (6.14.2) erb psych (>= 4.0.0) - recaptcha (5.19.0) + recaptcha (5.20.1) redis-client (0.23.2) connection_pool - regexp_parser (2.11.0) - reline (0.6.1) + regexp_parser (2.11.2) + reline (0.6.2) io-console (~> 0.5) responders (3.1.1) actionpack (>= 5.2) @@ -570,7 +570,7 @@ GEM rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) - rspec-activemodel-mocks (1.2.1) + rspec-activemodel-mocks (1.3.0) activemodel (>= 3.0) activesupport (>= 3.0) rspec-mocks (>= 2.99, < 4.0) @@ -582,7 +582,7 @@ GEM rspec-mocks (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (8.0.1) + rspec-rails (8.0.2) actionpack (>= 7.2) activesupport (>= 7.2) railties (>= 7.2) @@ -590,6 +590,8 @@ GEM rspec-expectations (~> 3.13) rspec-mocks (~> 3.13) rspec-support (~> 3.13) + rspec-rebound (0.2.1) + rspec-core (~> 3.3) rspec-support (3.13.4) rspectre (0.2.0) parser (>= 3.3.7.1) @@ -606,7 +608,7 @@ GEM rswag-ui (2.16.0) actionpack (>= 5.2, < 8.1) railties (>= 5.2, < 8.1) - rubocop (1.79.1) + rubocop (1.79.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -626,7 +628,7 @@ GEM rubocop-factory_bot (2.27.1) lint_roller (~> 1.1) rubocop (~> 1.72, >= 1.72.1) - rubocop-rails (2.32.0) + rubocop-rails (2.33.3) activesupport (>= 4.2.0) lint_roller (~> 1.1) rack (>= 1.1) @@ -646,7 +648,7 @@ GEM ruby-units (4.1.0) ruby-vips (2.2.1) ffi (~> 1.12) - rubyzip (2.4.1) + rubyzip (3.0.1) sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -660,17 +662,17 @@ GEM sprockets (> 3.0) sprockets-rails tilt - scout_apm (5.6.4) + scout_apm (5.7.0) parser searchkick (5.3.1) activemodel (>= 6.1) hashie securerandom (0.4.1) - selenium-webdriver (4.34.0) + selenium-webdriver (4.35.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) + rubyzip (>= 1.2.2, < 4.0) websocket (~> 1.0) sidekiq (7.3.9) base64 @@ -728,7 +730,8 @@ GEM rack-test (>= 0.5.3) webrick (1.9.1) websocket (1.2.11) - websocket-driver (0.7.6) + websocket-driver (0.8.0) + base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) will_paginate (4.0.1) @@ -825,6 +828,7 @@ DEPENDENCIES responders rspec-activemodel-mocks rspec-rails + rspec-rebound rspectre rswag-api rswag-specs diff --git a/app/assets/images/location-not-set.en.png b/app/assets/images/location-not-set.en.png deleted file mode 100644 index 8c02672da..000000000 Binary files a/app/assets/images/location-not-set.en.png and /dev/null differ diff --git a/app/assets/stylesheets/_members.scss b/app/assets/stylesheets/_members.scss index 79692355e..2af24fe7e 100644 --- a/app/assets/stylesheets/_members.scss +++ b/app/assets/stylesheets/_members.scss @@ -33,13 +33,6 @@ } } -.location-not-set { - background-image: image-url("location-not-set.en.png"); - background-position: center; - background-repeat: no-repeat; - height: 250px; - width: 100%; -} .card { .badge-location { background-color: darken($blue, 10%); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 1825ff9fb..d8d75004d 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -30,3 +30,7 @@ @import "predictions"; @import "homepage"; @import "maps"; + +@view-transition { + navigation: auto; +} \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7db3be745..7c7e58d6f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -78,6 +78,7 @@ class ApplicationController < ActionController::Base :tos_agreement, # profile stuff :bio, :location, :latitude, :longitude, + :website_url, :instagram_handle, :facebook_handle, :bluesky_handle, :other_url, # email settings :show_email, :newsletter, :send_notification_email, :send_planting_reminder, # update password diff --git a/app/controllers/seeds_controller.rb b/app/controllers/seeds_controller.rb index 89ab9daff..2425554d5 100644 --- a/app/controllers/seeds_controller.rb +++ b/app/controllers/seeds_controller.rb @@ -19,6 +19,10 @@ class SeedsController < DataController where['parent_planting'] = @planting.id end + if params[:tradeable_to].present? + where['tradeable_to'] = params[:tradeable_to] + end + @show_all = (params[:all] == '1') where['finished'] = false unless @show_all diff --git a/app/models/member.rb b/app/models/member.rb index 1c63a9a17..2427092f6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -91,6 +91,9 @@ class Member < ApplicationRecord uniqueness: { case_sensitive: false } + validates :website_url, format: { with: /\Ahttps?:\/\//, message: "must start with http:// or https://" }, allow_blank: true + validates :other_url, format: { with: /\Ahttps?:\/\//, message: "must start with http:// or https://" }, allow_blank: true + validates :instagram_handle, :facebook_handle, :bluesky_handle, format: { without: %r{\Ahttps?:\/\/|\/}, message: "should be a handle, not a URL" }, allow_blank: true # # Triggers diff --git a/app/views/devise/registrations/_edit_profile.html.haml b/app/views/devise/registrations/_edit_profile.html.haml index 869bf60be..6feb02d13 100644 --- a/app/views/devise/registrations/_edit_profile.html.haml +++ b/app/views/devise/registrations/_edit_profile.html.haml @@ -13,7 +13,32 @@ .form-group = f.label :bio, class: 'control-label col-md-2' .col-md-8 - = f.text_area :bio, rows: 6, class: 'form-control' + = f.text_area :bio, rows: 6, class: 'form-control', placeholder: "I'm am XYZ gardener interested in A, B, C" + + .form-group + = f.label :website_url, 'Website', class: 'control-label col-md-2' + .col-md-8 + = f.url_field :website_url, class: 'form-control', placeholder: "https://you.example.com/" + + .form-group + = f.label :instagram_handle, 'Instagram', class: 'control-label col-md-2' + .col-md-8 + = f.text_field :instagram_handle, class: 'form-control', placeholder: 'your_handle' + + .form-group + = f.label :facebook_handle, 'Facebook', class: 'control-label col-md-2' + .col-md-8 + = f.text_field :facebook_handle, class: 'form-control', placeholder: 'your_handle' + + .form-group + = f.label :bluesky_handle, 'Bluesky', class: 'control-label col-md-2' + .col-md-8 + = f.text_field :bluesky_handle, class: 'form-control', placeholder: 'your_handle' + + .form-group + = f.label :other_url, 'Other URL', class: 'control-label col-md-2' + .col-md-8 + = f.url_field :other_url, class: 'form-control', placeholder: "https://you.example.com/" .form-group %label.control-label.col-md-2 diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 929b40bd9..01a4d6b26 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -51,7 +51,8 @@ %section.seeds = cute_icon = render 'seeds' - %p.text-right= link_to "#{t('home.seeds.view_all')} »", seeds_path, class: 'btn btn-block' + %p.text-right + = link_to "#{t('home.seeds.view_all')} »", seeds_path(tradeable_to: ['locally', 'nationally', 'internationally']), class: 'btn btn-block' .col-12.col-lg-6 %section.discussion.text-center = cute_icon diff --git a/app/views/members/_bio.html.haml b/app/views/members/_bio.html.haml index 221f6d141..6bb67eed0 100644 --- a/app/views/members/_bio.html.haml +++ b/app/views/members/_bio.html.haml @@ -1,13 +1 @@ %h2 All about #{member.login_name} -%p - %small - %a{href: "#content"} - Skip to main content -- if member.bio.blank? - - if can? :edit, member - = link_to "Add a bio to complete your profile.", edit_member_registration_path - - else - #{member.login_name} hasn't written a bio yet. -- else - :markdown - #{ strip_tags markdownify(member.bio) } diff --git a/app/views/members/_contact.html.haml b/app/views/members/_contact.html.haml index d6bdb7cb9..ce07b2246 100644 --- a/app/views/members/_contact.html.haml +++ b/app/views/members/_contact.html.haml @@ -1,17 +1,42 @@ -- if twitter_auth || flickr_auth || member.show_email +- if member.website_url.present? || member.instagram_handle.present? || member.facebook_handle.present? || member.bluesky_handle.present? || member.other_url.present? || twitter_auth || flickr_auth || member.show_email %h4 Contact + - if member.website_url.present? + %p + = icon 'fas', 'globe', class: 'fa-fw' + = link_to "Website", member.website_url, target: '_blank', rel: 'noopener noreferrer' + + - if member.instagram_handle.present? + %p + = icon 'fab', 'instagram', class: 'fa-fw' + = link_to member.instagram_handle, "https://instagram.com/#{member.instagram_handle}", target: '_blank', rel: 'noopener noreferrer' + + - if member.facebook_handle.present? + %p + = icon 'fab', 'facebook', class: 'fa-fw' + = link_to member.facebook_handle, "https://facebook.com/#{member.facebook_handle}", target: '_blank', rel: 'noopener noreferrer' + + - if member.bluesky_handle.present? + %p + = icon 'fas', 'comment-dots', class: 'fa-fw' + = link_to member.bluesky_handle, "https://bsky.app/profile/#{member.bluesky_handle}", target: '_blank', rel: 'noopener noreferrer' + + - if member.other_url.present? + %p + = icon 'fas', 'link', class: 'fa-fw' + = link_to "More...", member.other_url, target: '_blank', rel: 'noopener noreferrer' + - if twitter_auth %p = image_tag "twitter_32.png", size: "32x32", alt: 'Twitter logo' - = link_to twitter_auth.name, "https://twitter.com/#{twitter_auth.name}" + = link_to twitter_auth.name, "https://twitter.com/#{twitter_auth.name}", target: '_blank', rel: 'noopener noreferrer' - if flickr_auth %p = image_tag "flickr_32.png", size: "32x32", alt: 'Flickr logo' - = link_to flickr_auth.name, "https://flickr.com/photos/#{flickr_auth.uid}" + = link_to flickr_auth.name, "https://flickr.com/photos/#{flickr_auth.uid}", target: '_blank', rel: 'noopener noreferrer' - if member.show_email %p - Email: + = icon 'fas', 'envelope', class: 'fa-fw' = mail_to member.email diff --git a/app/views/members/_map.html.haml b/app/views/members/_map.html.haml index 6a2060043..b130a5c20 100644 --- a/app/views/members/_map.html.haml +++ b/app/views/members/_map.html.haml @@ -5,5 +5,5 @@ = link_to member.location, place_path(member.location, anchor: "members") - else .location-not-set - .sr-only Location not known - .sr-only We can't show you what's nearby + %h1 Location not known or geocodable + %p We can't show you what's nearby diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index e8f06f111..c231a8cc8 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -21,6 +21,21 @@ .row .col= render "bio", member: @member .col= render "avatar", member: @member + .row + .col + %p + %small + %a{href: "#content"} + Skip to main content + - if @member.bio.blank? + - if can? :edit, @member + = link_to "Add a bio to complete your profile.", edit_member_registration_path + - else + #{@member.login_name} hasn't written a bio yet. + - else + :markdown + #{ strip_tags markdownify(@member.bio) } + - if @member.roles.any? %p - @member.roles.each do |role| @@ -30,12 +45,16 @@ = icon 'fas', 'map-marker' = truncate(@member.location, length: 15, separator: ' ', omission: '... ') %p - %strong Member since - = @member.created_at.to_fs(:date) + %small + %strong Member since + %br + = @member.created_at.to_fs(:date) - if @member.last_sign_in_at %p - %strong Last Login - = @member.last_sign_in_at&.to_fs(:default) + %small + %strong Last Login + %br + = @member.last_sign_in_at&.to_fs(:default) - if can? :update, @member = link_to edit_member_registration_path, class: 'btn btn-block' do diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index e50747b46..a05f54362 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -17,6 +17,14 @@ = check_box_tag 'active', 'all', @show_all include finished %hr/ + %section.filters + %h2 Tradeable + %ul.nav.flex-column + %li.nav-item= link_to "All tradable seeds", seeds_path(tradeable_to: ['locally', 'nationally', 'internationally']) + - Seed::TRADABLE_TO_VALUES.each do |value| + - unless value == 'nowhere' + %li.nav-item= link_to value.capitalize, seeds_path(tradeable_to: value) + %hr/ - if @owner = render @owner - if @crop diff --git a/config/initializers/mailboxer.rb b/config/initializers/mailboxer.rb index b43a61519..0c9bf8213 100644 --- a/config/initializers/mailboxer.rb +++ b/config/initializers/mailboxer.rb @@ -5,7 +5,7 @@ Mailboxer.setup do |config| config.uses_emails = true # Configures the default from for emails sent for Messages and Notifications - config.default_from = "no-reply@growstuff.org" + config.default_from = "Growstuff <#{ENV.fetch('GROWSTUFF_EMAIL', "no-reply@growstuff.org")}>" # Configures the methods needed by mailboxer # config.email_method = :email diff --git a/config/locales/mailboxer.en.yml b/config/locales/mailboxer.en.yml new file mode 100644 index 000000000..032a9a7c7 --- /dev/null +++ b/config/locales/mailboxer.en.yml @@ -0,0 +1,7 @@ +en: + mailboxer: + message_mailer: + subject_new: "New Notification: %{subject}" + subject_reply: "New Reply: %{subject}" + notification_mailer: + subject: "New notification: %{subject}" \ No newline at end of file diff --git a/db/migrate/20240716120000_add_social_media_to_members.rb b/db/migrate/20240716120000_add_social_media_to_members.rb new file mode 100644 index 000000000..1b7fc97ec --- /dev/null +++ b/db/migrate/20240716120000_add_social_media_to_members.rb @@ -0,0 +1,9 @@ +class AddSocialMediaToMembers < ActiveRecord::Migration[6.0] + def change + add_column :members, :website_url, :string + add_column :members, :instagram_handle, :string + add_column :members, :facebook_handle, :string + add_column :members, :bluesky_handle, :string + add_column :members, :other_handle, :string + end +end diff --git a/db/migrate/20240716120001_rename_other_handle_to_other_url_in_members.rb b/db/migrate/20240716120001_rename_other_handle_to_other_url_in_members.rb new file mode 100644 index 000000000..e78eb12eb --- /dev/null +++ b/db/migrate/20240716120001_rename_other_handle_to_other_url_in_members.rb @@ -0,0 +1,5 @@ +class RenameOtherHandleToOtherUrlInMembers < ActiveRecord::Migration[6.0] + def change + rename_column :members, :other_handle, :other_url + end +end diff --git a/db/schema.rb b/db/schema.rb index 44f298856..2ce2a6b6d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -446,6 +446,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_29_041435) do t.integer "photos_count" t.integer "forums_count" t.integer "activities_count" + t.string "website_url" + t.string "instagram_handle" + t.string "facebook_handle" + t.string "bluesky_handle" + t.string "other_url" t.index ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true t.index ["discarded_at"], name: "index_members_on_discarded_at" t.index ["email"], name: "index_members_on_email", unique: true diff --git a/lib/tasks/openfarm.rake b/lib/tasks/openfarm.rake index 3bbd4b20c..46394e942 100644 --- a/lib/tasks/openfarm.rake +++ b/lib/tasks/openfarm.rake @@ -9,10 +9,12 @@ namespace :openfarm do OpenfarmService.new.import! end - desc "Delete all pictures with source OpenFarm" + desc "Delete all pictures with source OpenFarm or from legacy S3 URL" task delete_pictures: :environment do - puts "Deleting pictures with source OpenFarm..." + puts "Deleting pictures with source OpenFarm or from legacy S3 URL..." + s3_legacy_url = 'https://s3.amazonaws.com/openfarm-project/%' photos_to_delete = Photo.where(source: 'openfarm') + .or(Photo.where('fullsize_url LIKE ?', s3_legacy_url)) count = photos_to_delete.count photos_to_delete.each do |photo| photo.photo_associations.each do |photo_association| diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 3c17087a9..bd64cd333 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -15,13 +15,13 @@ require 'capybara-screenshot/rspec' require 'axe-capybara' require 'axe-rspec' -# TODO: We may want to trial options.add_argument('--disable-dev-shm-usage') ### optional - # Required for running in the dev container Capybara.register_driver :selenium_chrome_customised_headless do |app| options = Selenium::WebDriver::Options.chrome options.add_argument("--headless") options.add_argument("--no-sandbox") + options.add_argument("--window-size=1920,1080") + options.add_argument("--disable-dev-shm-usage") # driver = Selenium::WebDriver.for :chrome, options: options @@ -120,8 +120,8 @@ RSpec.configure do |config| # Prevent Poltergeist from fetching external URLs during feature tests config.before(:each, :js) do # TODO: Why are we setting this page size then straight afterwards, maximising? - width = 1280 - height = 1280 + width = 1920 + height = 1080 Capybara.current_session.driver.browser.manage.window.resize_to(width, height) if page.driver.browser.respond_to?(:url_blacklist) @@ -132,6 +132,9 @@ RSpec.configure do |config| ] end - page.driver.browser.manage.window.maximize if page.driver.browser.respond_to?(:manage) + # Historically, we wanted to .maximize; but this actually undoes the resize_to step above + # with chrome headless + # page.driver.browser.manage.window.maximize if page.driver.browser.respond_to?(:manage) + # puts "Maximized window size: #{page.driver.browser.manage.window.size}" end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 40c0db74a..0bd6f9a1c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration require 'percy/capybara' +require 'rspec/rebound' require 'vcr' VCR.configure do |c| @@ -123,4 +124,20 @@ RSpec.configure do |config| # Remember which tests failed, so you can run rspec with the `--only-failures` flag. config.example_status_persistence_file_path = "tmp/examples.txt" + + # show retry status in spec process + config.verbose_retry = true + # show exception that triggers a retry if verbose_retry is set to true + config.display_try_failure_messages = true + + # run retry only on features + config.around :each, :js do |ex| + ex.run_with_retry retry: 3 + end + + # callback to be run between retries + config.retry_callback = proc do |ex| + # run some additional clean up task - can be filtered by example metadata + Capybara.reset! if ex.metadata[:js] + end end