diff --git a/Gemfile b/Gemfile index d4fbf7c0..99f5b024 100644 --- a/Gemfile +++ b/Gemfile @@ -35,13 +35,14 @@ gem 'jbuilder', '~> 2.5' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false +gem 'faraday' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rspec-rails' gem 'capybara' - gem 'pry' + gem 'pry-rails' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 9c8920e9..b0f1fc4b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,6 +72,10 @@ GEM diff-lcs (1.4.4) erubi (1.10.0) execjs (2.8.1) + faraday (2.7.4) + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) ffi (1.15.4) globalid (0.5.2) activesupport (>= 5.0) @@ -97,10 +101,14 @@ GEM nio4r (2.5.8) nokogiri (1.12.5-arm64-darwin) racc (~> 1.4) + nokogiri (1.12.5-x86_64-darwin) + racc (~> 1.4) pg (1.2.3) - pry (0.14.1) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) + pry-rails (0.3.9) + pry (>= 0.10.4) public_suffix (4.0.6) puma (3.12.6) racc (1.6.0) @@ -153,6 +161,7 @@ GEM rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-support (3.10.2) + ruby2_keywords (0.0.5) ruby_dep (1.5.0) sass (3.7.4) sass-listen (~> 4.0.0) @@ -199,16 +208,18 @@ GEM PLATFORMS arm64-darwin-20 + x86_64-darwin-21 DEPENDENCIES bootsnap (>= 1.1.0) byebug capybara coffee-rails (~> 4.2) + faraday jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) pg (>= 0.18, < 2.0) - pry + pry-rails puma (~> 3.11) rails (~> 5.2.6) rspec-rails @@ -224,4 +235,4 @@ RUBY VERSION ruby 2.7.4p191 BUNDLED WITH - 2.2.27 + 2.4.4 diff --git a/app/controllers/items_controller.rb b/app/controllers/items_controller.rb new file mode 100644 index 00000000..f74f1f1f --- /dev/null +++ b/app/controllers/items_controller.rb @@ -0,0 +1,9 @@ +class ItemsController < ApplicationController + def index + @items = ItemFacade.all_items + end + + def show + @item = ItemFacade.one_item(params[:id]) + end +end \ No newline at end of file diff --git a/app/controllers/merchants_controller.rb b/app/controllers/merchants_controller.rb new file mode 100644 index 00000000..4038f2fe --- /dev/null +++ b/app/controllers/merchants_controller.rb @@ -0,0 +1,10 @@ +class MerchantsController < ApplicationController + def index + @merchants = MerchantFacade.all_merchants + end + + def show + @merchant = MerchantFacade.one_merchant(params[:id]) + @items = MerchantFacade.one_merchants_items(params[:id]) + end +end \ No newline at end of file diff --git a/app/facades/item_facade.rb b/app/facades/item_facade.rb new file mode 100644 index 00000000..c0361a0a --- /dev/null +++ b/app/facades/item_facade.rb @@ -0,0 +1,15 @@ +class ItemFacade + def self.all_items + response = RailsEngineService.get_all_items + items = response[:data] + + items.map do |data| + Item.new(data) + end + end + + def self.one_item(item_id) + response = RailsEngineService.get_one_item(item_id) + Item.new(response[:data]) + end +end \ No newline at end of file diff --git a/app/facades/merchant_facade.rb b/app/facades/merchant_facade.rb new file mode 100644 index 00000000..e4ec420e --- /dev/null +++ b/app/facades/merchant_facade.rb @@ -0,0 +1,24 @@ +class MerchantFacade + def self.all_merchants + response = RailsEngineService.get_all_merchants + merchants = response[:data] + + merchants.map do |data| + Merchant.new(data) + end + end + + def self.one_merchant(merchant_id) + response = RailsEngineService.get_one_merchant(merchant_id) + Merchant.new(response[:data]) + end + + def self.one_merchants_items(merchant_id) + response = RailsEngineService.get_one_merchants_items(merchant_id) + items = response[:data] + + items.map do |data| + Item.new(data) + end + end +end \ No newline at end of file diff --git a/app/poros/item.rb b/app/poros/item.rb new file mode 100644 index 00000000..b0c079f5 --- /dev/null +++ b/app/poros/item.rb @@ -0,0 +1,12 @@ +class Item + attr_reader :id, + :name, + :description, + :unit_price + def initialize(data) + @id = data[:id] + @name = data[:attributes][:name] + @description = data[:attributes][:description] + @unit_price = data[:attributes][:unit_price] + end +end \ No newline at end of file diff --git a/app/poros/merchant.rb b/app/poros/merchant.rb new file mode 100644 index 00000000..6d47b8d7 --- /dev/null +++ b/app/poros/merchant.rb @@ -0,0 +1,9 @@ +class Merchant + attr_reader :name, + :id + def initialize(data) + @name = data[:attributes][:name] + # binding.pry + @id = data[:id] + end +end \ No newline at end of file diff --git a/app/services/rails_engine_service.rb b/app/services/rails_engine_service.rb new file mode 100644 index 00000000..a302c5c4 --- /dev/null +++ b/app/services/rails_engine_service.rb @@ -0,0 +1,34 @@ +class RailsEngineService + def self.conn + Faraday.new('http://localhost:3000/api/v1/') + end + + def self.json_parse(response) + JSON.parse(response.body, symbolize_names: true) + end + + def self.get_all_merchants + response = conn.get('merchants') + json_parse(response) + end + + def self.get_one_merchant(merchant_id) + response = conn.get("merchants/#{merchant_id}") + json_parse(response) + end + + def self.get_one_merchants_items(merchant_id) + response = conn.get("merchants/#{merchant_id}/items") + json_parse(response) + end + + def self.get_all_items + response = conn.get('items') + json_parse(response) + end + + def self.get_one_item(item_id) + response = conn.get("items/#{item_id}") + json_parse(response) + end +end \ No newline at end of file diff --git a/app/views/items/index.html.erb b/app/views/items/index.html.erb new file mode 100644 index 00000000..4dd4727d --- /dev/null +++ b/app/views/items/index.html.erb @@ -0,0 +1,5 @@ +

