2480 Commits

Author SHA1 Message Date
Daniel O'Connor
c9b8c54b81 Fix plantings ICS feed regression and enable request spec (#4687)
* Fix plantings ICS feed regression and enable request spec

- Update `app/views/plantings/index.ics.erb` to use ActiveRecord method calls instead of hash bracket access.
- Enable `spec/requests/plantings_spec.rb` and update it to account for mirrored harvest events.
- Add `config/initializers/faraday_patch.rb` to fix Searchkick/Faraday 2.x compatibility issues.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Delete config/initializers/faraday_patch.rb

* Apply suggestion from @CloCkWeRX

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Apply suggestion from @CloCkWeRX

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 23:18:24 +09:30
Daniel O'Connor
fa7f460510 Refactor Plantings to remove Elasticsearch dependency (#4686)
* Refactor Plantings to remove Elasticsearch dependency

This commit refactors the Plantings controller, model, and views to use
ActiveRecord instead of Searchkick/Elasticsearch.

Key changes:
- Refactored `PlantingsController#index` to use an ActiveRecord-based
  `plantings` method.
- Moved `homepage_records` logic from `SearchPlantings` concern to the
  `Planting` model using ActiveRecord scopes.
- Removed `SearchPlantings` concern and deleted the file.
- Updated `home/_plantings.html.haml` and `plantings/index.rss.haml` to
  use dot notation for `Planting` object attributes.
- Updated specs to remove Searchkick-related setup and assertions.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix Planting.reindex

* Fix test

* Mark test pending

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 22:26:49 +09:30
Daniel O'Connor
6e7cf1c813 Refactor Seeds to remove Elasticsearch dependency (#4684)
* Refactor Seeds to remove Elasticsearch dependency

This commit refactors the `SeedsController` and `Seed` model to remove
dependency on Elasticsearch and Searchkick.

Key changes:
- Removed `SearchSeeds` concern from the `Seed` model.
- Reimplemented `Seed.homepage_records` using ActiveRecord.
- Refactored `SeedsController#index` to use ActiveRecord for filtering,
  eager loading, and pagination.
- Deleted `app/models/concerns/search_seeds.rb`.
- Updated relevant specs to remove Searchkick-specific tags and setup.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Remove Seed.reindex

* Remove trait

* Fix tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-06-24 21:54:43 +09:30
Daniel O'Connor
3edd2510d8 Merge pull request #4683 from Growstuff/refactor-harvests-remove-elasticsearch-14630838429921835504
Refactor harvests to remove Elasticsearch
2026-06-24 20:26:22 +09:30
google-labs-jules[bot]
d6b9ededec Remove Photo.reindex calls from test suite
The Photo model is no longer using Searchkick/Elasticsearch, so calling
`Photo.reindex` causes a NoMethodError. This commit removes these calls
from `spec/spec_helper.rb` and feature specs, and removes the unused
`:reindex` trait from the photo factory call in `likeable_spec.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 14:00:08 +00:00
google-labs-jules[bot]
97e236f7e8 Convert Photos controller to plain SQL queries
- Refactored `PhotosController#index` to use ActiveRecord queries instead of Searchkick/Elasticsearch.
- Handled filtering by crop and planting via associations.
- Added eager loading for the photo owner to prevent N+1 queries.
- Decoupled the `Photo` model from Elasticsearch by removing the `SearchPhotos` concern.
- Deleted `app/models/concerns/search_photos.rb`.
- Updated controller and model specs to use standard ActiveRecord expectations.
- Cleaned up the photo factory by removing the now-obsolete `:reindex` trait.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-06-23 12:16:50 +00:00
Daniel O'Connor
d7a50f86b5 Allow collaborators to remove themselves from gardens (#4630)
- Update Ability to grant destroy permission to collaborators for their own record
- Add 'Leave garden' link to garden show page
- Add specs for garden collaborator permissions

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-12 17:23:24 +09:30
Daniel O'Connor
5ada7e7f77 Add crops search API endpoint (#4622)
* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Add crops search API endpoint

- Added GET /api/v1/crops/search endpoint.
- Updated CropSearchService to support additional search options.
- Manually updated Swagger documentation in swagger/v1/swagger.json.
- Added request specs to verify the new endpoint.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-04 18:12:36 +09:30
Daniel O'Connor
035210197f Prompt for updated planting rating when harvesting (#4608)
* Update planting rating when recording a harvest

- Added virtual attribute `overall_rating` to `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated.
- Refined feature tests for harvesting.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* I have updated the system to allow for recording a planting rating when a harvest is logged. Here is a summary of the changes:

- Added a virtual attribute `overall_rating` to the `Harvest` model.
- Updated `HarvestsController` to permit `overall_rating` and synchronize it to the associated `Planting`.
- Added a rating range field (1-5) to the harvest form.
- Added controller tests to verify that the planting rating is updated correctly.
- Updated feature tests to ensure the harvest form functions as expected.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Update database.yml

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

* Adjust wording

* Change harvest modal

* Fix tests

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-05-03 14:47:00 +09:30
Daniel O'Connor
8a8fd6eabd Merge pull request #4575 from Growstuff/memoize-unread-count
Memoize unread messages count
2026-05-02 16:46:26 +09:30
Daniel O'Connor
2380c662fe Merge pull request #4604 from Growstuff/harvest-reminders-16703221337897327633
Add Harvest Reminder Emails and Scheduled Task
2026-05-02 15:46:09 +09:30
Daniel O'Connor
1f6f3c4dfd Merge pull request #4612 from Growstuff/fix-crops-csv-export-11894001552728801282
Fix ArgumentError in Crops CSV export
2026-05-02 15:31:10 +09:30
google-labs-jules[bot]
4643fbd92e Associate post with crop from crop show page
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-05-01 11:35:58 +00:00
google-labs-jules[bot]
e423e6ac79 Add weekly harvest reminder emails and scheduled task
- Added `send_harvest_reminder` preference to Member model and settings UI.
- Implemented `harvest_in_next_week?` in PredictHarvest concern.
- Created `harvest_reminder` email with localized templates.
- Added `growstuff:send_harvest_reminders` Rake task to run weekly.
- Refactored existing and new reminder tasks to use `deliver_later` for scalability.
- Added unit tests for prediction logic and mailer.
- Fixed a bug in the existing planting reminder task where it was using an uninitialized constant `Notifier`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-30 04:09:26 +00:00
Daniel O'Connor
7160f50ac1 Refactor Activity model to remove Elasticsearch integration (#4576)
* Refactor Activity model to remove Elasticsearch integration

- Removed `SearchActivities` concern and Searchkick from `Activity` model.
- Implemented `Activity.homepage_records` using ActiveRecord with `DISTINCT ON` for PostgreSQL.
- Updated `ActivitiesController#index` to use ActiveRecord queries with eager loading and pagination.
- Added `active` scope to `Activity`.
- Added unit tests for `Activity` model.
- Deleted `app/models/concerns/search_activities.rb`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix NoMethodError: undefined method 'reindex' for class Activity

- Removed all calls to `Activity.reindex` in migrations, rake tasks, and spec helpers.
- These were causing failures after the removal of Searchkick from the Activity model.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous column id in homepage_records query

- Updated `Activity.homepage_records` to use `activities.id` instead of `id` in the subquery.
- This resolves the `PG::AmbiguousColumn: ERROR: column reference "id" is ambiguous` error.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix ambiguous created_at in homepage_records query

- Use `unscoped` in the subquery for `Activity.homepage_records` to bypass the default scope from `Ownable` concern.
- This prevents the join with the `members` table in the subquery, which was causing `PG::AmbiguousColumn: ERROR: column reference "created_at" is ambiguous`.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Complete refactoring of Activity model to remove Elasticsearch

- Removed SearchActivities concern and searchkick integration.
- Updated ActivitiesController#index to use ActiveRecord queries.
- Implemented performant Activity.homepage_records using DISTINCT ON (PostgreSQL).
- Added Activity.active scope.
- Added no-op Activity.reindex (class and instance methods) for backward compatibility.
- Cleaned up leftover reindex calls in rake tasks, migrations, and spec helpers.
- Added unit tests for new Activity model logic.
- Updated factories to include no-op reindex traits.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Less eager loading

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-28 17:51:01 +09:30
google-labs-jules[bot]
3c70ba12ca Allow filtering Flickr photos by tag when adding photos
- Update MemberFlickr concern to support tag-based search using flickr.photos.search
- Update PhotosController to handle the 'tag' parameter
- Add tag search input field to the 'New Photo' view
- Add test case to verify tag filtering in PhotosController spec

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-28 02:59:21 +00:00
google-labs-jules[bot]
ff9d99afe5 Improve Charts::CropsController with caching and refactoring
- Added Rails.cache.fetch to `sunniness` and `planted_from` actions.
- Refactored crop loading into a `before_action :set_crop`.
- Updated specs to verify caching behavior and ensure coverage.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-27 07:46:08 +00:00
Daniel O'Connor
8e7dd25e98 Add rake task to cleanup inactive members (#4574)
* Add members:cleanup_inactive rake task

This task identifies and deletes members who have not logged in for over
24 months and have no gardens, plantings, or other activity (posts,
comments, seeds, harvests, etc).

Includes support for DRY_RUN=true to preview deletions.
Added tests in spec/tasks/members_spec.rb.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Refactor activity check to Member#has_activity? and update rake task

- Added `Member#has_activity?` to encapsulate the check for gardens, plantings, and other activity.
- Updated `members:cleanup_inactive` rake task to use `Member#has_activity?`.
- Maintained `DRY_RUN` support and existing tests.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Apply suggestion from @CloCkWeRX

* Apply suggestions from code review

Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-27 01:40:54 +09:30
Daniel O'Connor
573daa8c8a Swap to modern expect style (#4571) 2026-04-26 22:58:04 +09:30
Daniel O'Connor
5174b1236e Merge pull request #4567 from Growstuff/memory-optimisation-3
Members - Nearest To - Memory improvements
2026-04-26 22:57:01 +09:30
Daniel O'Connor
5a349f8f1b Swap to modern expect style 2026-04-26 13:21:15 +00:00
Daniel O'Connor
0d850804cf Merge pull request #4570 from Growstuff/rubocop-tweaks
Rubocop fixes
2026-04-26 22:47:46 +09:30
Daniel O'Connor
8cfef5ce1a Rubocop fixes 2026-04-26 13:09:00 +00:00
Daniel O'Connor
6dacb0af74 Swap to modern expect style 2026-04-26 13:03:46 +00:00
Daniel O'Connor
7e2d36f99a Swap to modern expect style 2026-04-26 12:55:58 +00:00
google-labs-jules[bot]
3b60e8f974 Implement blocking feature (#4199)
* Implement blocking feature

This commit introduces a blocking feature that allows members to block other members.

A blocked member is prevented from:
- following the blocker
- sending private messages to the blocker
- replying to the blocker's posts
- liking the blocker's content

The implementation includes:
- A new `Block` model and a corresponding database table.
- Updates to the `Member` model to include associations for blocks.
- A new `BlocksController` to handle blocking and unblocking actions.
- New routes for the `BlocksController`.
- UI changes to add block/unblock buttons to the member profile page.
- Validations in the `Follow`, `Comment`, and `Like` models to enforce the blocking rules.
- A check in the `MessagesController` to prevent sending messages to a member who has blocked the sender.
- A callback in the `Block` model to destroy the follow relationship when a block is created.
- New feature and model specs to test the blocking functionality.

* Implement blocking feature and fix failing tests

This commit introduces a blocking feature that allows members to block other members.

A blocked member is prevented from:
- following the blocker
- sending private messages to the blocker
- replying to the blocker's posts
- liking the blocker's content

The implementation includes:
- A new `Block` model and a corresponding database table.
- Updates to the `Member` model to include associations for blocks.
- A new `BlocksController` to handle blocking and unblocking actions.
- New routes for the `BlocksController`.
- UI changes to add block/unblock buttons to the member profile page.
- Validations in the `Follow`, `Comment`, and `Like` models to enforce the blocking rules.
- A check in the `MessagesController` to prevent sending messages to a member who has blocked the sender.
- A callback in the `Block` model to destroy the follow relationship when a block is created.
- New feature and model specs to test the blocking functionality.

This commit also fixes a failing test in the blocking feature. The error was caused by the validation being called even when the `member` association was `nil`. A guard has been added to the validation methods in the `Like`, `Follow`, and `Comment` models to prevent this from happening.

* Generate schema

* Fix tests

* Add permissions

* Define Block permissions in Ability model

The feature specs for member blocking were failing because the "Block"
link was not being rendered on member profiles. This was due to the
lack of explicit create and destroy permissions for the Block resource
in the Ability model, which is used by CanCanCan to authorize actions
and by the view to conditionally show links.

This change adds the necessary permissions to `member_abilities`:
- Allows members to create blocks (except for blocking themselves).
- Allows members to destroy blocks where they are the blocker.

These rules ensure that the "Block" and "Unblock" links are correctly
rendered and authorized for signed-in members.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Comment out specs for now

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-26 14:22:32 +09:30
google-labs-jules[bot]
7ed3a97263 Improve test coverage of ability_spec (#4283)
* Improve test coverage of ability_spec

* Fix specs

* Rubocop

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
Co-authored-by: Daniel O'Connor <365751+CloCkWeRX@users.noreply.github.com>
2026-04-26 14:21:36 +09:30
Daniel O'Connor
2aa697a6d6 Add comprehensive test coverage for forums (#4561)
* Add comprehensive test coverage for forums

- Added `spec/controllers/forums_controller_spec.rb` to test all CRUD actions and authorization for guest, member, and admin roles.
- Added `spec/features/forums_spec.rb` to cover user-facing features such as browsing forums and creating posts from within a forum.
- Updated `spec/requests/forums_spec.rb` to cover basic request flow and JSON response formats.

Note: Tests were verified for content and logic but execution in the sandbox environment was blocked by missing infrastructure (PostgreSQL and Elasticsearch).

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Fix specs

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-26 14:18:28 +09:30
google-labs-jules[bot]
6c7903c2a5 Fix RSpec/ExpectInHook offenses
- Move expectations from `before` hooks to `it` blocks.
- Ensure controller actions are called after expectations are set in controller specs.
- Replace synchronization expectations in hooks with Capybara `find` calls.
- Remove RSpec/ExpectInHook from .rubocop_todo.yml.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>
2026-04-25 18:39:43 +00:00
Daniel O'Connor
dfa963cd65 Rubocop: RSpec/EmptyExampleGroup (#4554)
* Rubocop: RSpec/EmptyExampleGroup

* Undo renaming

* Apply suggestion from @CloCkWeRX

* Apply suggestion from @CloCkWeRX
2026-04-26 03:18:50 +09:30
Daniel O'Connor
163289e853 Fix RSpec/IndexedLet RuboCop issues in spec files (#4556)
* Fix RSpec/IndexedLet RuboCop issues in spec files

Replace indexed let variable names with descriptive names across 11 spec files.
This improves readability and complies with the RSpec/IndexedLet rule.

Co-authored-by: CloCkWeRX <365751+CloCkWeRX@users.noreply.github.com>

* Rubocop

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-26 03:10:03 +09:30
Daniel O'Connor
a133eddf21 Rubocop: RSpec/EmptyLineAfterExample 2026-04-25 16:52:34 +00:00
Daniel O'Connor
279cc88162 Update growstuff_markdown_spec.rb 2026-04-24 00:15:18 +09:30
Daniel O'Connor
d625eb2dbd Rubocop: Style/FrozenStringLiteralComment 2026-04-23 14:30:02 +00:00
Daniel O'Connor
e7659a75a4 Merge pull request #4548 from Growstuff/RSpecRails/HaveHttpStatus
Rubocop: RSpecRails/HaveHttpStatus
2026-04-23 23:52:40 +09:30
Daniel O'Connor
4a66bdc9fe Merge pull request #4546 from Growstuff/Rails/RedundantActiveRecordAllMethod
Rubocop: Rails/RedundantActiveRecordAllMethod
2026-04-23 23:46:39 +09:30
Daniel O'Connor
8de6b083f9 Rubocop: RSpecRails/HaveHttpStatus 2026-04-23 14:13:47 +00:00
Daniel O'Connor
accab7f84c Merge pull request #4545 from Growstuff/RSpecRails/InferredSpecType
Rubocop: RSpecRails/InferredSpecType
2026-04-23 23:29:17 +09:30
Daniel O'Connor
3f6dd59dfa Rubocop: Rails/RedundantActiveRecordAllMethod 2026-04-23 13:48:17 +00:00
Daniel O'Connor
0a71b44dea Merge pull request #4542 from Growstuff/RSpec/ContextMethod
Rubocop: RSpec/ContextMethod
2026-04-23 23:10:33 +09:30
Daniel O'Connor
ba75afb3f5 Rubocop: RSpecRails/InferredSpecType 2026-04-23 13:39:46 +00:00
Daniel O'Connor
aa1c9ceb05 Merge pull request #4543 from Growstuff/RSpec/ExpectChange
Rubocop: RSpec/ExpectChange
2026-04-23 23:02:03 +09:30
Daniel O'Connor
ea5f93f929 Merge pull request #4541 from Growstuff/Lint/EmptyBlock
Rubocop: Lint/EmptyBlock
2026-04-23 22:53:40 +09:30
Daniel O'Connor
6f59635ca7 Rubocop: RSpec/ExpectChange 2026-04-23 13:23:14 +00:00
Daniel O'Connor
6736ae3142 Rubocop: RSpec/ContextMethod 2026-04-23 13:20:47 +00:00
Daniel O'Connor
5d112e9134 Rubocop: Capybara/RSpec/HaveSelector (#4539)
* Rubocop: Capybara/RSpec/HaveSelector

* Rubocop: Capybara/RSpec/HaveSelector
2026-04-23 22:45:58 +09:30
Daniel O'Connor
6ba4f39b4a Rubocop: Lint/EmptyBlock 2026-04-23 13:14:39 +00:00
Daniel O'Connor
f1acb35520 Merge pull request #4537 from Growstuff/FactoryBot/SyntaxMethods
Rubocop: FactoryBot/SyntaxMethods
2026-04-23 22:29:24 +09:30
Daniel O'Connor
c1f171b09e Rubocop: Capybara/NegationMatcher 2026-04-23 12:30:06 +00:00
Daniel O'Connor
ae5c125a96 Rubocop: Layout/IndentationWidth 2026-04-23 12:10:09 +00:00