Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be us 17 recipe update #54

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.3-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.3-x86_64-darwin)
racc (~> 1.4)
pg (1.5.3)
Expand Down Expand Up @@ -216,6 +218,7 @@ GEM
zeitwerk (2.6.9)

PLATFORMS
arm64-darwin-22
x86_64-darwin-21
x86_64-darwin-22

Expand Down
36 changes: 36 additions & 0 deletions app/controllers/api/v1/recipes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,51 @@ def create
render json: RecipeSerializer.new(created_recipe), status: :created
end

def update
# Maybe, add find_recipe callback, so it stops if a recipe does not exists?
# For example, "The Recipe you requested does not exist."
# require 'pry'; binding.pry
if recipe_params[:api_id].nil?

# updated_recipe = @recipe.update(recipe_params)
# ^^^ Ultimately would like to refactor to this code, after a find_recipe before_callback
# has been successfully created. For now going with code below:
recipe = Recipe.find(params[:id]).update!(recipe_params)
updated_recipe = Recipe.find(params[:id])

if params.has_key?(:ingredients) && !params[:ingredients].empty?
updated_ingredients = ingredients_params(params)
updated_recipe.ingredients.destroy_all
updated_ingredients.each do |updated_ingredient|
updated_recipe.ingredients.create!(updated_ingredient)
end
end
render json: RecipeSerializer.new(updated_recipe), status: :ok
else
# SAD PATH - code to let user know they "You do not have access to update this recipe"
# Maybe this is a front-end problem???
# render json ErrorSerializer.new(:alert)
end
end

private

def recipe_params
params.require(:recipe).permit(:name, :instructions, :image_url, :cook_time, :public_status, :source_name,
:source_url, :user_submitted, :api_id)
end

def ingredients_params(params)
params.require(:ingredients).map do |ingredient|
ingredient.permit(:name, :instructions, :units, :unit_type)
end
end

def format_instructions(instruction)
add_commas = instruction.prepend(',') + ','
add_commas.gsub(', ', ',')
end

#Potential method for #find_recipe to be used as a callback before the recipes#show and recipes#update

end
187 changes: 187 additions & 0 deletions spec/requests/api/v1/recipes/update_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
require 'rails_helper'

describe 'Recipe API' do
let!(:user_1) { User.create!(uid: '123') }
let!(:recipe_1) { Recipe.create!(
name: 'Salad',
instructions: ",1. Eat it!,",
image_url: "www.image.com",
cook_time: 5,
public_status: true,
source_name: "Chef Mike",
source_url: "www.chefmike.com",
user_submitted: true
)
}

describe 'PUT api_v1_recipe_path' do
describe 'happy paths' do
it 'can update one recipe' do
id = recipe_1.id
created_recipe = Recipe.last

recipe_params = {
name: 'Dope Salad',
instructions: ",1. Rinse spinach and lettuce, 2. Get out that dressing give it a shake, 3. Add chickpeas and tomatoes and strawberries, 4. Shake it off yeah yeah shake it off,",
cook_time: 10,
public_status: true,
source_name: "Chef Mateo",
source_url: "www.chefmateo.com",
user_submitted: false
}

headers = { 'CONTENT_TYPE' => 'application/json' }
put api_v1_recipe_path(recipe_1), headers:, params: JSON.generate(recipe: recipe_params)

updated_recipe = Recipe.last

expect(response).to be_successful

expect(updated_recipe.id).to eq(created_recipe.id)
expect(updated_recipe.public_status).to eq(created_recipe.public_status)

expect(updated_recipe.name).to_not eq(created_recipe.name)
expect(updated_recipe.name).to eq("Dope Salad")

expect(updated_recipe.instructions).to_not eq(created_recipe.instructions)
expect(updated_recipe.instructions).to eq(["1. Rinse spinach and lettuce", " 2. Get out that dressing give it a shake", " 3. Add chickpeas and tomatoes and strawberries", " 4. Shake it off yeah yeah shake it off"])

expect(updated_recipe.cook_time).to_not eq(created_recipe.cook_time)
expect(updated_recipe.cook_time).to eq(10)

expect(updated_recipe.source_name).to_not eq(created_recipe.source_name)
expect(updated_recipe.source_name).to eq("Chef Mateo")

