diff --git a/app/views/bookingsync_portal/admin/rentals/index_with_search.js.erb b/app/views/bookingsync_portal/admin/rentals/index_with_search.js.erb
new file mode 100644
index 00000000..2a189779
--- /dev/null
+++ b/app/views/bookingsync_portal/admin/rentals/index_with_search.js.erb
@@ -0,0 +1,20 @@
+<%- if search_by_rentals? %>
+ list = $(".bookingsync-rentals-list.rentals-list .rentals-list-scroll")
+ data = $("<%=escape_javascript(render file: 'bookingsync_portal/admin/rentals/index') %>")
+ newList = $(data).find(".bookingsync-rentals-list.rentals-list .rentals-list-scroll").first()
+ list.html(newList.html())
+
+ $(".bookingsync-rental").draggableRental()
+ $(".panel.panel-remote").droppableRemoteRental()
+<%- elsif search_by_remote_rentals? %>
+ list = $(".remote-rentals-list.rentals-list .rentals-list-scroll")
+ data = $("<%=escape_javascript(render file: 'bookingsync_portal/admin/rentals/index') %>")
+ newList = $(data).find(".remote-rentals-list.rentals-list .rentals-list-scroll").first()
+ list.html(newList.html())
+
+ $(".bookingsync-rental").draggableRental()
+ $(".panel.panel-remote").droppableRemoteRental()
+<%- end %>
+
+$("body").data("rentals-records-count", "<%= @not_connected_rentals.count %>")
+$("body").data("remote-rentals-records-count", "<%= @remote_rentals.count %>")
diff --git a/app/views/layouts/bookingsync_portal/admin.html.erb b/app/views/layouts/bookingsync_portal/admin.html.erb
index a3afa18b..b89b864f 100644
--- a/app/views/layouts/bookingsync_portal/admin.html.erb
+++ b/app/views/layouts/bookingsync_portal/admin.html.erb
@@ -9,7 +9,13 @@
<%= stylesheet_link_tag 'admin/application', media: 'all' %>
<%= csrf_meta_tags %>
-
+
<%= render partial: '/layouts/bookingsync_portal/menu' %>
<%= render '/layouts/bookingsync_portal/flash' %>
diff --git a/bookingsync_portal.gemspec b/bookingsync_portal.gemspec
index 9952406b..18f3837c 100644
--- a/bookingsync_portal.gemspec
+++ b/bookingsync_portal.gemspec
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
s.add_dependency 'rails'
s.add_dependency 'sprockets-rails'
s.add_dependency 'responders'
- s.add_dependency 'bookingsync_application', ['>= 3', '< 4']
+ s.add_dependency 'bookingsync_application', '>= 3'
s.add_dependency 'redis'
# FIXME: Will no longer be needed once UI moved to Ember
s.add_dependency 'jquery-rails'
@@ -29,12 +29,16 @@ Gem::Specification.new do |s|
s.add_dependency 'font-awesome-sass', '4.7.0'
s.add_dependency 'handlebars_assets'
s.add_dependency 'simple_form'
- s.add_dependency 'message_bus'
+ s.add_dependency 'message_bus', '2.0.2'
s.add_dependency 'turbolinks'
- s.add_dependency 'sass-rails'
+ s.add_dependency 'sass-rails', '~> 5'
s.add_dependency 'uglifier'
s.add_dependency 'coffee-rails'
+ s.add_dependency 'ransack'
+ s.add_dependency 'kaminari'
+
+ s.add_development_dependency 'byebug'
s.add_development_dependency 'appraisal'
s.add_development_dependency 'rspec-rails'
s.add_development_dependency 'shoulda'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0269e231..557b0662 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -53,6 +53,7 @@ en:
rentals:
no_published_rentals_html: 'No published rentals present, please make sure to
fill all your rentals details.'
all_synchronized: Perfect! All your rentals are synchronized.
+ no_results: No results
rental:
bedrooms_html:
one: '
1 Bedroom'
diff --git a/config/routes.rb b/config/routes.rb
index e842863d..b125bfaa 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,8 @@
BookingsyncPortal::Engine.routes.draw do
namespace :admin do
resources :rentals, only: [:index, :show]
+ get "v2/rentals", to: "rentals#index_with_search", as: "v2_rentals"
+
resources :connections, only: [:create, :destroy]
resources :remote_accounts, only: [:new, :create]
get 'help', to: 'help#index'
diff --git a/gemfiles/rails_5.0.gemfile.lock b/gemfiles/rails_5.0.gemfile.lock
index 2f7f3e12..aeb8d80a 100644
--- a/gemfiles/rails_5.0.gemfile.lock
+++ b/gemfiles/rails_5.0.gemfile.lock
@@ -10,11 +10,13 @@ PATH
handlebars_assets
jquery-rails
jquery-ui-rails (~> 6.0.1)
- message_bus
+ kaminari
+ message_bus (= 2.0.2)
rails
+ ransack
redis
responders
- sass-rails
+ sass-rails (~> 5)
simple_form
sprockets-rails
turbolinks
@@ -91,6 +93,7 @@ GEM
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
builder (3.2.4)
+ byebug (11.1.1)
coderay (1.1.2)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
@@ -143,12 +146,24 @@ GEM
concurrent-ruby
railties (>= 4.1)
jwt (2.2.1)
+ kaminari (1.2.0)
+ activesupport (>= 4.1.0)
+ kaminari-actionview (= 1.2.0)
+ kaminari-activerecord (= 1.2.0)
+ kaminari-core (= 1.2.0)
+ kaminari-actionview (1.2.0)
+ actionview
+ kaminari-core (= 1.2.0)
+ kaminari-activerecord (1.2.0)
+ activerecord
+ kaminari-core (= 1.2.0)
+ kaminari-core (1.2.0)
loofah (2.4.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
- message_bus (2.2.3)
+ message_bus (2.0.2)
rack (>= 1.1.3)
method_source (0.9.2)
mini_mime (1.0.2)
@@ -181,6 +196,8 @@ GEM
parallel (1.19.1)
parser (2.7.0.2)
ast (~> 2.4.0)
+ polyamorous (2.3.0)
+ activerecord (>= 5.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
@@ -219,6 +236,12 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
+ ransack (2.3.0)
+ actionpack (>= 5.0)
+ activerecord (>= 5.0)
+ activesupport (>= 5.0)
+ i18n
+ polyamorous (= 2.3.0)
rb-fsevent (0.10.3)
rb-inotify (0.10.1)
ffi (~> 1.0)
@@ -257,16 +280,12 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
- sass-rails (6.0.0)
- sassc-rails (~> 2.1, >= 2.1.1)
- sassc (2.2.1)
- ffi (~> 1.9)
- sassc-rails (2.1.2)
- railties (>= 4.0.0)
- sassc (>= 2.0)
- sprockets (> 3.0)
- sprockets-rails
- tilt
+ sass-rails (5.0.7)
+ railties (>= 4.0.0, < 6)
+ sass (~> 3.1)
+ sprockets (>= 2.8, < 4.0)
+ sprockets-rails (>= 2.0, < 4.0)
+ tilt (>= 1.1, < 3)
shoulda (3.6.0)
shoulda-context (~> 1.0, >= 1.0.1)
shoulda-matchers (~> 3.0)
@@ -314,6 +333,7 @@ PLATFORMS
DEPENDENCIES
appraisal
bookingsync_portal!
+ byebug
factory_girl_rails
pry-rails
rails (~> 5.0.0)
diff --git a/gemfiles/rails_5.1.gemfile.lock b/gemfiles/rails_5.1.gemfile.lock
index b400c733..55d770ef 100644
--- a/gemfiles/rails_5.1.gemfile.lock
+++ b/gemfiles/rails_5.1.gemfile.lock
@@ -10,11 +10,13 @@ PATH
handlebars_assets
jquery-rails
jquery-ui-rails (~> 6.0.1)
- message_bus
+ kaminari
+ message_bus (= 2.0.2)
rails
+ ransack
redis
responders
- sass-rails
+ sass-rails (~> 5)
simple_form
sprockets-rails
turbolinks
@@ -91,6 +93,7 @@ GEM
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
builder (3.2.4)
+ byebug (11.1.1)
coderay (1.1.2)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
@@ -143,12 +146,24 @@ GEM
concurrent-ruby
railties (>= 4.1)
jwt (2.2.1)
+ kaminari (1.2.0)
+ activesupport (>= 4.1.0)
+ kaminari-actionview (= 1.2.0)
+ kaminari-activerecord (= 1.2.0)
+ kaminari-core (= 1.2.0)
+ kaminari-actionview (1.2.0)
+ actionview
+ kaminari-core (= 1.2.0)
+ kaminari-activerecord (1.2.0)
+ activerecord
+ kaminari-core (= 1.2.0)
+ kaminari-core (1.2.0)
loofah (2.4.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
- message_bus (2.2.3)
+ message_bus (2.0.2)
rack (>= 1.1.3)
method_source (0.9.2)
mini_mime (1.0.2)
@@ -181,6 +196,8 @@ GEM
parallel (1.19.1)
parser (2.7.0.2)
ast (~> 2.4.0)
+ polyamorous (2.3.0)
+ activerecord (>= 5.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
@@ -219,6 +236,12 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
+ ransack (2.3.0)
+ actionpack (>= 5.0)
+ activerecord (>= 5.0)
+ activesupport (>= 5.0)
+ i18n
+ polyamorous (= 2.3.0)
rb-fsevent (0.10.3)
rb-inotify (0.10.1)
ffi (~> 1.0)
@@ -257,16 +280,12 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
- sass-rails (6.0.0)
- sassc-rails (~> 2.1, >= 2.1.1)
- sassc (2.2.1)
- ffi (~> 1.9)
- sassc-rails (2.1.2)
- railties (>= 4.0.0)
- sassc (>= 2.0)
- sprockets (> 3.0)
- sprockets-rails
- tilt
+ sass-rails (5.0.7)
+ railties (>= 4.0.0, < 6)
+ sass (~> 3.1)
+ sprockets (>= 2.8, < 4.0)
+ sprockets-rails (>= 2.0, < 4.0)
+ tilt (>= 1.1, < 3)
shoulda (3.6.0)
shoulda-context (~> 1.0, >= 1.0.1)
shoulda-matchers (~> 3.0)
@@ -314,6 +333,7 @@ PLATFORMS
DEPENDENCIES
appraisal
bookingsync_portal!
+ byebug
factory_girl_rails
pry-rails
rails (~> 5.1.0)
diff --git a/lib/bookingsync_portal.rb b/lib/bookingsync_portal.rb
index e5b124f6..55e96a92 100644
--- a/lib/bookingsync_portal.rb
+++ b/lib/bookingsync_portal.rb
@@ -16,6 +16,8 @@
require 'simple_form'
require 'turbolinks'
require 'responders'
+require 'kaminari'
+require 'ransack'
module BookingsyncPortal
# portal name
@@ -57,6 +59,46 @@ module BookingsyncPortal
mattr_accessor :rate_model
@@rate_model = 'BookingsyncPortal::Rate'
+ # whether load-all (false) or paginated (true) view should be used for admin#index
+ mattr_accessor :use_paginated_view
+ @@use_paginated_view = -> (_account) { false }
+
+ # search by not connected rentals
+ mattr_accessor :rentals_search
+ @@rentals_search = {
+ numeric: %w(synced_id),
+ string: %w(name)
+ }
+
+ # search by remote rentals rentals
+ mattr_accessor :remote_rentals_search
+ @@remote_rentals_search = {
+ numeric: %w(uid remote_account.uid),
+ string: %w(rental.name)
+ }
+
+ mattr_accessor :filter_strategies
+ @@filter_strategies = [
+ "BookingsyncPortal::FilterStrategies::Rentals",
+ "BookingsyncPortal::FilterStrategies::RemoteRentals",
+ "BookingsyncPortal::FilterStrategies::BlankRemoteAccounts"
+ ]
+
+ # the number of items that will be displayed per page
+ # works only with enabled use_paginated_view
+ mattr_accessor :items_per_page
+ @@items_per_page = 25
+
+ mattr_accessor :before_rentals_index_action_filter
+ @@before_rentals_index_action_filter = -> (_controller) { }
+
+ mattr_accessor :after_rentals_index_action_filter
+ @@after_rentals_index_action_filter = -> (_controller) { }
+
+ # included tables for remote_rentals_by_account
+ mattr_accessor :remote_rentals_by_account_included_tables
+ @@remote_rentals_by_account_included_tables = %w(remote_account rental)
+
# message bus channel scope
mattr_accessor :message_bus_channel_scope
diff --git a/spec/controllers/admin/rentals_controller_spec.rb b/spec/controllers/admin/rentals_controller_spec.rb
index 30cc3d70..78c63ed6 100644
--- a/spec/controllers/admin/rentals_controller_spec.rb
+++ b/spec/controllers/admin/rentals_controller_spec.rb
@@ -5,10 +5,14 @@
routes { BookingsyncPortal::Engine.routes }
let!(:account) { create(:account) }
- let!(:remote_account) { create(:remote_account, account: account) }
- let(:rental) { create(:rental, account: account) }
- let!(:rental_connected) { create(:rental, account: account) }
- let!(:connection) { create(:connection, rental: rental_connected) }
+ let!(:remote_account) { create(:remote_account, account: account, uid: 3001) }
+ let(:rental) { create(:rental, account: account, synced_id: 1001) }
+ let!(:remote_rental) { create(:remote_rental, remote_account: remote_account, uid: 2001) }
+ let!(:rental_connected) { create(:rental, account: account, synced_id: 1002) }
+ let!(:remote_account_connected) { create(:remote_account, account: account, uid: 3002) }
+ let!(:remote_rental_connected) { create(:remote_rental, remote_account: remote_account_connected, uid: 2002) }
+ let!(:connection) { create(:connection, rental: rental_connected, remote_rental: remote_rental_connected) }
+ let!(:remote_account_empty) { create(:remote_account, account: account, uid: 3003) }
before do
request.env['HTTPS'] = 'on'
@@ -27,4 +31,292 @@
expect { get :index }.to change { Rental.count }
end
end
+
+ describe 'GET #index_with_search' do
+ subject(:index_with_search) do
+ get :index_with_search, params: params, format: request_format
+ end
+
+ let(:params) do
+ {
+ rentals_search: {query: rentals_search_query, page: rentals_search_page},
+ remote_rentals_search: {query: remote_rentals_search_query, page: remote_rentals_search_page},
+ }
+ end
+ let(:rentals_search_query) { "" }
+ let(:rentals_search_page) { 1 }
+ let(:remote_rentals_search_query) { "" }
+ let(:remote_rentals_search_page) { 1 }
+ let(:request_format) { :html }
+
+ context "when format is js" do
+ let(:request_format) { :js }
+
+ it "does not call Rental.synchronize for current_account" do
+ expect(Rental).not_to receive(:synchronize).with(scope: account)
+ index_with_search
+ end
+ end
+
+ context "when format is html" do
+ let(:request_format) { :html }
+
+ before do
+ allow(Rental).to receive(:synchronize).with(scope: account) do
+ # pretending to sync rentals :P
+ rental
+ end
+ end
+
+ it "calls Rental.synchronize for current_account" do
+ expect(Rental).to receive(:synchronize).with(scope: account)
+ index_with_search
+ end
+ end
+
+ context "when there is rentals_search query" do
+ context "and it's empty string" do
+ let(:rentals_search_query) { "" }
+
+ it "does not filter rentals" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected],
+ remote_account => [remote_rental],
+ remote_account_empty => []
+ })
+ expect(assigns(:remote_rentals_by_account).first).to eq([remote_account_empty, []])
+ end
+
+ context "and goes to the next page" do
+ let(:rentals_search_page) { 2 }
+
+ it "appies pagination only for not_connected_rentals" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to be_blank
+
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected],
+ remote_account => [remote_rental],
+ remote_account_empty => []
+ })
+ expect(assigns(:remote_rentals_by_account).first).to eq([remote_account_empty, []])
+ end
+ end
+ end
+
+ context "and it's attempt to filter by" do
+ context "rental.synced_id" do
+ let(:rentals_search_query) { "#{rental.synced_id}" }
+
+ it "filters not_connected_rentals but does not filter remote_rentals part" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected],
+ remote_account => [remote_rental],
+ remote_account_empty => []
+ })
+ expect(assigns(:remote_rentals_by_account).first).to eq([remote_account_empty, []])
+ end
+ end
+
+ context "rental_connected.synced_id" do
+ let(:rentals_search_query) { "#{rental_connected.synced_id}" }
+
+ it "filters not_connected_rentals but does not filter remote_rentals part" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to be_blank
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected],
+ remote_account => [remote_rental],
+ remote_account_empty => []
+ })
+ expect(assigns(:remote_rentals_by_account).first).to eq([remote_account_empty, []])
+ end
+ end
+ end
+ end
+
+ context "when there is remote_rentals_search query" do
+ context "and it's empty string" do
+ let(:remote_rentals_search_query) { "" }
+
+ it "does not filter rentals" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected],
+ remote_account => [remote_rental],
+ remote_account_empty => []
+ })
+ expect(assigns(:remote_rentals_by_account).first).to eq([remote_account_empty, []])
+ end
+
+ context "and goes to the next page" do
+ let(:remote_rentals_search_page) { 2 }
+
+ it "appies pagination only for remote_rentals" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to be_blank
+ end
+ end
+ end
+
+ context "and it's attempt to filter by" do
+ context "remote_account.uid" do
+ let(:remote_rentals_search_query) { "#{remote_account.uid}" }
+
+ it "filters remote_rentals but does not filter not_connected_rentals part" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account => [remote_rental]
+ })
+ end
+ end
+
+ context "remote_account_connected.uid" do
+ let(:remote_rentals_search_query) { "#{remote_account_connected.uid}" }
+
+ it "filters remote_rentals but does not filter not_connected_rentals part" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_connected => [remote_rental_connected]
+ })
+ end
+ end
+
+ context "remote_account_empty.uid" do
+ let(:remote_rentals_search_query) { "#{remote_account_empty.uid}" }
+
+ it "filters remote_rentals but does not filter not_connected_rentals part" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_empty => []
+ })
+ end
+ end
+
+ end
+ end
+
+ context "when there is before_rentals_index_action_filter setting" do
+ let(:rentals_index_action_extention) do
+ Proc.new do |controller|
+ controller.action_variables.not_connected_rentals = Rental.all
+ controller.action_variables.remote_rentals = RemoteRental.all
+ controller.action_variables.custom_variable = "BookingSync"
+ end
+ end
+
+ before do
+ BookingsyncPortal.before_rentals_index_action_filter = rentals_index_action_extention
+ end
+
+ after do
+ BookingsyncPortal.before_rentals_index_action_filter = Proc.new {}
+ end
+
+ it "applies extended logic" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).not_to eq(Rental.all) # will be overridden
+ expect(assigns(:remote_rentals)).not_to eq(RemoteRental.all) # will be overridden
+ expect(assigns(:custom_variable)).to eq("BookingSync")
+ end
+ end
+
+ context "when there is after_rentals_index_action_filter setting" do
+ let(:rentals_index_action_extention) do
+ Proc.new do |controller|
+ controller.action_variables.not_connected_rentals = Rental.all
+ controller.action_variables.remote_rentals = RemoteRental.all
+ controller.action_variables.custom_variable = "BookingSync"
+ end
+ end
+
+ before do
+ BookingsyncPortal.after_rentals_index_action_filter = rentals_index_action_extention
+ end
+
+ after do
+ BookingsyncPortal.after_rentals_index_action_filter = Proc.new {}
+ end
+
+ it "applies extended logic" do
+ index_with_search
+ expect(assigns(:not_connected_rentals)).to eq(Rental.all)
+ expect(assigns(:remote_rentals)).to eq(RemoteRental.all)
+ expect(assigns(:custom_variable)).to eq("BookingSync")
+ end
+ end
+
+ context "when there are several remote_rentals belonged to several remote_accounts" do
+ let!(:remote_account1) { remote_account }
+ let!(:remote_account2) { remote_account_connected }
+ let!(:remote_account3) { create(:remote_account, account: account) }
+
+ let!(:remote_rental_11) { remote_rental }
+ let!(:remote_rental_21) { remote_rental_connected }
+ let!(:remote_rental_31) { create(:remote_rental, remote_account: remote_account3) }
+
+ let!(:remote_rental_12) { create(:remote_rental, remote_account: remote_account1) }
+ let!(:remote_rental_22) { create(:remote_rental, remote_account: remote_account2) }
+ let!(:remote_rental_32) { create(:remote_rental, remote_account: remote_account3) }
+
+ let!(:remote_rental_13) { create(:remote_rental, remote_account: remote_account1) }
+ let!(:remote_rental_23) { create(:remote_rental, remote_account: remote_account2) }
+ let!(:remote_rental_33) { create(:remote_rental, remote_account: remote_account3) }
+
+ before do
+ allow(BookingsyncPortal).to receive(:items_per_page).and_return(4)
+ end
+
+ context "and there is the first page" do
+ let(:remote_rentals_search_page) { 1 }
+
+ it "displayes recors in corrent order" do
+ index_with_search
+
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account_empty => [],
+ remote_account3 => [remote_rental_31, remote_rental_32, remote_rental_33],
+ remote_account2 => [remote_rental_21],
+ })
+ end
+ end
+
+ context "and there is the second page" do
+ let(:remote_rentals_search_page) { 2 }
+
+ it "displayes recors in corrent order" do
+ index_with_search
+
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account2 => [remote_rental_22, remote_rental_23],
+ remote_account1 => [remote_rental_11, remote_rental_12],
+ })
+ end
+ end
+
+ context "and there is the third page" do
+ let(:remote_rentals_search_page) { 3 }
+
+ it "displayes recors in corrent order" do
+ index_with_search
+
+ expect(assigns(:not_connected_rentals)).to contain_exactly(rental)
+ expect(assigns(:remote_rentals_by_account)).to eq({
+ remote_account1 => [remote_rental_13],
+ })
+ end
+ end
+ end
+ end
end
diff --git a/spec/dummy/config/routes.rb b/spec/dummy/config/routes.rb
index 787824f8..19448cf0 100644
--- a/spec/dummy/config/routes.rb
+++ b/spec/dummy/config/routes.rb
@@ -1,3 +1,3 @@
Rails.application.routes.draw do
- # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
+ mount BookingsyncPortal::Engine => "/"
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index b11e0137..54c50193 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -8,6 +8,7 @@
require 'shoulda/matchers'
require 'factory_girl_rails'
require 'rails-controller-testing'
+require 'byebug'
Rails::Controller::Testing.install
diff --git a/spec/request/admin_rentals_spec.rb b/spec/request/admin_rentals_spec.rb
new file mode 100644
index 00000000..2076fc0b
--- /dev/null
+++ b/spec/request/admin_rentals_spec.rb
@@ -0,0 +1,44 @@
+require "rails_helper"
+
+describe "admin/rentals", type: :request do
+ let!(:account) { create(:account) }
+ let!(:remote_account) { create(:remote_account, account: account) }
+
+ describe "GET #index" do
+ subject(:get_rentals) { get "/admin/rentals", headers: { "HTTPS" => "on" } }
+
+ before do
+ allow_any_instance_of(BookingsyncPortal::Admin::RentalsController).to receive(:current_account).and_return(account)
+ end
+
+ context "when config's use_paginated_view returns false (default)" do
+ it "successfully renders page" do
+ get_rentals
+ expect(response).to have_http_status :ok
+ end
+ end
+
+ context "when config's use_paginated_view returns true" do
+ around do |example|
+ BookingsyncPortal.setup do |config|
+ config.use_paginated_view = ->(account) { account.persisted? } # anything as long as returns true
+ end
+ example.run
+ BookingsyncPortal.setup do |config|
+ config.use_paginated_view = ->(_account) { false }
+ end
+ end
+
+ before do
+ allow_any_instance_of(BookingsyncPortal::Admin::RentalsController).to receive(:current_account).and_return(account)
+ end
+
+ it "successfully renders page" do
+ get_rentals
+ expect(response).to redirect_to("/admin/v2/rentals")
+ follow_redirect!
+ expect(response).to have_http_status :ok
+ end
+ end
+ end
+end
diff --git a/spec/services/bookingsync_portal/filter_strategies/blank_remote_accounts_spec.rb b/spec/services/bookingsync_portal/filter_strategies/blank_remote_accounts_spec.rb
new file mode 100644
index 00000000..cedeb143
--- /dev/null
+++ b/spec/services/bookingsync_portal/filter_strategies/blank_remote_accounts_spec.rb
@@ -0,0 +1,27 @@
+require 'rails_helper'
+
+describe BookingsyncPortal::FilterStrategies::BlankRemoteAccounts do
+ describe ".call" do
+ subject(:call) { described_class.call(records: records, search_filter: search_filter) }
+
+ let(:search_filter) { BookingsyncPortal::SearchFilter.new({}) }
+
+ context "when records is RemoteAccount based" do
+ let(:records) { RemoteAccount.all }
+
+ it "delegates logic to searcher" do
+ expect(BookingsyncPortal::Searcher).to receive(:call)
+ call
+ end
+ end
+
+ context "when records is not RemoteAccount based" do
+ let(:records) { RemoteRental.all }
+
+ it "does not delegate logic to searcher and return current records" do
+ expect(BookingsyncPortal::Searcher).not_to receive(:call)
+ expect(call).to eq(records)
+ end
+ end
+ end
+end
diff --git a/spec/services/bookingsync_portal/filter_strategies/remote_rentals_spec.rb b/spec/services/bookingsync_portal/filter_strategies/remote_rentals_spec.rb
new file mode 100644
index 00000000..141a95d5
--- /dev/null
+++ b/spec/services/bookingsync_portal/filter_strategies/remote_rentals_spec.rb
@@ -0,0 +1,27 @@
+require 'rails_helper'
+
+describe BookingsyncPortal::FilterStrategies::RemoteRentals do
+ describe ".call" do
+ subject(:call) { described_class.call(records: records, search_filter: search_filter) }
+
+ let(:search_filter) { BookingsyncPortal::SearchFilter.new({}) }
+
+ context "when records is RemoteRental based" do
+ let(:records) { RemoteRental.all }
+
+ it "delegates logic to searcher" do
+ expect(BookingsyncPortal::Searcher).to receive(:call)
+ call
+ end
+ end
+
+ context "when records is not RemoteRental based" do
+ let(:records) { Rental.all }
+
+ it "does not delegate logic to searcher and return current records" do
+ expect(BookingsyncPortal::Searcher).not_to receive(:call)
+ expect(call).to eq(records)
+ end
+ end
+ end
+end
diff --git a/spec/services/bookingsync_portal/filter_strategies/rentals_spec.rb b/spec/services/bookingsync_portal/filter_strategies/rentals_spec.rb
new file mode 100644
index 00000000..616424f6
--- /dev/null
+++ b/spec/services/bookingsync_portal/filter_strategies/rentals_spec.rb
@@ -0,0 +1,27 @@
+require 'rails_helper'
+
+describe BookingsyncPortal::FilterStrategies::Rentals do
+ describe ".call" do
+ subject(:call) { described_class.call(records: records, search_filter: search_filter) }
+
+ let(:search_filter) { BookingsyncPortal::SearchFilter.new({}) }
+
+ context "when records is Rental based" do
+ let(:records) { Rental.all }
+
+ it "delegates logic to searcher" do
+ expect(BookingsyncPortal::Searcher).to receive(:call)
+ call
+ end
+ end
+
+ context "when records is not Rental based" do
+ let(:records) { RemoteRental.all }
+
+ it "does not delegate logic to searcher and return current records" do
+ expect(BookingsyncPortal::Searcher).not_to receive(:call)
+ expect(call).to eq(records)
+ end
+ end
+ end
+end
diff --git a/spec/services/bookingsync_portal/search_filter_spec.rb b/spec/services/bookingsync_portal/search_filter_spec.rb
new file mode 100644
index 00000000..6617ab04
--- /dev/null
+++ b/spec/services/bookingsync_portal/search_filter_spec.rb
@@ -0,0 +1,87 @@
+require 'rails_helper'
+
+describe BookingsyncPortal::SearchFilter do
+ let(:search_filter) { described_class.new(params) }
+ let(:params) do
+ {
+ rentals_search: rentals_search,
+ remote_rentals_search: remote_rentals_search,
+ }
+ end
+ let(:remote_rentals_search) { {} }
+ let(:rentals_search) { {} }
+
+ describe "#rentals_query" do
+ subject(:rentals_query) { search_filter.rentals_query }
+
+ let(:rentals_search) { { query: query } }
+
+ context "when query is blank" do
+ let(:query) { "" }
+
+ it { is_expected.to be_blank }
+ end
+
+ context "when query exists" do
+ let(:query) { "bla-bla" }
+
+ it { is_expected.to eq(query) }
+ end
+ end
+
+ describe "#remote_rentals_query" do
+ subject(:remote_rentals_query) { search_filter.remote_rentals_query }
+
+ let(:remote_rentals_search) { { query: query } }
+
+ context "when remote_rentals_page is blank" do
+ let(:query) { "" }
+
+ it { is_expected.to be_blank }
+ end
+
+ context "when query exists" do
+ let(:query) { "bla-bla" }
+
+ it { is_expected.to eq(query) }
+ end
+ end
+
+ describe "#rentals_page" do
+ subject(:rentals_page) { search_filter.rentals_page }
+
+ let(:rentals_search) { { page: page } }
+
+ context "when page is blank" do
+ let(:page) { "" }
+
+ it { is_expected.to eq(1) }
+ end
+
+ context "when page exists" do
+ let(:page) { 20 }
+
+ it { is_expected.to eq(page) }
+ end
+
+ end
+
+ describe "#remote_rentals_page" do
+ subject(:remote_rentals_page) { search_filter.remote_rentals_page }
+
+ let(:remote_rentals_search) { { page: page } }
+
+ context "when page is blank" do
+ let(:page) { "" }
+
+ it { is_expected.to eq(1) }
+ end
+
+ context "when page exists" do
+ let(:page) { 20 }
+
+ it { is_expected.to eq(page) }
+ end
+
+ end
+end
diff --git a/spec/services/bookingsync_portal/searcher_spec.rb b/spec/services/bookingsync_portal/searcher_spec.rb
new file mode 100644
index 00000000..59a17ab7
--- /dev/null
+++ b/spec/services/bookingsync_portal/searcher_spec.rb
@@ -0,0 +1,47 @@
+require 'rails_helper'
+
+describe BookingsyncPortal::Searcher do
+ describe ".call" do
+ subject(:call) { described_class.call(query: query, search_settings: search_settings, records: records) }
+
+ let(:records) { Rental.all }
+ let(:search_settings) do
+ {
+ numeric: %w(synced_id),
+ string: %w(synced_data)
+ }
+ end
+
+ context "when query is synced_id" do
+ let(:query) { "1" }
+
+ context "and there is rental with such synced_id" do
+ let!(:rental) { create(:rental, synced_id: query) }
+
+ it { is_expected.to contain_exactly(rental) }
+ end
+
+ context "and there is no rental with such synced_id" do
+ let!(:rental) { create(:rental, synced_id: query.to_i + 1) }
+
+ it { is_expected.to be_blank }
+ end
+ end
+
+ context "when query is string" do
+ let(:query) { "bla-bla" }
+
+ context "and there is rental with such synced_id" do
+ let!(:rental) { create(:rental, synced_data: { name: query }) }
+
+ it { is_expected.to contain_exactly(rental) }
+ end
+
+ context "and there is no rental with such synced_id" do
+ let!(:rental) { create(:rental, synced_data: { name: "zzz" }) }
+
+ it { is_expected.to be_blank }
+ end
+ end
+ end
+end