Items

+ +<% @items.each do |item| %> +

<%= link_to item.name, "/items/#{item.id}" %>

+<% end %> \ No newline at end of file diff --git a/app/views/items/show.html.erb b/app/views/items/show.html.erb new file mode 100644 index 00000000..9eae47e1 --- /dev/null +++ b/app/views/items/show.html.erb @@ -0,0 +1,4 @@ +

<%= @item.name %>

+ +

Description: <%= @item.description %>

+

Unit price: $<%= @item.unit_price %>

\ No newline at end of file diff --git a/app/views/merchants/index.html.erb b/app/views/merchants/index.html.erb new file mode 100644 index 00000000..834f597f --- /dev/null +++ b/app/views/merchants/index.html.erb @@ -0,0 +1,7 @@ +

Merchants

+ +
+ <% @merchants. each do |merchant| %> +

<%= link_to merchant.name, "/merchants/#{merchant.id}" %>


+ <% end %> +
\ No newline at end of file diff --git a/app/views/merchants/show.html.erb b/app/views/merchants/show.html.erb new file mode 100644 index 00000000..2db9f7f4 --- /dev/null +++ b/app/views/merchants/show.html.erb @@ -0,0 +1,7 @@ +

<%= @merchant.name %>'s Items

+ +
+ <% @items.each do |item| %> +

<%= item.name %>