expect(updated_recipe.source_url).to_not eq(created_recipe.source_url)
expect(updated_recipe.source_url).to eq("www.chefmateo.com")

expect(updated_recipe.user_submitted).to_not eq(created_recipe.user_submitted)
expect(updated_recipe.user_submitted).to be(false)
end

it 'can update ingredients and recipe_ingredients during recipe update' do
recipe_params = {
name: 'Salad',
instructions: '1. Rinse spinach and lettuce, 4. Shake it off yeah yeah shake it off',
cook_time: 5,
public_status: true,
source_name: "Chef Mike",
source_url: "www.chefmike.com",
user_submitted: true
}

ingredients_params = [
{
name: 'Spinach',
units: 1.0,
unit_type: 'cups'
},
{
name: 'Lettuce',
units: 1.0,
unit_type: 'cups'
},
{
name: 'Vegan Ranch',
units: 0.5,
unit_type: 'cups'
},
{
name: 'Chickpeas',
units: 0.5,
unit_type: 'cups'
},
{
name: 'Cherry Tomatoes',
units: 0.5,
unit_type: 'cups'
},
{
name: 'Strawberries',
units: 0.25,
unit_type: 'cups'
}
]

headers = { 'CONTENT_TYPE' => 'application/json' }
post api_v1_recipes_path, headers:,
params: JSON.generate(recipe: recipe_params, ingredients: ingredients_params)

created_recipe = Recipe.last
id = created_recipe.id

update_recipe_params = {
name: 'Dope Salad',
instructions: ",1. Rinse spinach and lettuce, 2. Get out that dressing give it a shake, 3. Add chickpeas and tomatoes and strawberries, 4. Shake it off yeah yeah shake it off,",
cook_time: 10,
public_status: true,
source_name: "Chef Mateo",
source_url: "www.chefmateo.com",
user_submitted: false
}

update_ingredients_params = [
{
name: 'Cabbage',
units: 2.0,
unit_type: 'ounces'
},
{
name: 'Tomatoes',
units: 1.0,
unit_type: 'ounces'
}
]

put api_v1_recipe_path(created_recipe), headers:, params: JSON.generate(recipe: update_recipe_params, ingredients: update_ingredients_params)


updated_recipe = Recipe.last
first_ingredient = updated_recipe.ingredients.first
last_ingredient = updated_recipe.ingredients.last
expect(updated_recipe.ingredients.count).to eq(2)

expect(first_ingredient.name).to_not eq(ingredients_params.first[:name])
expect(first_ingredient.name).to eq(update_ingredients_params.first[:name])
expect(first_ingredient.name).to eq("Cabbage")

expect(first_ingredient.units).to_not eq(ingredients_params.first[:units])
expect(first_ingredient.units).to eq(update_ingredients_params.first[:units])
expect(first_ingredient.units).to eq(2.0)

expect(first_ingredient.unit_type).to_not eq(ingredients_params.first[:unit_type])
expect(first_ingredient.unit_type).to eq(update_ingredients_params.first[:unit_type])
expect(first_ingredient.unit_type).to eq('ounces')

expect(last_ingredient.name).to_not eq(ingredients_params.last[:name])
expect(last_ingredient.name).to eq(update_ingredients_params.last[:name])
expect(last_ingredient.name).to eq("Tomatoes")
end
end

# describe 'sad paths' do
# it 'will not update a recipe without a name' do
# recipe_params = {
# instructions: '1. Rinse spinach and lettuce, 2. Get out that dressing give it a shake, 3. Add chickpeas and tomatoes and strawberries, 4. Shake it off yeah yeah shake it off',
# cook_time: 10,
# public_status: true,
# source_name: user_1.uid,
# source_url: api_v1_user_path(user_1),
# user_submitted: true
# }

# headers = { 'CONTENT_TYPE' => 'application/json' }
# post api_v1_recipes_path, headers:, params: JSON.generate(recipe: recipe_params)

# expect(response).to_not be_successful
# expect(response.status).to eq(404)

# data = JSON.parse(response.body, symbolize_names: true)

# expect(data[:errors]).to be_a(Array)
# expect(data[:errors].first[:status]).to eq('404')
# expect(data[:errors].first[:title]).to eq("Validation failed: Name can't be blank")
# end
# end
end
end