diff --git a/app/controllers/listings_controller.rb b/app/controllers/listings_controller.rb index ac9a66d..6ec07b0 100644 --- a/app/controllers/listings_controller.rb +++ b/app/controllers/listings_controller.rb @@ -9,6 +9,10 @@ def new @listing = Listing.new end + def show + @listing = Listing.find(params[:id]) + end + def create listing = Listing.create(listing_params) diff --git a/app/controllers/offers_controller.rb b/app/controllers/offers_controller.rb new file mode 100644 index 0000000..4f9d85c --- /dev/null +++ b/app/controllers/offers_controller.rb @@ -0,0 +1,26 @@ +class OffersController < ApplicationController + def index + @offers = Offer.all + end + + def new + offer = Offer.new(offer_params) + end + + def create + @listing = Listing.find(params[:listing_id]) + @offer = @listing.offers.create(offer_params) + + if @offer.persisted? + redirect_to root_path + else + redirect_to listing_path(@listing), notice: "Please fill in all fields correctly" + end + end + + + private + def offer_params + params.require(:offer).permit(:name, :email, :location, :price) + end +end \ No newline at end of file diff --git a/app/models/listing.rb b/app/models/listing.rb index ce2f2ed..8f5cebc 100644 --- a/app/models/listing.rb +++ b/app/models/listing.rb @@ -1,3 +1,4 @@ class Listing < ApplicationRecord + has_many :offers validates_presence_of :pet_name, :pet_location, :pet_description, :start_date, :end_date, :pet_picture -end +end \ No newline at end of file diff --git a/app/models/offer.rb b/app/models/offer.rb new file mode 100644 index 0000000..38035cc --- /dev/null +++ b/app/models/offer.rb @@ -0,0 +1,4 @@ +class Offer < ApplicationRecord + belongs_to :listing + validates_presence_of :name, :email, :location, :price +end diff --git a/app/views/listings/index.html.haml b/app/views/listings/index.html.haml index 4bf7960..827e6e6 100644 --- a/app/views/listings/index.html.haml +++ b/app/views/listings/index.html.haml @@ -7,3 +7,4 @@ %p= listing.start_date %p= listing.end_date %p= listing.pet_picture + = link_to 'Make an offer', listing_path(listing) \ No newline at end of file diff --git a/app/views/listings/show.html.haml b/app/views/listings/show.html.haml new file mode 100644 index 0000000..05f4006 --- /dev/null +++ b/app/views/listings/show.html.haml @@ -0,0 +1,26 @@ +%h1= @listing.pet_name +%p=@listing.pet_location +%p=@listing.pet_description +%p Dates: #{@listing.start_date} to #{@listing.end_date} +%p=@listing.pet_picture + +%h2 Create your offer += form_with(model: [ @listing, @listing.offers.build ], local: true) do |form| + %p + = form.label :name + %br/ + = form.text_field :name + %p + = form.label :email + %br/ + = form.text_field :email + %p + = form.label :location + %br/ + = form.text_area :location + %p + = form.label :price + %br/ + = form.number_field :price + %p + = form.submit "Create offer" \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 54a2b83..8eddb08 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,9 +2,8 @@ devise_for :users root controller: :listings, action: :index - - resources :listings, only: [:new, :create] - resources :profiles, only: [:new, :create] - -end + resources :listings, only: [:new, :show, :create] do + resources :offers + end +end \ No newline at end of file diff --git a/db/migrate/20190509113524_create_offers.rb b/db/migrate/20190509113524_create_offers.rb new file mode 100644 index 0000000..fa06fc4 --- /dev/null +++ b/db/migrate/20190509113524_create_offers.rb @@ -0,0 +1,12 @@ +class CreateOffers < ActiveRecord::Migration[5.2] + def change + create_table :offers do |t| + t.string :name + t.string :email + t.string :location + t.integer :price + + t.timestamps + end + end +end diff --git a/db/migrate/20190509121804_add_listing_to_offers.rb b/db/migrate/20190509121804_add_listing_to_offers.rb new file mode 100644 index 0000000..fef522d --- /dev/null +++ b/db/migrate/20190509121804_add_listing_to_offers.rb @@ -0,0 +1,5 @@ +class AddListingToOffers < ActiveRecord::Migration[5.2] + def change + add_reference :offers, :listing, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 752a008..65c97cb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -26,6 +26,17 @@ t.string "pet_picture" end + create_table "offers", force: :cascade do |t| + t.string "name" + t.string "email" + t.string "location" + t.integer "price" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "listing_id" + t.index ["listing_id"], name: "index_offers_on_listing_id" + end + create_table "profiles", force: :cascade do |t| t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -49,5 +60,6 @@ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "offers", "listings" add_foreign_key "profiles", "users" end diff --git a/features/host_can_make_offer_on_listing.feature b/features/host_can_make_offer_on_listing.feature new file mode 100644 index 0000000..08b5eb1 --- /dev/null +++ b/features/host_can_make_offer_on_listing.feature @@ -0,0 +1,38 @@ +Feature: Host can make an offer on a listing + As a host, + In order to make some money, + I want to be able to make an offer on a listing + + Background: + Given the following listings exist + | pet_name | pet_location | pet_description | start_date | end_date | pet_picture | + | Zane | Gothenburg | I'm nice | 2019-06-28 | 2019-06-29 | picture1 | + | Carla | Stockholm | I love cats! | 2019-05-28 | 2019-06-01 | picture2 | + + Given the following user exist + | email | password | + | boa@snake.se | pswrd12345 | + + Given I am logged in as "boa@snake.se" + When I visit the landing page + + Scenario: Host can successfully create an offer + When I click "Make an offer" within "Zane" section + Then I should be on the "Zane" listing page + And I should see "Create your offer" + When I fill in "Name" with "Steffe" + And I fill in "Email" with "steffe@gmail.com" + And I fill in "Location" with "Gothenburg" + And I fill in "Price" with "100kr" + When I click "Create offer" button + Then I should be on landing page + + Scenario: Host can not create an offer when not all the fields are filled in. + When I click "Make an offer" within "Zane" section + Then I should be on the "Zane" listing page + And I should see "Create your offer" + And I fill in "Name" with "Steffe" + And I fill in "Location" with "Gothenburg" + And I fill in "Price" with "100kr" + When I click "Create offer" button + Then I should see "Please fill in all fields correctly" \ No newline at end of file diff --git a/features/step_definitions/assertion_steps.rb b/features/step_definitions/assertion_steps.rb index 937d69a..b5cc36a 100644 --- a/features/step_definitions/assertion_steps.rb +++ b/features/step_definitions/assertion_steps.rb @@ -22,10 +22,16 @@ expect(current_path).to eq root_path end +Then("I should be on the {string} listing page") do |listing_name| + name = Listing.find_by(pet_name: listing_name) + expect(current_path).to eq listing_path(name) +end + Then("I should be on Create profile page") do expect(current_path).to eq new_profile_path end + Then("I should be on the Log in page") do expect(current_path).to eq new_user_session_path end diff --git a/features/step_definitions/basic_steps.rb b/features/step_definitions/basic_steps.rb index 6d8cab3..5cf0b39 100644 --- a/features/step_definitions/basic_steps.rb +++ b/features/step_definitions/basic_steps.rb @@ -18,6 +18,21 @@ click_button button end +When("I click on {string} within {string} section") do |content, section| + name = Listing.find_by(pet_name: section) + dom_section = "#listing_#{name.id}" + within(dom_section) do + expect(page).to have_content content + end +end + +When("I click {string} within {string} section") do |link, section| + name = Listing.find_by(pet_name: section) + dom_section = "#listing_#{name.id}" + within(dom_section) do + click_on link + end +end Then "stop" do binding.pry end diff --git a/spec/factories/offers.rb b/spec/factories/offers.rb new file mode 100644 index 0000000..17ec0f6 --- /dev/null +++ b/spec/factories/offers.rb @@ -0,0 +1,9 @@ +FactoryBot.define do + factory :offer do + name { "MyString" } + email { "MyString" } + location { "MyString" } + price { 1 } + listing + end +end \ No newline at end of file diff --git a/spec/models/listing_spec.rb b/spec/models/listing_spec.rb index 795f43e..4c3ad14 100644 --- a/spec/models/listing_spec.rb +++ b/spec/models/listing_spec.rb @@ -20,6 +20,10 @@ it { is_expected.to validate_presence_of :pet_picture } end + describe 'Associations' do + it { is_expected.to have_many(:offers)} + end + describe 'Factory' do it 'should have a valid Factory' do expect(FactoryBot.create(:listing)).to be_valid diff --git a/spec/models/offer_spec.rb b/spec/models/offer_spec.rb new file mode 100644 index 0000000..87098af --- /dev/null +++ b/spec/models/offer_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe Offer, type: :model do + describe 'DB table' do + it { is_expected.to have_db_column :id } + it { is_expected.to have_db_column :name } + it { is_expected.to have_db_column :email } + it { is_expected.to have_db_column :location } + it { is_expected.to have_db_column :price } + end + + describe 'Validations' do + it { is_expected.to validate_presence_of :name } + it { is_expected.to validate_presence_of :email } + it { is_expected.to validate_presence_of :location } + it { is_expected.to validate_presence_of :price } + end + + describe 'Associations' do + it { is_expected.to belong_to(:listing)} + end + + describe 'Factory' do + it 'should have a valid Factory' do + expect(FactoryBot.create(:offer)).to be_valid + end + end +end \ No newline at end of file