+ <% end %> +
\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 787824f8..48ff1474 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,6 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + resources :merchants, only:[:index, :show] + resources :items, only:[:index, :show] end diff --git a/spec/facades/item_facade_spec.rb b/spec/facades/item_facade_spec.rb new file mode 100644 index 00000000..b279811a --- /dev/null +++ b/spec/facades/item_facade_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe ItemFacade do + describe 'Item calls' do + it 'all_items' do + items = ItemFacade.all_items + + expect(items).to be_a(Array) + + items.each do |item| + expect(item).to be_instance_of(Item) + end + expect(items[0].name).to eq("Item Nemo Facere") + expect(items[1].name).to eq("Item Expedita Aliquam") + end + + it 'one_item' do + item = ItemFacade.one_item(179) + + expect(item).to be_instance_of(Item) + + expect(item.id).to eq("179") + expect(item.name).to eq("Item Qui Veritatis") + expect(item.description).to eq("Totam labore quia harum dicta eum consequatur qui. Corporis inventore consequatur. Illum facilis tempora nihil placeat rerum sint est. Placeat ut aut. Eligendi perspiciatis unde eum sapiente velit.") + expect(item.unit_price).to eq(906.17) + end + end +end \ No newline at end of file diff --git a/spec/facades/merchant_facade_spec.rb b/spec/facades/merchant_facade_spec.rb new file mode 100644 index 00000000..f56240e1 --- /dev/null +++ b/spec/facades/merchant_facade_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' + +RSpec.describe MerchantFacade do + describe 'merchant calls' do + it 'all_merchants' do + merchants = MerchantFacade.all_merchants + + expect(merchants).to be_a(Array) + + merchants.each do |merchant| + expect(merchant).to be_instance_of(Merchant) + end + expect(merchants[0].name).to eq("Schroeder-Jerde") + expect(merchants[1].name).to eq("Klein, Rempel and Jones") + end + + it 'one_merchant' do + merchant = MerchantFacade.one_merchant(42) + + expect(merchant).to be_instance_of(Merchant) + expect(merchant.id).to eq("42") + expect(merchant.name).to eq("Glover Inc") + end + + it "one_merchants_items" do + items = MerchantFacade.one_merchants_items(99) + + expect(items).to be_a(Array) + + items.each do |item| + expect(item).to be_instance_of(Item) + end + + expect(items[0].name).to eq("Item Excepturi Rem") + expect(items[0].description).to eq("Perferendis reprehenderit fugiat sit eos. Corporis ipsum ut. Natus molestiae quia rerum fugit quis. A cumque doloremque magni.") + expect(items[0].unit_price).to eq(476.82) + end + end +end \ No newline at end of file diff --git a/spec/features/items/item_show_spec.rb b/spec/features/items/item_show_spec.rb new file mode 100644 index 00000000..c35bd79c --- /dev/null +++ b/spec/features/items/item_show_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe "Item show" do + it 'an items show page will list a description and unit price' do + visit "/items/45" + + expect(page).to have_content("Item Id Aut") + expect(page).to have_content("Description: Blanditiis alias cupiditate dolores. Cum architecto est magnam similique quis culpa est. Incidunt consequatur sunt maxime veritatis labore officia. Quaerat nemo molestias et omnis quia.") + expect(page).to have_content("Unit price: $318.76") + end +end \ No newline at end of file diff --git a/spec/features/items/items_index_spec.rb b/spec/features/items/items_index_spec.rb new file mode 100644 index 00000000..01ee40dd --- /dev/null +++ b/spec/features/items/items_index_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +RSpec.describe 'items index', type: :feature do + describe 'visiting /items' do + it 'see list of items by name' do + visit '/items' + + expect(page).to have_content("Item Nemo Facere") + expect(page).to have_content("Item Expedita Aliquam") + expect(page).to have_content("Item Provident At") + expect(page).to have_content("Item Expedita Fuga") + expect(page).to have_content("Item Est Consequuntur") + expect(page).to have_content("Item Quo Magnam") + expect(page).to have_content("Item Quidem Suscipit") + expect(page).to have_content("Item Rerum Magni") + end + end + + it 'can click on an items name and be directed to that items show page' do + visit '/items' + + click_link "Item Nemo Facere" + + expect(current_path).to eq("/items/4") + end +end diff --git a/spec/features/merchants/merchants_index_spec.rb b/spec/features/merchants/merchants_index_spec.rb new file mode 100644 index 00000000..2be32f64 --- /dev/null +++ b/spec/features/merchants/merchants_index_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +RSpec.describe 'merchants index', type: :feature do + describe 'visiting /merchants' do + it 'see list of merchants by name' do + visit '/merchants' + + within "#merchants" do + expect(page).to have_content("Schroeder-Jerde") + expect(page).to have_content("Klein, Rempel and Jones") + end + end + + it 'when a merchants name is clicked the user should be directed to /merchants/:id + and they should see a list of items that merchant sells' do + visit '/merchants' + + click_link 'Schroeder-Jerde' + + expect(current_path).to eq('/merchants/1') + expect(page).to have_content("Schroeder-Jerde's Items") + + within "#items" do + expect(page).to have_content("Item Nemo Facere") + expect(page).to have_content("Item Expedita Aliquam") + expect(page).to have_content("Item Provident At") + expect(page).to have_content("Item Expedita Fuga") + expect(page).to have_content("Item Est Consequuntur") + end + end + end +end \ No newline at end of file diff --git a/spec/poros/item_spec.rb b/spec/poros/item_spec.rb new file mode 100644 index 00000000..663d3ec2 --- /dev/null +++ b/spec/poros/item_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +RSpec.describe Item do + it 'item exists and has attribsutes' do + data = {id: "2425", attributes: {name: "Item Excepture Rem", + description: "Perferendis reprehenderit fugiat sit eos. Corporis ipsum ut. Natus molestiae quia rerum fugit quis. A cumque doloremque magni.", + unit_price: 476.82} + } + item1 = Item.new(data) + + expect(item1).to be_instance_of(Item) + expect(item1.name).to eq("Item Excepture Rem") + expect(item1.description).to eq("Perferendis reprehenderit fugiat sit eos. Corporis ipsum ut. Natus molestiae quia rerum fugit quis. A cumque doloremque magni.") + expect(item1.unit_price).to eq(476.82) + end +end \ No newline at end of file diff --git a/spec/poros/merchant_spec.rb b/spec/poros/merchant_spec.rb new file mode 100644 index 00000000..9058f0a0 --- /dev/null +++ b/spec/poros/merchant_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe Merchant do + it 'merchant exists and has attributes' do + data = {id: 1, attributes: {name: "Albatross Smith"}} + merchant1 = Merchant.new(data) + + expect(merchant1.name).to eq("Albatross Smith") + expect(merchant1.id).to eq(1) + end +end \ No newline at end of file diff --git a/spec/services/rails_engine_service_spec.rb b/spec/services/rails_engine_service_spec.rb new file mode 100644 index 00000000..15a5282a --- /dev/null +++ b/spec/services/rails_engine_service_spec.rb @@ -0,0 +1,85 @@ +require 'rails_helper' + +RSpec.describe RailsEngineService do + describe 'get_all_merchants' do + it 'can return a list of merchants' do + response = RailsEngineService.get_all_merchants + + expect(response).to have_key(:data) + expect(response[:data]).to be_a(Array) + + response[:data].each do |data| + expect(data).to have_key(:id) + expect(data).to have_key(:attributes) + expect(data[:attributes]).to have_key(:name) + end + end + end + + describe 'get_one_merchant' do + it 'can return one merchant response' do + response = RailsEngineService.get_one_merchant(42) + + expect(response).to have_key(:data) + expect(response[:data]).to be_a(Hash) + expect(response[:data]).to have_key(:id) + expect(response[:data][:attributes]).to have_key(:name) + + expect(response[:data][:id]).to eq("42") + expect(response[:data][:attributes][:name]).to eq("Glover Inc") + end + end + + describe 'get_one_merchants_items' do + it 'can return all the items for an individual merchant' do + response = RailsEngineService.get_one_merchants_items(99) + + expect(response).to have_key(:data) + expect(response[:data]).to be_a(Array) + + response[:data].each do |item| + expect(item).to have_key(:id) + expect(item[:attributes]).to have_key(:name) + expect(item[:attributes]).to have_key(:description) + expect(item[:attributes]).to have_key(:unit_price) + expect(item[:attributes]).to have_key(:merchant_id) + end + + expect(response[:data][0][:attributes][:name]).to eq("Item Excepturi Rem") + expect(response[:data][0][:attributes][:merchant_id]).to eq(99) + end + end + + describe 'get_all_items' do + it 'returns all items' do + response = RailsEngineService.get_all_items + + expect(response).to have_key(:data) + expect(response[:data]).to be_a(Array) + + response[:data].each do |item| + expect(item).to have_key(:id) + expect(item[:attributes]).to have_key(:name) + expect(item[:attributes]).to have_key(:description) + expect(item[:attributes]).to have_key(:unit_price) + expect(item[:attributes]).to have_key(:merchant_id) + end + end + end + + describe 'get_one_item' do + it 'gets an item based on id' do + response = RailsEngineService.get_one_item(179) + + expect(response).to have_key(:data) + expect(response[:data]).to be_a(Hash) + expect(response[:data]).to have_key(:id) + expect(response[:data][:attributes]).to have_key(:name) + expect(response[:data][:attributes]).to have_key(:description) + expect(response[:data][:attributes]).to have_key(:unit_price) + + expect(response[:data][:id]).to eq("179") + expect(response[:data][:attributes][:name]).to eq("Item Qui Veritatis") + end + end +end \ No newline at end of file