mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-10-31 03:09:06 -04:00
* Implement AddSeedsPicker component and enhance planting selection UI; update styles and serializers for better seed management * Enhance PlantingPicker component: add hints and titles for harvest and seed actions; update test to reflect changes in seed saving behavior * Enhance harvest recording: allow harvesting from crops without plantings; update forms and modals for better user experience * Refactor code structure for improved readability and maintainability * Remove AddSeedsPicker component and its associated tests * Add planting picker functionality for harvesting and seed saving - Introduced PlantingPickersController to handle JSON responses for member's plantings. - Updated HomeHelper to include crop ID in planting picker properties. - Refactored PlantPicker and PlantSomethingModal components to support multiple gardens. - Created PlantingFlow component to manage planting actions (harvest and save seeds). - Implemented RecordDialog component to handle server-rendered links for harvesting and seed saving. - Updated various views to include data attributes for triggering the record dialog. - Added routes for planting picker and corresponding request specs for testing. - Adjusted styles in _plantings.scss for better layout and spacing. * Add job management features including job creation and wishlist functionality * Remove WishlistJobsController and associated views and tests * Add suggestion links rendering and fix routes formatting * Refactor AddJobModal and JobPicker components to simplify props and enhance user experience * Update seed addition test to check dialog presence and current path * Apply suggestion from @CloCkWeRX --------- Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
98 lines
3.9 KiB
Ruby
98 lines
3.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
# GET /plantings/:slug/seeds/new.json and POST /seeds.json are for our own React
|
|
# garden cards only: session cookie and CSRF token, same origin.
|
|
describe 'Saving seeds as JSON' do
|
|
include Devise::Test::IntegrationHelpers
|
|
|
|
let(:member) { create(:london_member) }
|
|
let(:garden) { create(:garden, owner: member) }
|
|
let(:crop) { create(:annual_crop, name: 'lettuce') }
|
|
let!(:planting) { create(:planting, garden: garden, owner: member, crop: crop) }
|
|
let(:json_headers) { { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' } }
|
|
|
|
def save_seeds(**attributes)
|
|
post '/seeds.json', params: { seed: { parent_planting_id: planting.id, saved_at: '2026-09-21', quantity: 40,
|
|
tradable_to: 'locally', description: 'Bolted early', **attributes } }.to_json,
|
|
headers: json_headers
|
|
end
|
|
|
|
describe 'loading the form' do
|
|
before { sign_in member }
|
|
|
|
it 'gives the crop, the trade choices and where the member is' do
|
|
get "/plantings/#{planting.slug}/seeds/new.json", headers: { 'ACCEPT' => 'application/json' }
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(response.parsed_body).to include(
|
|
'crop' => { 'id' => crop.id, 'name' => 'lettuce' }, 'parent_planting_id' => planting.id,
|
|
'tradable_to_values' => %w(nowhere locally nationally internationally),
|
|
'location' => 'Greenwich, UK', 'settings_url' => '/members/edit'
|
|
)
|
|
expect(response.parsed_body['saved_at']).to eq Time.zone.today.to_s
|
|
end
|
|
|
|
it 'gives a form for a crop with no planting' do
|
|
get "/seeds/new.json?crop_id=#{crop.id}", headers: { 'ACCEPT' => 'application/json' }
|
|
|
|
expect(response.parsed_body).to include('crop' => { 'id' => crop.id, 'name' => 'lettuce' }, 'parent_planting_id' => nil)
|
|
end
|
|
|
|
it 'has no location when the member has not set one' do
|
|
member.update_columns(location: nil)
|
|
|
|
get "/plantings/#{planting.slug}/seeds/new.json", headers: { 'ACCEPT' => 'application/json' }
|
|
|
|
expect(response.parsed_body['location']).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when signed in' do
|
|
before { sign_in member }
|
|
|
|
it 'saves the seeds from the planting and returns a link to them' do
|
|
expect { save_seeds }.to change { planting.child_seeds.count }.by(1)
|
|
|
|
expect(response).to have_http_status(:created)
|
|
seed = planting.child_seeds.last
|
|
expect(response.parsed_body['seed']).to eq('id' => seed.id, 'url' => "/seeds/#{seed.slug}")
|
|
expect(seed).to have_attributes(owner: member, crop: crop, quantity: 40, tradable_to: 'locally',
|
|
description: 'Bolted early', source: 'my own seed saving', saved_at: Date.new(2026, 9, 21))
|
|
end
|
|
|
|
it 'saves seeds of a crop with no planting' do
|
|
expect do
|
|
post '/seeds.json', params: { seed: { crop_id: crop.id, source: 'retail outlet' } }.to_json, headers: json_headers
|
|
end.to change(member.seeds, :count).by(1)
|
|
end
|
|
|
|
it 'does not queue a flash message for the next page' do
|
|
save_seeds
|
|
|
|
get root_path
|
|
expect(response.body).not_to include('to your stash')
|
|
end
|
|
|
|
it 'takes seeds with no quantity or notes' do
|
|
expect { save_seeds(quantity: '', description: '', tradable_to: 'nowhere') }.to change(Seed, :count).by(1)
|
|
|
|
expect(Seed.last).to have_attributes(quantity: nil, tradable_to: 'nowhere')
|
|
end
|
|
|
|
it 'returns the validation errors as 422 and saves nothing' do
|
|
expect { save_seeds(tradable_to: 'the moon') }.not_to(change(Seed, :count))
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
expect(response.parsed_body['errors']).to have_key('tradable_to')
|
|
end
|
|
end
|
|
|
|
it 'asks a visitor who is not signed in to sign in' do
|
|
expect { save_seeds }.not_to(change(Seed, :count))
|
|
|
|
expect(response).to have_http_status(:unauthorized)
|
|
end
|
|
end
|