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 validation for supply product #378

Merged
Merged
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
27 changes: 26 additions & 1 deletion rails_application/app/controllers/supplies_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
class SuppliesController < ApplicationController
class SupplyForm
include ActiveModel::Model
include ActiveModel::Validations

attr_reader :product_id, :quantity

def initialize(params)
@product_id = params[:product_id]
@quantity = params[:quantity]
end
Comment on lines +3 to +11
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't use ActiveModel::Attributes like in other places because then only_integer: true does not work as expected. It seems like ActiveModel::Attributes converts the value to integer during the initialization of the object. This is problematic because "abc".to_i # => 0, so the validation error was "Quantity must be greater than 0" instead of "Quantity is not a number".


validates :product_id, presence: true
validates :quantity, presence: true, numericality: { only_integer: true, greater_than: 0, allow_blank: true }
end

def new
@product_id = params[:product_id]
end

def create
supply(params[:product_id], params[:quantity])
supply_form = SupplyForm.new(supply_params)

unless supply_form.valid?
return render "new", locals: { errors: supply_form.errors }, status: :unprocessable_entity
end

supply(supply_form.product_id, supply_form.quantity.to_i)
redirect_to products_path, notice: "Stock level changed"
end

Expand All @@ -15,4 +36,8 @@ def supply(product_id, quantity)
Inventory::Supply.new(product_id: product_id, quantity: quantity)
)
end

def supply_params
params.permit(:product_id, :quantity)
end
end
12 changes: 11 additions & 1 deletion rails_application/app/views/supplies/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,15 @@
<label for="quantity" class="block font-bold">
Quantity
</label>
<%= number_field_tag :quantity, nil, min: 1, step: 1, id: "quantity", class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
<%= number_field_tag :quantity, nil, min: 1, step: 1, id: "quantity",
class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md",
data: { turbo_permanent: true } %>

<% if defined?(errors) %>
<% errors.each do |error| %>
<div class="mt-2 text-red-600">
<span><%= error.full_message %></span>
</div>
<% end %>
<% end %>
<% end %>
67 changes: 67 additions & 0 deletions rails_application/test/integration/supplies_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require "test_helper"

class SuppliesTest < InMemoryRESIntegrationTestCase
def test_happy_path
product_id = register_product("Async Remote", 100, 10)

get "/products/#{product_id}/supplies/new"
assert_select "h1", "Supply"
post "/products/#{product_id}/supplies",
params: {
"authenticity_token" => "[FILTERED]",
"product_id" => product_id,
"quantity" => "1"
}
follow_redirect!

assert_select "#notice", "Stock level changed"
end

def test_renders_validation_error_when_quantity_is_not_present
product_id = register_product("Async Remote", 100, 10)

get "/products/#{product_id}/supplies/new"
assert_select "h1", "Supply"
post "/products/#{product_id}/supplies",
params: {
"authenticity_token" => "[FILTERED]",
"product_id" => product_id,
"quantity" => ""
}

assert_response :unprocessable_entity
assert_select "span", "Quantity can't be blank"
end

def test_renders_validation_error_when_quantity_is_not_a_number
product_id = register_product("Async Remote", 100, 10)

get "/products/#{product_id}/supplies/new"
assert_select "h1", "Supply"
post "/products/#{product_id}/supplies",
params: {
"authenticity_token" => "[FILTERED]",
"product_id" => product_id,
"quantity" => "not a number"
}

assert_response :unprocessable_entity
assert_select "span", "Quantity is not a number"
end

def test_renders_validation_error_when_quantity_is_zero
product_id = register_product("Async Remote", 100, 10)

get "/products/#{product_id}/supplies/new"
assert_select "h1", "Supply"
post "/products/#{product_id}/supplies",
params: {
"authenticity_token" => "[FILTERED]",
"product_id" => product_id,
"quantity" => "0"
}

assert_response :unprocessable_entity
assert_select "span", "Quantity must be greater than 0"
end
end