Add couchbase with modifications, formalize broadcaster and make testable and some other stuff
This commit is contained in:
@@ -122,4 +122,36 @@ describe List do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#place_order' do
|
||||
|
||||
it 'returns an order object' do
|
||||
list.place_order(user, product.id => 7).should be_a Order
|
||||
end
|
||||
|
||||
it 'creates an order' do
|
||||
expect{ list.place_order(user, product.id => 7) }.to change{ Order.count }.by(1)
|
||||
end
|
||||
|
||||
describe 'broadcasting' do
|
||||
it 'broadcasts to the user and the supplier the active order counter' do
|
||||
list.place_order(user, product.id => 7)
|
||||
|
||||
expect{
|
||||
list.place_order(user, product.id => 3)
|
||||
}.to broadcast_to_user(user.id).message('orders_in_process_count').with(count: 2)
|
||||
|
||||
expect{
|
||||
list.place_order(user, product.id => 5)
|
||||
}.to broadcast_to_supplier(supplier.id).message('orders_in_process_count').with(count: 3)
|
||||
end
|
||||
end
|
||||
|
||||
it 'sets the list price as kind of caching' do
|
||||
list.place_order(user, product.id => 7)
|
||||
list.reload
|
||||
list.price.should == 3
|
||||
end
|
||||
|
||||
describe 'product order creation'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,4 +37,64 @@ describe Order do
|
||||
it 'paginates'
|
||||
end
|
||||
|
||||
describe '#is_being_processed!' do
|
||||
describe 'broadcasting' do
|
||||
|
||||
it 'broadcasts order info to the user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'order_being_processed' ).with(id: order.id, list_id: list.id)
|
||||
end
|
||||
|
||||
describe 'counters' do
|
||||
before do
|
||||
# hack some initial values
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_in_process", 7
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
end
|
||||
|
||||
it 'reduces the orders_in_process count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
end
|
||||
|
||||
it 'increases the orders_delivered count and communicates it to user' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_user(user.id).message( 'orders_delivered_count' ).with(count: 10)
|
||||
end
|
||||
|
||||
it 'reduces the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_in_process_count' ).with(count: 6)
|
||||
end
|
||||
|
||||
it 'increases the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'orders_delivered_count' ).with(count: 10)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it 'broadcasts order info to the supplier' do
|
||||
expect{ order.is_being_processed! }.to broadcast_to_supplier(supplier.id).message( 'order_being_processed' ).with(id: order.id, list_id: list.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#is_delivered!' do
|
||||
describe 'broadcasting' do
|
||||
describe 'counters' do
|
||||
before do
|
||||
# hack some initial values
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_in_process", 7
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
end
|
||||
|
||||
it 'decreases the orders_delivered count and communicates it to user' do
|
||||
expect{ order.is_delivered! }.to broadcast_to_user(user.id).message( 'orders_delivered_count' ).with(count: 8)
|
||||
end
|
||||
|
||||
it 'decreases the orders_in_process count and communicates it to supplier' do
|
||||
expect{ order.is_delivered! }.to broadcast_to_supplier(supplier.id).message( 'orders_delivered_count' ).with(count: 8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,62 +1,67 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Supplier do
|
||||
before :each do
|
||||
@supplier = build :supplier
|
||||
end
|
||||
let(:supplier){ build :supplier }
|
||||
# property open
|
||||
describe :open do
|
||||
it 'should be false by default' do
|
||||
@supplier.open.should == false
|
||||
supplier.open.should == false
|
||||
end
|
||||
|
||||
it 'should not be open? by default' do
|
||||
@supplier.open?.should == false
|
||||
supplier.open?.should == false
|
||||
end
|
||||
|
||||
it 'should be closed? by default' do
|
||||
@supplier.closed?.should == true
|
||||
supplier.closed?.should == true
|
||||
end
|
||||
|
||||
describe :mark_as_open! do
|
||||
before :each do
|
||||
@supplier.mark_as_open!
|
||||
supplier.mark_as_open!
|
||||
end
|
||||
it 'should be persisted in the database' do
|
||||
@supplier.reload
|
||||
@supplier.open.should == true
|
||||
supplier.reload
|
||||
supplier.open.should == true
|
||||
end
|
||||
|
||||
it 'should be open?' do
|
||||
@supplier.open?.should == true
|
||||
supplier.open?.should == true
|
||||
end
|
||||
|
||||
it 'should not be closed?' do
|
||||
@supplier.closed?.should == false
|
||||
supplier.closed?.should == false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe :mark_as_closed! do
|
||||
before :each do
|
||||
@supplier.mark_as_open!
|
||||
@supplier.mark_as_closed!
|
||||
supplier.mark_as_open!
|
||||
supplier.mark_as_closed!
|
||||
end
|
||||
|
||||
it 'should be persisted in the database' do
|
||||
@supplier.reload
|
||||
@supplier.open.should == false
|
||||
supplier.reload
|
||||
supplier.open.should == false
|
||||
end
|
||||
|
||||
it 'should be open?' do
|
||||
@supplier.open?.should == false
|
||||
supplier.open?.should == false
|
||||
end
|
||||
|
||||
it 'should not be closed?' do
|
||||
@supplier.closed?.should == true
|
||||
supplier.closed?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#decrement_orders_delivered_count!' do
|
||||
it 'decreases orders_delivered' do
|
||||
Qwaiter::Counter.set "supplier:#{supplier.id}:orders_delivered", 9
|
||||
supplier.decrement_orders_delivered_count!.should == 8
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -43,6 +43,10 @@ module SpecSelectorHelpers
|
||||
%x(launchy http://localhost:3000/capybara.html)
|
||||
end
|
||||
end
|
||||
|
||||
# NOT THREADSAFE!!!!!! but good enough for testing since the real couchbase flush is slowwwwww....
|
||||
Qwaiter::Counter.connection = InMemoryQCounter.new
|
||||
|
||||
RSpec.configure do |config|
|
||||
# == Mock Framework
|
||||
#
|
||||
@@ -56,6 +60,7 @@ RSpec.configure do |config|
|
||||
config.include FactoryAttributesFor
|
||||
config.include Devise::TestHelpers, type: :controller
|
||||
config.include EndWithMatcher
|
||||
config.include Matchers
|
||||
config.include Features::BasicHelpers, type: :feature
|
||||
config.include SpecRouteHelpers, type: :feature
|
||||
#config.use_transactional_fixtures = true
|
||||
@@ -98,6 +103,7 @@ RSpec.configure do |config|
|
||||
|
||||
config.before :each do
|
||||
CouchPotato.couchrest_database.recreate!
|
||||
Qwaiter::Counter.connection.flush
|
||||
end
|
||||
|
||||
config.before :each, type: :feature do
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# This is a non thread safe replacement for the
|
||||
# couchbase counter mechanism since every test needs
|
||||
# a clean start and Hash#clear is soooo much faster than
|
||||
# a couchbase bucket flush
|
||||
class InMemoryQCounter
|
||||
STORE = {}
|
||||
|
||||
def get(key)
|
||||
STORE[key]
|
||||
end
|
||||
|
||||
def set(key, value)
|
||||
STORE[key] = value
|
||||
end
|
||||
|
||||
def incr(key, options = {})
|
||||
STORE[key] ||= options[:initial].to_i
|
||||
STORE[key] += 1
|
||||
end
|
||||
|
||||
def decr(key, options = {})
|
||||
STORE[key] ||= options[:initial].to_i
|
||||
STORE[key] -= 1
|
||||
end
|
||||
|
||||
def flush
|
||||
STORE.clear
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
module Matchers
|
||||
class BroadcastToSupplier
|
||||
class TestBroadcaster
|
||||
attr_reader :broadcasts
|
||||
|
||||
def initialize
|
||||
@broadcasts = []
|
||||
end
|
||||
|
||||
def broadcast(object)
|
||||
self.broadcasts << object
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(supplier_id)
|
||||
@supplier_id = supplier_id
|
||||
end
|
||||
|
||||
def matches?(block)
|
||||
old_broadcaster = Qwaiter.broadcaster
|
||||
test_broadcaster = TestBroadcaster.new
|
||||
Qwaiter.broadcaster = test_broadcaster
|
||||
block.call
|
||||
Qwaiter.broadcaster = old_broadcaster
|
||||
|
||||
relevant_broadcasts = test_broadcaster.broadcasts.select{|b| b[:channel] =~ /^\/supplier\/#{@supplier_id}/ && b[:data][:event] == @message}
|
||||
@failure_debug_content = "was #{relevant_broadcasts.map{|b| b[:data][:data].inspect}.join(" and ")}"
|
||||
relevant_broadcasts.any?{|b| b[:data][:data] == @target_object}
|
||||
end
|
||||
|
||||
def message(msg)
|
||||
@message = msg
|
||||
self
|
||||
end
|
||||
|
||||
def with(target_object)
|
||||
@target_object = target_object
|
||||
self
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"supplier #{@supplier_id} did not receive broadcast #{@message} with #{@target_object.inspect} #{@failure_debug_content}"
|
||||
end
|
||||
end
|
||||
|
||||
def broadcast_to_supplier(*args, &block)
|
||||
BroadcastToSupplier.new(*args, &block)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
module Matchers
|
||||
class BroadcastToUser
|
||||
class TestBroadcaster
|
||||
attr_reader :broadcasts
|
||||
|
||||
def initialize
|
||||
@broadcasts = []
|
||||
end
|
||||
|
||||
def broadcast(object)
|
||||
self.broadcasts << object
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(user_id)
|
||||
@user_id = user_id
|
||||
end
|
||||
|
||||
def matches?(block)
|
||||
old_broadcaster = Qwaiter.broadcaster
|
||||
test_broadcaster = TestBroadcaster.new
|
||||
Qwaiter.broadcaster = test_broadcaster
|
||||
block.call
|
||||
Qwaiter.broadcaster = old_broadcaster
|
||||
|
||||
relevant_broadcasts = test_broadcaster.broadcasts.select{|b| b[:channel] =~ /^\/user\/#{@user_id}/ && b[:data][:event] == @message}
|
||||
@failure_debug_content = "was #{relevant_broadcasts.map{|b| b[:data][:data].inspect}.join(" and ")}"
|
||||
relevant_broadcasts.any?{|b| b[:data][:data] == @target_object}
|
||||
end
|
||||
|
||||
def message(msg)
|
||||
@message = msg
|
||||
self
|
||||
end
|
||||
|
||||
def with(target_object)
|
||||
@target_object = target_object
|
||||
self
|
||||
end
|
||||
|
||||
def failure_message
|
||||
"user #{@user_id} did not receive broadcast #{@message} with #{@target_object.inspect} #{@failure_debug_content}"
|
||||
end
|
||||
end
|
||||
|
||||
def broadcast_to_user(*args, &block)
|
||||
BroadcastToUser.new(*args, &block)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user