diff --git a/Gemfile b/Gemfile index 66526d43..1446f3d9 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ gem 'rspec', '~> 2.14.1' gem 'sinatra', '~> 1.4.5' gem 'sinatra-contrib', '~> 1.4.2' gem 'rest-client' +gem 'pg' # Testing gem 'pry-byebug' diff --git a/Gemfile.lock b/Gemfile.lock index bbeebb1e..f4cf3bf0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,6 +14,7 @@ GEM mime-types (1.25.1) multi_json (1.10.1) netrc (0.8.0) + pg (0.17.1) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -55,6 +56,7 @@ PLATFORMS ruby DEPENDENCIES + pg pry-byebug rest-client rspec (~> 2.14.1) diff --git a/README.md b/README.md new file mode 100644 index 00000000..36f201de --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +bundle exec rake db:create +bundle exec rake db:create_tables +bundle exec rake db:seed + +bundle exec rspec + +bundle exec rackup -p 4567 diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..4d551e6d --- /dev/null +++ b/Rakefile @@ -0,0 +1,61 @@ + +task :environment do + require './lib/petshop.rb' +end + +task :console => :environment do + require 'irb' + ARGV.clear + IRB.start +end + + +namespace :db do + + task :create do + `createdb petshop_dev` + `createdb petshop_test` + puts "Created." + end + + task :drop do + `dropdb petshop_dev` + `dropdb petshop_test` + puts "Dropped." + end + + task :create_tables => :environment do + db1 = PetShop.create_db_connection('petshop_test') + db2 = PetShop.create_db_connection('petshop_dev') + PetShop.create_tables(db1) + PetShop.create_tables(db2) + puts "Created tables." + end + + task :drop_tables => :environment do + db1 = PetShop.create_db_connection('petshop_test') + db2 = PetShop.create_db_connection('petshop_dev') + PetShop.drop_tables(db1) + PetShop.drop_tables(db2) + puts "Dropped tables." + end + + task :clear => :environment do + # The test db clears all the time, so there's no point in doing it here. + db = PetShop.create_db_connection('petshop_dev') + db1 = PetShop.create_db_connection('petshop_test') + PetShop.drop_tables(db) + PetShop.drop_tables(db1) + PetShop.create_tables(db) + PetShop.create_tables(db1) + puts "Cleared tables." + end + + task :seed => :environment do + db = PetShop.create_db_connection('petshop_dev') + db1 = PetShop.create_db_connection('petshop_test') + PetShop.seed_db(db) + puts "Seeded." + end + +end diff --git a/config.ru b/config.ru new file mode 100644 index 00000000..159ba053 --- /dev/null +++ b/config.ru @@ -0,0 +1,8 @@ +require './server' + +# set up db tables +db = PetShop.create_db_connection 'petshop_dev' +PetShop.create_tables db + +# run web app +run PetShop::Server diff --git a/lib/petshop.rb b/lib/petshop.rb new file mode 100644 index 00000000..b7cd8ddd --- /dev/null +++ b/lib/petshop.rb @@ -0,0 +1,98 @@ +require 'pg' + +module PetShop + def self.create_db_connection(dbname) + PG.connect(host: 'localhost', dbname: dbname) + end + + def self.clear_db(db) + db.exec <<-SQL + DELETE FROM cats; + DELETE FROM dogs; + DELETE FROM shops; + DELETE FROM owners; + SQL + end + + def self.create_tables(db) + db.exec <<-SQL + CREATE TABLE IF NOT EXISTS shops( + id SERIAL PRIMARY KEY, + name VARCHAR + ); + CREATE TABLE IF NOT EXISTS owners( + id SERIAL PRIMARY KEY, + username VARCHAR, + password VARCHAR + ); + CREATE TABLE IF NOT EXISTS cats( + id SERIAL PRIMARY KEY, + name VARCHAR, + shopid INT references shops (id), + owner_id INT references owners (id), + imageurl TEXT, + adopted VARCHAR + ); + CREATE TABLE IF NOT EXISTS dogs( + id SERIAL PRIMARY KEY, + name VARCHAR, + shopid INT references shops (id), + owner_id INT references owners (id), + imageurl TEXT, + adopted VARCHAR + ); + + SQL + end + + def self.drop_tables(db) + db.exec <<-SQL + DROP TABLE cats; + DROP TABLE dogs; + DROP TABLE shops; + DROP TABLE owners; + SQL + end + + def self.seed_db(db) + db.exec <<-SQL + -- Insert Shops + INSERT INTO shops (name) values ('Store Prime'); + INSERT INTO shops (name) values ('Canineite'); + INSERT INTO shops (name) values ('Poochy Paradise'); + SQL + + db.exec <<-SQL + -- Insert Owners + INSERT INTO owners (username, password) values ('Jason', 'pass'); + INSERT INTO owners (username, password) values ('Alex', 'pass'); + SQL + + db.exec <<-SQL + -- Insert Dogs + INSERT INTO dogs (name, shopid, imageurl, adopted) values + ('Sam The Pup', 2, 'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSMp3Zb-s_O38HlY4x9xPI0k0cJ8_DtEH4zJ4mKCt_4sGapVOOYrw', 'false'); + INSERT INTO dogs (name, shopid, imageurl, adopted) values + ('Bark', 1, 'http://animal-backgrounds.com/download/1092/1920x1200/crop/cute-and-funny-small-dog-wallpaper-1920x1200.jpg', 'false'); + INSERT INTO dogs (name, shopid, imageurl, adopted) values + ('Woof', 3, 'http://www.bobtail-chiens.com/medias/images/24-04-2011-gustave.jpg', 'false'); + INSERT INTO dogs (name, shopid, imageurl, adopted) values + ('Growl', 2, 'http://www.smalldogbreedsdb.com/wp-content/uploads/EasyRotatorStorage/user-content/erc_66_1381848811/content/assets/Beagle-3.jpg-0.jpg', 'false'); + SQL + + db.exec <<-SQL + -- Cats + INSERT INTO cats (name, shopid, imageurl, adopted) values + ('Lammie', 1, 'https://c2.staticflickr.com/8/7418/9738381563_0ac7da6cdc_b.jpg', 'false'); + INSERT INTO cats (name, shopid, imageurl, adopted) values + ('Joja', 2, 'http://wallpaper-download.net/wallpapers/animal-wallpapers-african-lion-king-wallpaper-31870.jpg', 'false'); + INSERT INTO cats (name, shopid, imageurl, adopted) values + ('Biboo', 3, 'http://alabamapioneers.com/ap2/wp-content/uploads/2014/06/black_panther-t2.jpg', 'false'); + SQL + end +end + +require_relative 'petshop/shop_repo' +require_relative 'petshop/owner_repo' +require_relative 'petshop/dog_repo' +require_relative 'petshop/cat_repo' diff --git a/lib/petshop/cat_repo.rb b/lib/petshop/cat_repo.rb new file mode 100644 index 00000000..b5af310b --- /dev/null +++ b/lib/petshop/cat_repo.rb @@ -0,0 +1,56 @@ +require 'pry-byebug' + +module PetShop + class CatRepo + + def self.all(db) + result = db.exec("SELECT * FROM cats").to_a + end + + def self.find(db, cat_id) + cat = db.exec("SELECT * FROM cats WHERE id=$1", [cat_id]).first + end + + def self.find_all_by_shop(db, shopid) + cats = db.exec("SELECT * FROM cats WHERE shopid=$1", [shopid]).to_a + end + + def self.find_all_by_owner(db, owner_id) + cats = db.exec("SELECT * FROM cats WHERE owner_id=$1", [owner_id]).to_a + end + + def self.save(db, cat_data) + if cat_data['id'] # Update an Existing Cat + + # Ensure cat exists + cat = find(db, cat_data['id']) + raise "A valid cat_id is required." if cat.nil? + + owner = find(db, cat_data['owner_id']) + raise "A valid owner_id is required." if owner.nil? + + #Assign owner + if cat_data['adopted'] && cat_data['name'] + result = db.exec("UPDATE cats SET owner_id = $2, adopted = $3, name = $4 WHERE id = $1", [cat_data['id'], cat_data['owner_id'], cat_data['adopted'], cat_data['name']]) + elsif cat_data['name'] + result = db.exec("UPDATE cats SET owner_id = $2, name = $3 WHERE id = $1", [cat_data['id'], cat_data['owner_id'], cat_data['name']]) + elsif cat_data['adopted'] + result = db.exec("UPDATE cats SET owner_id = $2, adopted = $3 WHERE id = $1", [cat_data['id'], cat_data['owner_id'], cat_data['adopted']]) + end + self.find(db, cat_data['id']) + else # Create a New Cat + raise "name is required." if cat_data['name'].nil? || cat_data['name'] == '' + raise "shopid is required." if cat_data['shopid'].nil? || cat_data['shopid'] == '' + raise "imageurl is required." if cat_data['imageurl'].nil? || cat_data['imageurl'] == '' + result = db.exec("INSERT INTO cats (name, shopid, imageurl, adopted) values ($1, $2, $3, 'false') RETURNING id", [cat_data['name'], cat_data['shopid'], cat_data['imageurl']]) + self.find(db, result.entries.first['id']) + end + end + + def self.destroy(db, cat_id) + # Delete SQL statement + db.exec("DELETE FROM cats WHERE id = $1", [cat_id]) + end + + end +end diff --git a/lib/petshop/dog_repo.rb b/lib/petshop/dog_repo.rb new file mode 100644 index 00000000..94bf2e44 --- /dev/null +++ b/lib/petshop/dog_repo.rb @@ -0,0 +1,54 @@ +require 'pry-byebug' + +module PetShop + class DogRepo + + def self.all(db) + result = db.exec("SELECT * FROM dogs").to_a + end + + def self.find(db, dog_id) + dog = db.exec("SELECT * FROM dogs WHERE id=$1", [dog_id]).first + end + + def self.find_all_by_shop(db, shopid) + dogs = db.exec("SELECT * FROM dogs WHERE shopid=$1", [shopid]).to_a + end + + def self.find_all_by_owner(db, owner_id) + dogs = db.exec("SELECT * FROM dogs WHERE owner_id=$1", [owner_id]).to_a + end + + def self.save(db, dog_data) + if dog_data['id'] # Update + + # Ensure dog exists + dog = find(db, dog_data['id']) + raise "A valid dog_id is required." if dog.nil? + raise "A valid owner_id is required." if dog.nil? + + #Assign owner + if dog_data['adopted'] && dog_data['name'] + result = db.exec("UPDATE dogs SET owner_id = $2, adopted = $3, name = $4 WHERE id = $1", [dog_data['id'], dog_data['owner_id'], dog_data['adopted'], dog_data['name']]) + elsif dog_data['name'] + result = db.exec("UPDATE dogs SET owner_id = $2, name = $3 WHERE id = $1", [dog_data['id'], dog_data['owner_id'], dog_data['name']]) + elsif dog_data['adopted'] + result = db.exec("UPDATE dogs SET owner_id = $2, adopted = $3 WHERE id = $1", [dog_data['id'], dog_data['owner_id'], dog_data['adopted']]) + end + self.find(db, dog_data['id']) + else + raise "name is required." if dog_data['name'].nil? || dog_data['name'] == '' + raise "shopid is required." if dog_data['shopid'].nil? || dog_data['shopid'] == '' + raise "imageurl is required." if dog_data['imageurl'].nil? || dog_data['imageurl'] == '' + result = db.exec("INSERT INTO dogs (name, shopid, imageurl, adopted) values ($1, $2, $3, 'false') RETURNING id", [dog_data['name'], dog_data['shopid'], dog_data['imageurl']]) + self.find(db, result.entries.first['id']) + end + end + + def self.destroy(db, dog_id) + # Delete SQL statement + db.exec("DELETE FROM dogs WHERE id = $1", [dog_id]) + end + + end +end diff --git a/lib/petshop/owner_repo.rb b/lib/petshop/owner_repo.rb new file mode 100644 index 00000000..61b5e583 --- /dev/null +++ b/lib/petshop/owner_repo.rb @@ -0,0 +1,55 @@ +require 'pry-byebug' + +module PetShop + class OwnerRepo + + def self.all(db) + # Other code should not have to deal with the PG:Result. + # Therefore, convert the results into a plain array. + result = db.exec("SELECT * FROM owners").to_a + end + + def self.find(db, owner_id) + owner = db.exec("SELECT * FROM owners WHERE id=$1", [owner_id]).first + end + + # find user by username. Intended to be used when + # someone tries to sign in. + def self.find_by_name db, username + sql = %q[SELECT * FROM owners WHERE username = $1] + result = db.exec(sql, [username]) + result.first + end + + def self.save(db, owner_data) + if owner_data['id'] # Edit owner + + # Ensure owner exists + owner = find(db, owner_data['id']) + raise "A valid owner id is required." if owner.nil? + + if owner_data['username'] # Update Owner Name + result = db.exec("UPDATE owners SET username = $2 WHERE id = $1", [owner_data['id'], owner_data['username']]) + end + + if owner_data['password'] # Update Owner Password + result = db.exec("UPDATE owners SET password = $2 WHERE id = $1", [owner_data['id'], owner_data['password']]) + end + self.find(db, owner_data['id']) + else + raise "username is required." if owner_data['username'].nil? || owner_data['username'] == '' + raise "password is required." if owner_data['password'].nil? || owner_data['password'] == '' + result = db.exec("INSERT INTO owners (username, password) VALUES ($1, $2) RETURNING *", [owner_data['username'], owner_data['password']]) + self.find(db, result.entries.first['id']) + end + end + + def self.destroy(db, owner_id) + # Delete SQL statement + db.exec("UPDATE cats SET owner_id = null, adopted = false WHERE owner_id = $1", [owner_id]) + db.exec("UPDATE dogs SET owner_id = null, adopted = false WHERE owner_id = $1", [owner_id]) + db.exec("DELETE FROM owners WHERE id = $1", [owner_id]) + end + + end +end diff --git a/lib/petshop/shop_repo.rb b/lib/petshop/shop_repo.rb new file mode 100644 index 00000000..e21dd54a --- /dev/null +++ b/lib/petshop/shop_repo.rb @@ -0,0 +1,43 @@ +require 'pry-byebug' + +module PetShop + class ShopRepo + + def self.all(db) + # Other code should not have to deal with the PG:Result. + # Therefore, convert the results into a plain array. + # TODO: This has to be a JOIN table + result = db.exec("SELECT * FROM shops").to_a + end + + def self.find(db, shopid) + # TODO: This has to be a JOIN table + + shop = db.exec("SELECT * FROM shops WHERE id=$1", [shopid]).first + end + + def self.save(db, shop_data) + if shop_data['id'] # Edit Shop + + # Ensure shop exists + shop = find(db, shop_data['id']) + raise "A valid shop id is required." if shop.nil? + + result = db.exec("UPDATE shops SET name = $2 WHERE id = $1", [shop_data['id'], shop_data['name']]) + self.find(db, shop_data['id']) + else + raise "shop name is required." if shop_data['name'].nil? || shop_data['name'] == '' + result = db.exec("INSERT INTO shops (name) VALUES ($1) RETURNING *", [shop_data['name']]) + self.find(db, result.entries.first['id']) + end + end + + def self.destroy(db, shopid) + # Delete SQL statement + db.exec("DELETE FROM cats WHERE shopid = $1", [shopid]) + db.exec("DELETE FROM dogs WHERE shopid = $1", [shopid]) + db.exec("DELETE FROM shops WHERE id = $1", [shopid]) + end + + end +end diff --git a/public/js/pet-container.js b/public/js/pet-container.js index 68e095ca..ee33c56f 100644 --- a/public/js/pet-container.js +++ b/public/js/pet-container.js @@ -29,11 +29,10 @@ } var petsView = function (ctrl, type, pets) { - var petDivs = pets.map(function(pet) { return m('.pet', [ m('.photo', - m('img', { src: pet.imageUrl }) + m('img', { src: pet.imageurl }) ), m('.info', [ m('h4', pet.name) diff --git a/public/js/pet-shop.js b/public/js/pet-shop.js index 8aa6893b..160696f7 100644 --- a/public/js/pet-shop.js +++ b/public/js/pet-shop.js @@ -18,7 +18,7 @@ m.request({ method: 'put', url: adoptUrl }).then(function() { var pet = pets().find(function(p){ return p.id == petId }) - pet.adopted = true + pet.adopted = "true" appCtrl.user()[type].push(pet) }, genericError) } @@ -40,23 +40,22 @@ var petsView = function (ctrl, type, pets) { if (!pets) return null - + debugger var petDivs = pets.map(function(pet) { var adoptLink = m('a', { onclick: ctrl.adopt.coldCurry(type, pet.id), href: '#' }, 'Adopt this pet') - return m('.pet', [ m('.photo', - m('img', { src: pet.imageUrl }) + m('img', { src: pet.imageurl }) ), m('.info', [ m('h4', pet.name), m('b', "Adopted: "), - m('span', pet.adopted ? "Yes!" : "No..."), + m('span', pet.adopted == "true" ? "Yes!" : "No..."), m('br'), - pet.adopted ? null : adoptLink + pet.adopted == "true" ? null : adoptLink ]) ]) }) diff --git a/server.rb b/server.rb index 07df95f4..17d62ad8 100644 --- a/server.rb +++ b/server.rb @@ -2,95 +2,127 @@ require 'sinatra/reloader' require 'rest-client' require 'json' +require 'pry-byebug' +# require 'rack-flash' -# # -# This is our only html view... -# -get '/' do - if session[:user_id] - # TODO: Grab user from database - @current_user = $sample_user +require_relative 'lib/petshop.rb' + +class PetShop::Server < Sinatra::Application + + set :bind, '0.0.0.0' # This is needed for Vagrant + + configure do + enable :sessions + # use Rack::Flash + end + + before do + @db = PetShop.create_db_connection 'petshop_dev' + if session[:user_id] + owner_id = session['user_id'] + @current_user = PetShop::OwnerRepo.find @db, owner_id + @current_user['cats'] = PetShop::CatRepo.find_all_by_owner(@db, @current_user['id']) + @current_user['dogs'] = PetShop::DogRepo.find_all_by_owner(@db, @current_user['id']) + @current_user + else + #@current_user = $sample_user + end end - erb :index -end -# # -# ...the rest are JSON endpoints -# -get '/shops' do - headers['Content-Type'] = 'application/json' - RestClient.get("http://pet-shop.api.mks.io/shops") -end + # # + # This is our only html view... + # + get '/' do + erb :index + end -post '/signin' do - params = JSON.parse request.body.read + # # + # ...the rest are JSON endpoints + # + get '/shops' do + headers['Content-Type'] = 'application/json' + shops = PetShop::ShopRepo.all(@db).to_json + end - username = params['username'] - password = params['password'] + post '/signin' do + params = JSON.parse request.body.read - # TODO: Grab user by username from database and check password - user = { 'username' => 'alice', 'password' => '123' } + username = params['username'] + password = params['password'] - if password == user['password'] + # TODO: Grab user by username from database and check password + owner = PetShop::OwnerRepo.find_by_name(@db, username) + # user = { 'username' => 'alice', 'password' => '123' } + + # Validate credentials Valid + if !owner.nil? && password == owner['password'] + headers['Content-Type'] = 'application/json' + + # TODO: Return all pets adopted by this user + owner['cats'] = PetShop::CatRepo.find_all_by_owner(@db, owner['id']) + owner['dogs'] = PetShop::DogRepo.find_all_by_owner(@db, owner['id']) + + # TODO: Set session[:user_id] so the server will remember this user has logged in + session['user_id'] = owner['id'] + + owner.to_json + else + status 401 + end + end + + # # # # + # Cats # + # # # # + get '/shops/:id/cats' do headers['Content-Type'] = 'application/json' - # TODO: Return all pets adopted by this user - # TODO: Set session[:user_id] so the server will remember this user has logged in - $sample_user.to_json - else - status 401 + id = params[:id] + # TODO: Grab from database instead + # RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") + + PetShop::CatRepo.find_all_by_shop(@db, id).to_json end -end - - # # # # -# Cats # -# # # # -get '/shops/:id/cats' do - headers['Content-Type'] = 'application/json' - id = params[:id] - # TODO: Grab from database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/cats") -end - -put '/shops/:shop_id/cats/:id/adopt' do - headers['Content-Type'] = 'application/json' - shop_id = params[:shop_id] - id = params[:id] - # TODO: Grab from database instead - RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/cats/#{id}", - { adopted: true }, :content_type => 'application/json') - # TODO (after you create users table): Attach new cat to logged in user -end - - - # # # # -# Dogs # -# # # # -get '/shops/:id/dogs' do - headers['Content-Type'] = 'application/json' - id = params[:id] - # TODO: Update database instead - RestClient.get("http://pet-shop.api.mks.io/shops/#{id}/dogs") -end - -put '/shops/:shop_id/dogs/:id/adopt' do - headers['Content-Type'] = 'application/json' - shop_id = params[:shop_id] - id = params[:id] - # TODO: Update database instead - RestClient.put("http://pet-shop.api.mks.io/shops/#{shop_id}/dogs/#{id}", - { adopted: true }, :content_type => 'application/json') - # TODO (after you create users table): Attach new dog to logged in user -end - - -$sample_user = { - id: 999, - username: 'alice', - cats: [ - { shopId: 1, name: "NaN Cat", imageUrl: "http://i.imgur.com/TOEskNX.jpg", adopted: true, id: 44 }, - { shopId: 8, name: "Meowzer", imageUrl: "http://www.randomkittengenerator.com/images/cats/rotator.php", id: 8, adopted: "true" } - ], - dogs: [ - { shopId: 1, name: "Leaf Pup", imageUrl: "http://i.imgur.com/kuSHji2.jpg", happiness: 2, id: 2, adopted: "true" } - ] -} + + put '/shops/:shopid/cats/:id/adopt' do + headers['Content-Type'] = 'application/json' + # shopid = params[:shopid] + id = params[:id] + # Grab Cat data from database + + owner = PetShop::OwnerRepo.find(@db, @current_user['id']) + cat = PetShop::CatRepo.save(@db, {'id' => id, 'owner_id' => owner['id'], 'adopted' => 'true'}).to_json + end + + + # # # # + # Dogs # + # # # # + get '/shops/:id/dogs' do + headers['Content-Type'] = 'application/json' + id = params[:id] + dogs = PetShop::DogRepo.find_all_by_shop(@db, id).to_json + end + + put '/shops/:shopid/dogs/:id/adopt' do + headers['Content-Type'] = 'application/json' + shopid = params[:shopid] + id = params[:id] + + owner = PetShop::OwnerRepo.find(@db, @current_user['id']) + cat = PetShop::DogRepo.save(@db, {'id' => id, 'owner_id' => owner['id'], 'adopted' => 'true'}).to_json + + end + + + $sample_user = { + id: 999, + username: 'anonymous', + cats: [ + { shopid: 1, name: "NaN Cat", imageurl: "http://i.imgur.com/TOEskNX.jpg", adopted: 'true', id: 44 }, + { shopid: 8, name: "Meowzer", imageurl: "http://www.randomkittengenerator.com/images/cats/rotator.php", id: 8, adopted: 'true' } + ], + dogs: [ + { shopid: 1, name: "Leaf Pup", imageurl: "http://i.imgur.com/kuSHji2.jpg", happiness: 2, id: 2, adopted: 'true' } + ] + } +end \ No newline at end of file diff --git a/spec/repos/owner_repo_spec.rb b/spec/repos/owner_repo_spec.rb new file mode 100644 index 00000000..b21f4a84 --- /dev/null +++ b/spec/repos/owner_repo_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe PetShop::OwnerRepo do + + def owner_count + repo.all(db).count + end + + let(:repo) { PetShop::OwnerRepo } + let(:db) { PetShop.create_db_connection('petshop_test') } + + before(:each) do + PetShop.clear_db(db) + @owner_id1 = PetShop::OwnerRepo.save(db, { 'username' => "Giovanni", 'password' => 'Swordfish' })['id'] + @owner_id2 = PetShop::OwnerRepo.save(db, { 'username' => "Leonardo", 'password' => 'Swordfish' })['id'] + end + + it "gets all owners" do + + owners = repo.all(db) + expect(owners).to be_a Array + expect(owners.count).to eq 2 + + usernames = owners.map {|u| u['username'] } + expect(usernames).to include "Leonardo", "Giovanni" + end + + it "creates owners" do + expect(owner_count).to eq 2 + + owner = repo.save(db, { 'username' => "Brian", 'password' => 'puppyfan102' }) + expect(owner['id']).to_not be_nil + expect(owner['username']).to eq "Brian" + expect(owner['password']).to eq "puppyfan102" + + # Check for persistence + expect(owner_count).to eq 3 + + owner = repo.all(db).first + expect(owner['id']).to_not be_nil + expect(owner['username']).to eq "Giovanni" + expect(owner['password']).to eq "Swordfish" + + end + + it "requires a username" do + expect { repo.save(db, {}) }.to raise_error {|e| + expect(e.message).to match /username/ + } + end + + it "requires an owner id that exists" do + expect { + repo.save(db, { 'id' => 999, 'username' => "Mr FunGuy" }) + } + .to raise_error {|e| + expect(e.message).to match /owner id/ + } + end + + it "finds owners" do + retrieved_owner = repo.find(db, @owner_id1) + expect(retrieved_owner['username']).to eq "Giovanni" + end + + it "updates owners" do + owner1 = repo.save(db, { 'id' => @owner_id1, 'username' => "Billy Boy" }) + owner2 = repo.save(db, { 'id' => @owner_id1, 'password' => "bigDogsRCool14" }) + expect(owner2['id']).to eq(owner1['id']) + expect(owner2['password']).to eq "bigDogsRCool14" + + # Check for persistence + owner3 = repo.find(db, owner1['id']) + expect(owner3['username']).to eq "Billy Boy" + end + +end diff --git a/spec/repos/pet_repo_spec.rb b/spec/repos/pet_repo_spec.rb new file mode 100644 index 00000000..d2ff2b81 --- /dev/null +++ b/spec/repos/pet_repo_spec.rb @@ -0,0 +1,95 @@ +require 'spec_helper' + +describe PetShop::DogRepo do + + def dog_count + repo.all(db).count + end + + let(:repo) { PetShop::DogRepo } + let(:db) { PetShop.create_db_connection('petshop_test') } + + before(:each) do + PetShop.clear_db(db) + @shopid = PetShop::ShopRepo.save(db, { 'name' => "SuperShop" })['id'] + end + + it "gets all dogs" do + dog = repo.save(db, {'name' => "Barnaby", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + dog = repo.save(db, {'name' => "Giles", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + dog = repo.save(db, {'name' => "Goji", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + dog = repo.save(db, {'name' => "Berry", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + + expect(dog['shopid']).to_not be_nil + + dogs = repo.all(db) + expect(dogs).to be_a Array + expect(dogs.count).to eq 4 + + names = dogs.map {|u| u['name'] } + expect(names).to include "Barnaby", "Giles", "Goji", "Berry" + end + + it "creates dogs" do + expect(dog_count).to eq 0 + + dog = repo.save(db, {'name' => "Barnaby", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + expect(dog['id']).to_not be_nil + expect(dog['shopid']).to_not be_nil + expect(dog['name']).to eq "Barnaby" + + # Check for persistence + expect(dog_count).to eq 1 + + dog_count_by_store = repo.find_all_by_shop(db, @shopid).count + expect(dog_count_by_store).to eq 1 + + dog = repo.all(db).first + expect(dog['id']).to_not be_nil + expect(dog['shopid']).to_not be_nil + expect(dog['name']).to eq "Barnaby" + + end + + it "requires a name" do + expect { repo.save(db, {}) }.to raise_error {|e| + expect(e.message).to match /name/ + } + end + + it "requires an shop id" do + expect { + repo.save(db, { 'name' => "Barnaby" }) + } + .to raise_error {|e| + expect(e.message).to match /shopid/ + } + end + + it "requires an imageurl" do + expect { + repo.save(db, { 'name' => "Barnaby", 'shopid' => @shopid }) + } + .to raise_error {|e| + expect(e.message).to match /imageurl/ + } + end + + it "finds dogs" do + dog = repo.save(db, {'name' => "Barnaby", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + retrieved_dog = repo.find(db, dog['id']) + expect(retrieved_dog['name']).to eq "Barnaby" + end + + it "updates dogs" do + dog = repo.save(db, {'name' => "Barnaby", 'shopid' => @shopid, 'imageurl' => 'dummy', 'adopted' => 'false' }) + dog2 = repo.save(db, { 'id' => dog['id'], 'name' => "Funky" }) + expect(dog2['id']).to eq(dog['id']) + expect(dog2['name']).to eq "Funky" + + # Check for persistence + dog3 = repo.find(db, dog['id']) + expect(dog3['name']).to eq "Funky" + end + +end diff --git a/spec/repos/shop_repo_spec.rb b/spec/repos/shop_repo_spec.rb new file mode 100644 index 00000000..dd25ce0d --- /dev/null +++ b/spec/repos/shop_repo_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe PetShop::ShopRepo do + + def shop_count + repo.all(db).count + end + + let(:repo) { PetShop::ShopRepo } + let(:db) { PetShop.create_db_connection('petshop_test') } + + before(:each) do + PetShop.clear_db(db) + @shopid1 = PetShop::ShopRepo.save(db, { 'name' => "Pup By Pup Best" })['id'] + @shopid2 = PetShop::ShopRepo.save(db, { 'name' => "U Buy Cat Now" })['id'] + end + + it "gets all shops" do + + shops = repo.all(db) + expect(shops).to be_a Array + expect(shops.count).to eq 2 + + names = shops.map {|u| u['name'] } + expect(names).to include "Pup By Pup Best", "U Buy Cat Now" + end + + it "creates shops" do + expect(shop_count).to eq 2 + + shop = repo.save(db, { 'name' => "Bitten by Kittens" }) + expect(shop['id']).to_not be_nil + expect(shop['name']).to eq "Bitten by Kittens" + + # Check for persistence + expect(shop_count).to eq 3 + + shop = repo.all(db).first + expect(shop['id']).to_not be_nil + expect(shop['name']).to eq "Pup By Pup Best" + + end + + it "requires a name" do + expect { repo.save(db, {}) }.to raise_error {|e| + expect(e.message).to match /name/ + } + end + + it "requires an shop id that exists" do + expect { + repo.save(db, { 'id' => 999, 'name' => "Mr Puppy Love" }) + } + .to raise_error {|e| + expect(e.message).to match /shop id/ + } + end + + it "finds shops" do + retrieved_shop = repo.find(db, @shopid1) + expect(retrieved_shop['name']).to eq "Pup By Pup Best" + end + + it "updates shops" do + shop1 = repo.save(db, { 'id' => @shopid1, 'name' => "Billy Boy" }) + expect(shop1['id']).to eq(@shopid1) + + # Check for persistence + shop2 = repo.find(db, shop1['id']) + expect(shop2['name']).to eq "Billy Boy" + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..bd555383 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,13 @@ +require 'petshop' + +RSpec.configure do |config| + config.treat_symbols_as_metadata_keys_with_true_values = true + config.run_all_when_everything_filtered = true + config.filter_run :focus + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = 'random' +end