Finished Implementation

Let’s finalize the test implementation for our Rails application.

We'll cover the following...

We know it’ll make this section even longer, but let’s quickly go through the remainder of the implementation. Here are the remaining tests:

Press + to interact
# test/services/widget_creator_test.rb
assert_equal "finance@example.com", mail_message["to"].to…
assert_match /Stembolt/, mail_message.text_part.to_s
end
→ test "name, price, and manufacturer are required" do
→ result = @widget_creator.create_widget(Widget.new)
→ refute result.created?
→ widget = result.widget
→ assert widget.invalid?
→ assert widget.errors[:name].any? { |message|
→ message =~ /canott be blank/i
→ }, widget.errors.full_messages_for(:name)
→ assert widget.errors[:price_cents].any? { |message|
→ message =~ /is not a number/i
→ }, widget.errors.full_messages_for(:price_cents)
→ assert widget.errors[:manufacturer].any? { |message|
→ message =~ /must exist/i
→ }, widget.errors.full_messages_for(:manufacturer)
→ end
→ test "price cannot be 0" do
→ result = @widget_creator.create_widget(Widget.new(
→ name: "Stembolt",
→ price_cents: 0,
→ manufacturer_id: @manufacturer.id
→ ))
→ refute result.created?
→ assert result.widget.errors[:price_cents].any? { |message|
→ message =~ /greater than 0/i
→ }, result.widget.errors.full_messages_for(:price_cents)
→ end
→ test "price cannot be more than 10,000" do
→ result = @widget_creator.create_widget(Widget.new(
→ name: "Stembolt",
→ price_cents: 10_000_01,
→ manufacturer_id: @manufacturer.id
→ ))
→ refute result.created?
→ assert result.widget.errors[:price_cents].any? { |message|
→ message =~ /less than or equal to 1000000/i
→ }, result.widget.errors.full_messages_for(:price_cents)
→ end
→ test "legacy manufacturers cannot have a price under $100" do
→ legacy_manufacturer = FactoryBot.create(:manufacturer,
→ created_at: DateTime.new(2010,1,1) - 1.day)
→ result = @widget_creator.create_widget(Widget.new(
→ name: "Stembolt",
→ price_cents: 99_00,
→ manufacturer_id: legacy_manufacturer.id
→ ))
→ refute result.created?
→ assert result.widget.errors[:price_cents].any? { |message|
→ message =~ /< \$100.*legacy/i
→ }, result.widget.errors.full_messages_for(:price_cents)
→ end
→ test "email admin staff for widgets on new manufacturers " do
→ new_manufacturer = FactoryBot.create(:manufacturer,
→ name: "Cyberdyne Systems",
→ created_at: 59.days.ago)
→ result = @widget_creator.create_widget(Widget.new(
→ name: "Stembolt",
→ price_cents: 99_00,
→ manufacturer_id: new_manufacturer.id
→ ))
→ assert result.created?
→ assert_equal 1, ActionMailer::Base.deliveries.size
→ mail_message = ActionMailer::Base.deliveries.first
→ assert_equal "admin@example.com", mail_message["to"].to_s
→ assert_match /Stembolt/, mail_message.text_part.to_s
→ assert_match /Cyberdyne Systems/, mail_message.text_part.to_s
→ end
end

The first test (that tests for omitting all of the values) fails, but not in the right way. Our WidgetCreator has a bug, in that it assumes price_cents has a value. We can fix that by early-exiting when we see the widget is invalid:

Press + to interact
# app/services/widget_creator.rb
widget.widget_status =
WidgetStatus.find_by!(name: "Fresh")
widget.save
→ if widget.invalid?
→ return Result.new(created: false, widget: widget)
→ end
if widget.price_cents > 7_500_00
FinanceMailer.high_priced_widget(widget).deliver_now
end

Next, we’ll trigger the mailer to the admin team. We’ll need that mailer:

Press + to interact
# app/mailers/admin_mailer.rb
class AdminMailer < ApplicationMailer
def new_widget_from_new_manufacturer(widget)
@widget = widget
mail to: "admin@example.com"
end
end

Like FinanceMailer, the views can be minimal for now:

<%# app/views/admin_mailer/new_widget_from_new_manufacturer.html.erb
...