Compare commits
136 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a4d800c45e | |||
| 80a0d762fb | |||
| 7a8db04640 | |||
| e51b389328 | |||
| 3fba8ce18c | |||
| 37c6c4489f | |||
| e571f407ca | |||
| ccfe047ff3 | |||
| d5a5daaea7 | |||
| b86d85584f | |||
| 60890d78d7 | |||
| b646eeb48b | |||
| 3d46e5b806 | |||
| 3a09b9bcff | |||
| 1a7ebce6b4 | |||
| 7dc60fdfb8 | |||
| 6a020618c3 | |||
| b52ba6be1a | |||
| c4a1b857a9 | |||
| 91d0d5b8a6 | |||
| 6330a6b4e1 | |||
| 614a53b253 | |||
| 69e8e06975 | |||
| 54b2e4bec6 | |||
| 86085206e4 | |||
| 13730bf979 | |||
| fe136d1764 | |||
| 6b5be166f8 | |||
| a74eb11e32 | |||
| 3ca6055f47 | |||
| b4d028857a | |||
| 4bf08ca446 | |||
| b84a833d10 | |||
| b1017682bd | |||
| 828a88020e | |||
| 97b42e31cb | |||
| 2cc50d88ba | |||
| 93d121238b | |||
| 1e0eabcef6 | |||
| 91b33a8c63 | |||
| 18612e2efc | |||
| 5358752e26 | |||
| 2b5a0b2ccc | |||
| 13f4d04ca0 | |||
| 2d2acffede | |||
| 5e5be7ca9a | |||
| c622da90bd | |||
| 68339a3a0d | |||
| 92633e58ad | |||
| 501972870d | |||
| 69ce3f6b4c | |||
| 196174401e | |||
| 2134ea02ce | |||
| ef17b1f8f9 | |||
| e8a03473f7 | |||
| 1e34a17bd2 | |||
| 4f5d15fdab | |||
| 57c4b50c74 | |||
| 7086f156c0 | |||
| d72ed9eeec | |||
| 753acd9aee | |||
| 8685196ce9 | |||
|
|
5814f2fe4b | ||
|
|
a7b63fce83 | ||
|
|
0173aa76e6 | ||
|
|
d1fbff6372 | ||
|
|
10be40b25c | ||
|
|
3886936080 | ||
|
|
9a5220bf1e | ||
|
|
3900abf27f | ||
|
|
b0ed575892 | ||
|
|
2a501b3eec | ||
|
|
ffca28a0c7 | ||
|
|
71d86b9091 | ||
|
|
ac596c79e1 | ||
|
|
51a03a089d | ||
|
|
36f84bb1ac | ||
|
|
b550531219 | ||
|
|
f9050ee48a | ||
|
|
54e4443ff4 | ||
|
|
d8744e4c23 | ||
|
|
48a1a89f20 | ||
|
|
b2a459b51a | ||
|
|
001a88737f | ||
|
|
bc00ab5a3d | ||
|
|
0fd46f5da2 | ||
|
|
22d1f90684 | ||
|
|
af6893b679 | ||
|
|
392f580648 | ||
|
|
4acb86c4c0 | ||
|
|
6a6bfea612 | ||
|
|
b6d87b63b4 | ||
|
|
cc4395e3c3 | ||
|
|
8159492c84 | ||
|
|
eafbe7693d | ||
|
|
03c2f92397 | ||
|
|
2554c46aaf | ||
|
|
6f11e34298 | ||
|
|
4c2fbf5843 | ||
|
|
8a8f324fac | ||
|
|
c9c136f3f1 | ||
|
|
adf30b8399 | ||
|
|
0e45a8d621 | ||
|
|
f82590d31f | ||
|
|
49885a3149 | ||
|
|
f15b7e2172 | ||
|
|
57f8aaa938 | ||
|
|
4c52336fd4 | ||
|
|
8a325a31b1 | ||
|
|
76c61e1358 | ||
|
|
d01f4c7486 | ||
|
|
0bd8f226d4 | ||
|
|
666e3fb798 | ||
|
|
deb01bef12 | ||
|
|
1b40b6c7b3 | ||
|
|
d01c0ccf10 | ||
|
|
96635964be | ||
|
|
8d75df244d | ||
|
|
fba063cf4f | ||
|
|
37b36345af | ||
|
|
0cb3232f39 | ||
|
|
1085ed17a6 | ||
|
|
77fa19dee7 | ||
|
|
5ceee4bac4 | ||
|
|
54156c2956 | ||
|
|
d6c58efe0c | ||
|
|
b23d044438 | ||
|
|
59fe16033a | ||
|
|
584f364964 | ||
|
|
cf1e1b7493 | ||
|
|
2a9c4a6a76 | ||
|
|
ff63178547 | ||
|
|
d28b412add | ||
|
|
b8755a783b | ||
|
|
aafc0db112 | ||
|
|
917d02a4e5 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
# Corrections? Improvements? Create a GitHub issue:
|
||||
# http://github.com/RailsApps/rails-composer/issues
|
||||
#----------------------------------------------------------------------------
|
||||
/spec/reports/
|
||||
|
||||
# ctags
|
||||
tags
|
||||
|
||||
8
Capfile
8
Capfile
@ -4,12 +4,13 @@ require 'capistrano/setup'
|
||||
# Includes default deployment tasks
|
||||
require 'capistrano/deploy'
|
||||
|
||||
require 'capistrano/rbenv'
|
||||
require 'capistrano/puma'
|
||||
install_plugin Capistrano::Puma # Default puma tasks
|
||||
require 'capistrano/puma/workers'
|
||||
require 'capistrano/puma/jungle'
|
||||
require 'capistrano/rbenv'
|
||||
require 'capistrano/bundler'
|
||||
require 'capistrano/nginx'
|
||||
# require 'capistrano/nginx'
|
||||
require 'capistrano/rails/assets'
|
||||
require 'capistrano/rails/migrations'
|
||||
require 'capistrano/postgresql'
|
||||
@ -19,7 +20,8 @@ require 'capistrano/postgresql'
|
||||
# Includes tasks from other gems included in your Gemfile
|
||||
#
|
||||
# For documentation on these, see for example:
|
||||
#
|
||||
require "capistrano/scm/git"
|
||||
install_plugin Capistrano::SCM::Git#
|
||||
# https://github.com/capistrano/rvm
|
||||
# https://github.com/capistrano/rbenv
|
||||
# https://github.com/capistrano/chruby
|
||||
|
||||
16
Gemfile
16
Gemfile
@ -1,6 +1,8 @@
|
||||
source 'https://rubygems.org'
|
||||
ruby '2.6.0'
|
||||
gem 'rails', '5.2.2'
|
||||
# TODO Upgrade sprockets
|
||||
gem 'sprockets', '~> 3.7'
|
||||
gem 'sass-rails' #, '~> 4.0.3'
|
||||
gem 'uglifier' #, '>= 1.3.0'
|
||||
gem 'coffee-rails' #, '~> 4.0.0'
|
||||
@ -8,7 +10,6 @@ gem 'jquery-rails'
|
||||
gem 'turbolinks'
|
||||
gem 'jbuilder' #, '~> 2.0'
|
||||
gem 'sdoc', group: :doc #, '~> 0.4.0'
|
||||
gem 'spring', group: :development
|
||||
gem 'devise'
|
||||
gem 'devise_invitable'
|
||||
gem 'haml-rails'
|
||||
@ -17,10 +18,10 @@ gem 'pg'
|
||||
gem 'puma'
|
||||
gem 'pundit'
|
||||
gem 'simple_form'
|
||||
gem 'upmin-admin'
|
||||
gem 'dotenv-rails'
|
||||
gem 'react-rails'
|
||||
# gem 'react-rails-hot-loader'
|
||||
gem 'ci_reporter_rspec'
|
||||
group :development do
|
||||
gem 'parallel_tests', group: :development
|
||||
gem 'better_errors'
|
||||
@ -30,7 +31,7 @@ group :development do
|
||||
gem 'capistrano-bundler'
|
||||
gem 'capistrano-rails'
|
||||
gem 'capistrano-rails-console'
|
||||
gem 'capistrano3-puma'
|
||||
gem 'capistrano3-puma', '~> 3'
|
||||
gem 'capistrano-rbenv'
|
||||
gem 'capistrano-nginx', github: 'koenpunt/capistrano-nginx'
|
||||
gem "capistrano-db-tasks", require: false
|
||||
@ -47,21 +48,24 @@ group :development do
|
||||
gem 'rb-fchange', require: false
|
||||
gem 'rb-fsevent', require: false
|
||||
gem 'rb-inotify', require: false
|
||||
gem 'spring-commands-rspec'
|
||||
# gem 'spring-commands-rspec'
|
||||
gem 'guard-ctags-bundler'
|
||||
end
|
||||
group :development, :test, :staging do
|
||||
group :development, :test do
|
||||
gem 'factory_girl_rails'
|
||||
gem 'faker'
|
||||
gem 'pry-rails'
|
||||
gem 'pry-rescue'
|
||||
gem 'rspec-rails'
|
||||
gem 'spring'
|
||||
gem 'spring-commands-rspec'
|
||||
end
|
||||
group :test, :staging do
|
||||
gem 'capybara'
|
||||
gem 'database_cleaner'
|
||||
gem "poltergeist"
|
||||
gem 'launchy'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'webdrivers'
|
||||
gem 'simplecov', :require => false
|
||||
end
|
||||
gem 'capybara-screenshot', :group => :test
|
||||
|
||||
419
Gemfile.lock
419
Gemfile.lock
@ -49,114 +49,125 @@ GEM
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.6.0)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
airbrussh (1.3.1)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
airbrussh (1.4.0)
|
||||
sshkit (>= 1.6.1, != 1.7.0)
|
||||
arel (9.0.0)
|
||||
ast (2.4.0)
|
||||
ast (2.4.2)
|
||||
babel-source (5.8.35)
|
||||
babel-transpiler (0.7.0)
|
||||
babel-source (>= 4.0, < 6)
|
||||
execjs (~> 2.0)
|
||||
bcrypt (3.1.12)
|
||||
better_errors (2.5.1)
|
||||
bcrypt (3.1.16)
|
||||
better_errors (2.9.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubi (>= 1.0.0)
|
||||
rack (>= 0.9.0)
|
||||
binding_of_caller (0.8.0)
|
||||
binding_of_caller (1.0.0)
|
||||
debug_inspector (>= 0.0.1)
|
||||
builder (3.2.3)
|
||||
capistrano (3.11.0)
|
||||
builder (3.2.4)
|
||||
capistrano (3.16.0)
|
||||
airbrussh (>= 1.0.0)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (>= 1.9.0)
|
||||
capistrano-bundler (1.5.0)
|
||||
capistrano-bundler (2.0.1)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-db-tasks (0.6)
|
||||
capistrano (>= 3.0.0)
|
||||
capistrano-postgresql (6.2.0)
|
||||
capistrano (>= 3.0)
|
||||
sshkit (>= 1.17.0)
|
||||
capistrano-rails (1.4.0)
|
||||
capistrano-rails (1.6.1)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-bundler (>= 1.1, < 3)
|
||||
capistrano-rails-console (2.3.0)
|
||||
capistrano (>= 3.5.0, < 4.0.0)
|
||||
sshkit-interactive (~> 0.3.0)
|
||||
capistrano-rbenv (2.1.4)
|
||||
capistrano-rbenv (2.2.0)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.3)
|
||||
capistrano3-puma (3.1.1)
|
||||
capistrano (~> 3.7)
|
||||
capistrano-bundler
|
||||
puma (~> 3.4)
|
||||
capybara (3.14.0)
|
||||
capybara (3.36.0)
|
||||
addressable
|
||||
matrix
|
||||
mini_mime (>= 0.1.3)
|
||||
nokogiri (~> 1.8)
|
||||
rack (>= 1.6.0)
|
||||
rack-test (>= 0.6.3)
|
||||
regexp_parser (~> 1.2)
|
||||
regexp_parser (>= 1.5, < 3.0)
|
||||
xpath (~> 3.2)
|
||||
chartkick (3.0.2)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
cliver (0.3.2)
|
||||
coderay (1.1.2)
|
||||
coffee-rails (4.2.2)
|
||||
capybara-screenshot (1.0.25)
|
||||
capybara (>= 1.0, < 4)
|
||||
launchy
|
||||
childprocess (4.1.0)
|
||||
ci_reporter (2.0.0)
|
||||
builder (>= 2.1.2)
|
||||
ci_reporter_rspec (1.0.0)
|
||||
ci_reporter (~> 2.0)
|
||||
rspec (>= 2.14, < 4)
|
||||
coderay (1.1.3)
|
||||
coffee-rails (5.0.0)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0)
|
||||
railties (>= 5.2.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.1.4)
|
||||
connection_pool (2.2.2)
|
||||
crass (1.0.4)
|
||||
database_cleaner (1.7.0)
|
||||
debug_inspector (0.0.3)
|
||||
devise (4.6.1)
|
||||
concurrent-ruby (1.1.9)
|
||||
connection_pool (2.2.5)
|
||||
crass (1.0.6)
|
||||
database_cleaner (2.0.1)
|
||||
database_cleaner-active_record (~> 2.0.0)
|
||||
database_cleaner-active_record (2.0.1)
|
||||
activerecord (>= 5.a)
|
||||
database_cleaner-core (~> 2.0.0)
|
||||
database_cleaner-core (2.0.1)
|
||||
debug_inspector (1.1.0)
|
||||
devise (4.8.0)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise_invitable (2.0.0)
|
||||
devise_invitable (2.0.5)
|
||||
actionmailer (>= 5.0)
|
||||
devise (>= 4.6)
|
||||
diff-lcs (1.3)
|
||||
docile (1.3.1)
|
||||
dotenv (2.7.1)
|
||||
dotenv-rails (2.7.1)
|
||||
dotenv (= 2.7.1)
|
||||
railties (>= 3.2, < 6.1)
|
||||
em-websocket (0.5.1)
|
||||
diff-lcs (1.4.4)
|
||||
docile (1.4.0)
|
||||
dotenv (2.7.6)
|
||||
dotenv-rails (2.7.6)
|
||||
dotenv (= 2.7.6)
|
||||
railties (>= 3.2)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
erubi (1.8.0)
|
||||
http_parser.rb (~> 0)
|
||||
erubi (1.10.0)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.7.0)
|
||||
execjs (2.8.1)
|
||||
factory_girl (4.9.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.9.0)
|
||||
factory_girl (~> 4.9.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.9.3)
|
||||
i18n (>= 0.7)
|
||||
ffi (1.10.0)
|
||||
formatador (0.2.5)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
guard (2.15.0)
|
||||
faker (2.19.0)
|
||||
i18n (>= 1.6, < 2)
|
||||
ffi (1.15.4)
|
||||
formatador (0.3.0)
|
||||
globalid (0.5.2)
|
||||
activesupport (>= 5.0)
|
||||
guard (2.18.0)
|
||||
formatador (>= 0.2.4)
|
||||
listen (>= 2.7, < 4.0)
|
||||
lumberjack (>= 1.0.12, < 2.0)
|
||||
nenv (~> 0.1)
|
||||
notiffany (~> 0.0)
|
||||
pry (>= 0.9.12)
|
||||
pry (>= 0.13.0)
|
||||
shellany (~> 0.0)
|
||||
thor (>= 0.18.1)
|
||||
guard-bundler (2.2.1)
|
||||
@ -179,103 +190,86 @@ GEM
|
||||
guard (~> 2.1)
|
||||
guard-compat (~> 1.1)
|
||||
rspec (>= 2.99.0, < 4.0)
|
||||
haml (5.0.4)
|
||||
haml (5.2.2)
|
||||
temple (>= 0.8.0)
|
||||
tilt
|
||||
haml-rails (2.0.0)
|
||||
haml-rails (2.0.1)
|
||||
actionpack (>= 5.1)
|
||||
activesupport (>= 5.1)
|
||||
haml (>= 4.0.6, < 6.0)
|
||||
html2haml (>= 1.0.1)
|
||||
railties (>= 5.1)
|
||||
high_voltage (3.1.0)
|
||||
high_voltage (3.1.2)
|
||||
html2haml (2.2.0)
|
||||
erubis (~> 2.7.0)
|
||||
haml (>= 4.0, < 6)
|
||||
nokogiri (>= 1.6.0)
|
||||
ruby_parser (~> 3.5)
|
||||
http_parser.rb (0.6.0)
|
||||
http_parser.rb (0.8.0)
|
||||
hub (1.12.4)
|
||||
i18n (1.6.0)
|
||||
i18n (1.8.11)
|
||||
concurrent-ruby (~> 1.0)
|
||||
interception (0.5)
|
||||
jaro_winkler (1.5.2)
|
||||
jbuilder (2.8.0)
|
||||
activesupport (>= 4.2.0)
|
||||
multi_json (>= 1.2)
|
||||
jquery-rails (4.3.3)
|
||||
jbuilder (2.11.2)
|
||||
activesupport (>= 5.0.0)
|
||||
jquery-rails (4.4.0)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.2.0)
|
||||
kaminari (1.1.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
kaminari-activerecord (= 1.1.1)
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-actionview (1.1.1)
|
||||
actionview
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-activerecord (1.1.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-core (1.1.1)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby_dep (~> 1.2)
|
||||
loofah (2.2.3)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
listen (3.7.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.12.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
lumberjack (1.0.13)
|
||||
lumberjack (1.2.8)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (0.3.3)
|
||||
mimemagic (~> 0.3.2)
|
||||
method_source (0.9.2)
|
||||
mimemagic (0.3.3)
|
||||
mini_mime (1.0.1)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
multi_json (1.13.1)
|
||||
matrix (0.4.2)
|
||||
method_source (1.0.0)
|
||||
mimemagic (0.3.10)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.6.1)
|
||||
minitest (5.14.4)
|
||||
multi_json (1.15.0)
|
||||
nenv (0.3.0)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (5.1.0)
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.10.1)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
notiffany (0.1.1)
|
||||
net-scp (3.0.0)
|
||||
net-ssh (>= 2.6.5, < 7.0.0)
|
||||
net-ssh (6.1.0)
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.12.5)
|
||||
mini_portile2 (~> 2.6.1)
|
||||
racc (~> 1.4)
|
||||
notiffany (0.1.3)
|
||||
nenv (~> 0.1)
|
||||
shellany (~> 0.0)
|
||||
orm_adapter (0.5.0)
|
||||
parallel (1.14.0)
|
||||
parallel_tests (2.28.0)
|
||||
parallel (1.21.0)
|
||||
parallel_tests (3.7.3)
|
||||
parallel
|
||||
parser (2.6.0.0)
|
||||
ast (~> 2.4.0)
|
||||
pg (1.1.4)
|
||||
poltergeist (1.18.1)
|
||||
capybara (>= 2.1, < 4)
|
||||
cliver (~> 0.3.1)
|
||||
websocket-driver (>= 0.2.0)
|
||||
powerpack (0.1.2)
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
parser (3.0.2.0)
|
||||
ast (~> 2.4.1)
|
||||
pg (1.2.3)
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
pry-rescue (1.5.0)
|
||||
pry-rescue (1.5.2)
|
||||
interception (>= 0.5)
|
||||
pry (>= 0.12.0)
|
||||
psych (3.1.0)
|
||||
public_suffix (3.0.3)
|
||||
puma (3.12.0)
|
||||
pundit (2.0.1)
|
||||
public_suffix (4.0.6)
|
||||
puma (3.12.6)
|
||||
pundit (2.1.1)
|
||||
activesupport (>= 3.0.0)
|
||||
rack (2.0.6)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack-livereload (0.3.17)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
@ -296,8 +290,8 @@ GEM
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
rails-html-sanitizer (1.4.2)
|
||||
loofah (~> 2.3)
|
||||
rails_layout (1.0.42)
|
||||
railties (5.2.2)
|
||||
actionpack (= 5.2.2)
|
||||
@ -306,130 +300,123 @@ GEM
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
rake (12.3.2)
|
||||
ransack (2.1.1)
|
||||
actionpack (>= 5.0)
|
||||
activerecord (>= 5.0)
|
||||
activesupport (>= 5.0)
|
||||
i18n
|
||||
rake (13.0.6)
|
||||
rb-fchange (0.0.6)
|
||||
ffi
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.0)
|
||||
rb-fsevent (0.11.0)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rdoc (6.1.1)
|
||||
react-rails (2.4.7)
|
||||
rdoc (6.3.3)
|
||||
react-rails (2.6.1)
|
||||
babel-transpiler (>= 0.7.0)
|
||||
connection_pool
|
||||
execjs
|
||||
railties (>= 3.2)
|
||||
tilt
|
||||
regexp_parser (1.3.0)
|
||||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
railties (>= 4.2.0, < 6.0)
|
||||
rspec (3.8.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-core (3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-expectations (3.8.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-mocks (3.8.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-rails (3.8.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.8.0)
|
||||
rspec-expectations (~> 3.8.0)
|
||||
rspec-mocks (~> 3.8.0)
|
||||
rspec-support (~> 3.8.0)
|
||||
rspec-support (3.8.0)
|
||||
rubocop (0.65.0)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.5, != 2.5.1.1)
|
||||
powerpack (~> 0.1)
|
||||
psych (>= 3.1.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.4.0)
|
||||
ruby-progressbar (1.10.0)
|
||||
ruby_dep (1.5.0)
|
||||
ruby_parser (3.12.0)
|
||||
sexp_processor (~> 4.9)
|
||||
rubyzip (1.2.2)
|
||||
sass (3.7.3)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
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)
|
||||
sdoc (1.0.0)
|
||||
rdoc (>= 5.0)
|
||||
selenium-webdriver (3.141.0)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.2, >= 1.2.2)
|
||||
sexp_processor (4.11.0)
|
||||
shellany (0.0.1)
|
||||
simple_form (4.1.0)
|
||||
regexp_parser (2.1.1)
|
||||
responders (3.0.1)
|
||||
actionpack (>= 5.0)
|
||||
activemodel (>= 5.0)
|
||||
simplecov (0.16.1)
|
||||
railties (>= 5.0)
|
||||
rexml (3.2.5)
|
||||
rspec (3.10.0)
|
||||
rspec-core (~> 3.10.0)
|
||||
rspec-expectations (~> 3.10.0)
|
||||
rspec-mocks (~> 3.10.0)
|
||||
rspec-core (3.10.1)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-expectations (3.10.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-mocks (3.10.2)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-rails (5.0.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rspec-core (~> 3.10)
|
||||
rspec-expectations (~> 3.10)
|
||||
rspec-mocks (~> 3.10)
|
||||
rspec-support (~> 3.10)
|
||||
rspec-support (3.10.3)
|
||||
rubocop (1.22.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.0.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml
|
||||
rubocop-ast (>= 1.12.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.13.0)
|
||||
parser (>= 3.0.1.1)
|
||||
ruby-progressbar (1.11.0)
|
||||
ruby_parser (3.18.1)
|
||||
sexp_processor (~> 4.16)
|
||||
rubyzip (2.3.2)
|
||||
sass-rails (6.0.0)
|
||||
sassc-rails (~> 2.1, >= 2.1.1)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
sdoc (2.2.0)
|
||||
rdoc (>= 5.0)
|
||||
selenium-webdriver (4.0.3)
|
||||
childprocess (>= 0.5, < 5.0)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2)
|
||||
sexp_processor (4.16.0)
|
||||
shellany (0.0.1)
|
||||
simple_form (5.1.0)
|
||||
actionpack (>= 5.2)
|
||||
activemodel (>= 5.2)
|
||||
simplecov (0.21.2)
|
||||
docile (~> 1.1)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
spring (2.0.2)
|
||||
activesupport (>= 4.2)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov_json_formatter (~> 0.1)
|
||||
simplecov-html (0.12.3)
|
||||
simplecov_json_formatter (0.1.3)
|
||||
spring (3.0.0)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets-rails (3.3.0)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
sshkit (1.18.2)
|
||||
sshkit (1.21.2)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
sshkit-interactive (0.3.0)
|
||||
sshkit (~> 1.12)
|
||||
temple (0.8.1)
|
||||
thor (0.20.3)
|
||||
temple (0.8.2)
|
||||
thor (1.1.0)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.9)
|
||||
turbolinks (5.2.0)
|
||||
tilt (2.0.10)
|
||||
turbolinks (5.2.1)
|
||||
turbolinks-source (~> 5.2)
|
||||
turbolinks-source (5.2.0)
|
||||
tzinfo (1.2.5)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (4.1.20)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.4.1)
|
||||
upmin-admin (0.1.3)
|
||||
chartkick
|
||||
haml (>= 3.0.0)
|
||||
jquery-rails
|
||||
kaminari
|
||||
rails
|
||||
ransack
|
||||
sass-rails
|
||||
warden (1.2.8)
|
||||
rack (>= 2.0.6)
|
||||
websocket-driver (0.7.0)
|
||||
unicode-display_width (2.1.0)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
webdrivers (5.0.0)
|
||||
nokogiri (~> 1.6)
|
||||
rubyzip (>= 1.3.0)
|
||||
selenium-webdriver (~> 4.0)
|
||||
websocket-driver (0.7.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.5)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
|
||||
@ -447,8 +434,10 @@ DEPENDENCIES
|
||||
capistrano-rails
|
||||
capistrano-rails-console
|
||||
capistrano-rbenv
|
||||
capistrano3-puma
|
||||
capistrano3-puma (~> 3)
|
||||
capybara
|
||||
capybara-screenshot
|
||||
ci_reporter_rspec
|
||||
coffee-rails
|
||||
database_cleaner
|
||||
devise
|
||||
@ -470,7 +459,6 @@ DEPENDENCIES
|
||||
launchy
|
||||
parallel_tests
|
||||
pg
|
||||
poltergeist
|
||||
pry-rails
|
||||
pry-rescue
|
||||
puma
|
||||
@ -491,12 +479,13 @@ DEPENDENCIES
|
||||
simplecov
|
||||
spring
|
||||
spring-commands-rspec
|
||||
sprockets (~> 3.7)
|
||||
turbolinks
|
||||
uglifier
|
||||
upmin-admin
|
||||
webdrivers
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.6.0p0
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.2
|
||||
1.17.3
|
||||
|
||||
122
Guardfile
122
Guardfile
@ -35,10 +35,10 @@ guard :bundler do
|
||||
files.each { |file| watch(helper.real_path(file)) }
|
||||
end
|
||||
|
||||
#guard 'rails', host: '127.0.0.1' do
|
||||
# watch('Gemfile.lock')
|
||||
# watch(%r{^(config|lib)/.*})
|
||||
#end
|
||||
guard 'rails', host: '0.0.0.0', port: 9913 do
|
||||
watch('Gemfile.lock')
|
||||
watch(%r{^(config|lib)/.*})
|
||||
end
|
||||
|
||||
|
||||
# Note: The cmd option is now required due to the increasing number of ways
|
||||
@ -50,61 +50,61 @@ end
|
||||
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
||||
# * 'just' rspec: 'rspec'
|
||||
|
||||
rspec_options = {
|
||||
cmd: "bundle exec spring rspec",
|
||||
all_after_pass: false,
|
||||
failed_mode: :focus,
|
||||
# run_all: {
|
||||
# cmd: "bundle exec parallel_rspec -o '",
|
||||
# cmd_additional_args: "'"
|
||||
#rspec_options = {
|
||||
# cmd: "bundle exec rspec",
|
||||
# all_after_pass: false,
|
||||
# failed_mode: :focus,
|
||||
## run_all: {
|
||||
## cmd: "bundle exec parallel_rspec -o '",
|
||||
## cmd_additional_args: "'"
|
||||
## }
|
||||
#}
|
||||
}
|
||||
guard :rspec, rspec_options do #, failed_mode: :focus
|
||||
require "guard/rspec/dsl"
|
||||
dsl = Guard::RSpec::Dsl.new(self)
|
||||
notification :off
|
||||
|
||||
# Feel free to open issues for suggestions and improvements
|
||||
|
||||
# RSpec files
|
||||
rspec = dsl.rspec
|
||||
watch(rspec.spec_helper) { rspec.spec_dir }
|
||||
watch(rspec.spec_support) { rspec.spec_dir }
|
||||
watch(rspec.spec_files)
|
||||
|
||||
# Ruby files
|
||||
ruby = dsl.ruby
|
||||
dsl.watch_spec_files_for(ruby.lib_files)
|
||||
|
||||
# Rails files
|
||||
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
||||
dsl.watch_spec_files_for(rails.app_files)
|
||||
dsl.watch_spec_files_for(rails.views)
|
||||
|
||||
watch(rails.controllers) do |m|
|
||||
[
|
||||
rspec.spec.("routing/#{m[1]}_routing"),
|
||||
rspec.spec.("controllers/#{m[1]}_controller"),
|
||||
rspec.spec.("acceptance/#{m[1]}")
|
||||
]
|
||||
end
|
||||
|
||||
# Rails config changes
|
||||
watch(rails.spec_helper) { rspec.spec_dir }
|
||||
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
||||
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
||||
|
||||
# Capybara features specs
|
||||
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
||||
|
||||
# Turnip features and steps
|
||||
watch(%r{^spec/acceptance/(.+)\.feature$})
|
||||
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
||||
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
||||
end
|
||||
end
|
||||
|
||||
guard 'ctags-bundler', src_path: ["app", "lib", "spec/support"], project_file: "tags" do
|
||||
watch(/^(app|lib|spec\/support)\/.*\.rb$/)
|
||||
watch('Gemfile.lock')
|
||||
end
|
||||
#guard :rspec, rspec_options do #, failed_mode: :focus
|
||||
# require "guard/rspec/dsl"
|
||||
# dsl = Guard::RSpec::Dsl.new(self)
|
||||
# notification :off
|
||||
#
|
||||
# # Feel free to open issues for suggestions and improvements
|
||||
#
|
||||
# # RSpec files
|
||||
# rspec = dsl.rspec
|
||||
# watch(rspec.spec_helper) { rspec.spec_dir }
|
||||
# watch(rspec.spec_support) { rspec.spec_dir }
|
||||
# watch(rspec.spec_files)
|
||||
#
|
||||
# # Ruby files
|
||||
# ruby = dsl.ruby
|
||||
# dsl.watch_spec_files_for(ruby.lib_files)
|
||||
#
|
||||
# # Rails files
|
||||
# rails = dsl.rails(view_extensions: %w(erb haml slim))
|
||||
# dsl.watch_spec_files_for(rails.app_files)
|
||||
# dsl.watch_spec_files_for(rails.views)
|
||||
#
|
||||
# watch(rails.controllers) do |m|
|
||||
# [
|
||||
# rspec.spec.("routing/#{m[1]}_routing"),
|
||||
# rspec.spec.("controllers/#{m[1]}_controller"),
|
||||
# rspec.spec.("acceptance/#{m[1]}")
|
||||
# ]
|
||||
# end
|
||||
#
|
||||
# # Rails config changes
|
||||
# watch(rails.spec_helper) { rspec.spec_dir }
|
||||
# watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
||||
# watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
||||
#
|
||||
# # Capybara features specs
|
||||
# watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
||||
#
|
||||
# # Turnip features and steps
|
||||
# watch(%r{^spec/acceptance/(.+)\.feature$})
|
||||
# watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
||||
# Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
||||
# end
|
||||
#end
|
||||
#
|
||||
#guard 'ctags-bundler', src_path: ["app", "lib", "spec/support"], project_file: "tags" do
|
||||
# watch(/^(app|lib|spec\/support)\/.*\.rb$/)
|
||||
# watch('Gemfile.lock')
|
||||
#end
|
||||
|
||||
9
Rakefile
9
Rakefile
@ -5,3 +5,12 @@
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
|
||||
Rails.application.load_tasks
|
||||
|
||||
require 'ci/reporter/rake/rspec'
|
||||
|
||||
# ...
|
||||
# Rake code that creates a task called `:rspec`
|
||||
# ...
|
||||
|
||||
task :rspec => 'ci:setup:rspec'
|
||||
task :spec => 'ci:setup:rspec'
|
||||
|
||||
@ -13,8 +13,18 @@
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require turbolinks
|
||||
//= require react
|
||||
//= require react_ujs
|
||||
// require react
|
||||
// require react_ujs
|
||||
//= require components
|
||||
//= require qrcode.min.js
|
||||
// require react-rails-hot-loader
|
||||
//= require_tree .
|
||||
// require_tree .
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
setInterval(function() {
|
||||
// $('#table-component').load("#{request.path} #table-component");
|
||||
$('#play-to-beat').load("#{request.path} #play-to-beat");
|
||||
$('#play-buttons').load("#{request.path} #play-buttons");
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
7
app/assets/javascripts/table-loader.js
Normal file
7
app/assets/javascripts/table-loader.js
Normal file
@ -0,0 +1,7 @@
|
||||
$(document).ready(function(){
|
||||
setInterval(function() {
|
||||
if ( $('.taking-turn.player[data-soft-token=' + soft_token + ']').length < 1 ) {
|
||||
$('#table-component').load(window.location.pathname +" #table-component");
|
||||
}
|
||||
}, 5000);
|
||||
});
|
||||
@ -40,7 +40,7 @@ h1
|
||||
|
||||
header
|
||||
font-size: 3vmin
|
||||
margin-bottom: 10vmin
|
||||
// margin-bottom: 10vmin
|
||||
nav
|
||||
padding: 1vmin
|
||||
background: #222
|
||||
|
||||
@ -27,9 +27,11 @@
|
||||
|
||||
//// Show Game#show
|
||||
|
||||
button
|
||||
button,
|
||||
input[type=submit]
|
||||
font-size: 4vmin
|
||||
|
||||
#table-component,
|
||||
#game-component-container-container
|
||||
display: flex
|
||||
flex-direction: column
|
||||
@ -110,35 +112,73 @@ ol#cards-to-beat
|
||||
flex-wrap: wrap
|
||||
text-align: center
|
||||
li
|
||||
position: relative
|
||||
margin-left: -21vmin
|
||||
// Don't offset first card
|
||||
&:first-of-type
|
||||
margin-left: -4vmin
|
||||
flex: 1 1 auto
|
||||
//flex: 1 1 auto
|
||||
text-align: center
|
||||
display: inline-block
|
||||
img
|
||||
width: 6vmin
|
||||
width: 16vmin
|
||||
border: 1px solid black
|
||||
border-radius: .3vmin
|
||||
|
||||
|
||||
////// Inventory
|
||||
|
||||
.player form
|
||||
.player
|
||||
&.taking-turn
|
||||
font-weight: bold
|
||||
box-shadow: 0px 0px .5vmin 1vmin inset rgba(white,0.2)
|
||||
ul#inventory
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
text-align: left
|
||||
li
|
||||
margin-left: -21vmin
|
||||
// Don't offset first card
|
||||
&:first-of-type
|
||||
// margin-left: 0
|
||||
margin-left: -4vmin
|
||||
flex: 1 1 auto
|
||||
input[type="checkbox"]
|
||||
visibility: hidden
|
||||
// Capybara test requires visible checkbox
|
||||
// visibility: hidden
|
||||
opacity: .000001
|
||||
position: absolute
|
||||
&:checked ~ img
|
||||
box-shadow: 0px 0px 2px 6px cadetblue
|
||||
box-shadow: 0px 0px 2px 5px #05adff, inset 0 0 2px 3px #056dff
|
||||
margin-top: -2vmin
|
||||
img
|
||||
width: 6vmin
|
||||
width: 26vmin
|
||||
border: 1px solid black
|
||||
border-radius: .3vmin
|
||||
border-radius: 1.2vmin
|
||||
transition: margin-top ease-out .10s
|
||||
|
||||
#mid
|
||||
ul#inventory
|
||||
margin-left: 8vmin
|
||||
li
|
||||
margin-left: -8vmin
|
||||
// Don't offset first card
|
||||
&:first-of-type
|
||||
// margin-left: -0vmin
|
||||
img
|
||||
width: 16vmin
|
||||
|
||||
.inventory
|
||||
text-align: left
|
||||
|
||||
.inventory
|
||||
text-align: center
|
||||
img
|
||||
width: 6vmin
|
||||
border: 1px solid black
|
||||
border: 2px solid black
|
||||
border-radius: .3vmin
|
||||
margin-left: -2vmin
|
||||
// Don't offset first card
|
||||
&:first-of-type
|
||||
// margin-left: 0vmin
|
||||
|
||||
23
app/assets/stylesheets/tables.css.sass
Normal file
23
app/assets/stylesheets/tables.css.sass
Normal file
@ -0,0 +1,23 @@
|
||||
#table-component, #table-component-container, .table
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
#table-controls
|
||||
text-align: right
|
||||
padding: 0 1em
|
||||
#newgame
|
||||
float: left
|
||||
|
||||
#qrcode
|
||||
float: right
|
||||
margin-top: -.5em
|
||||
margin-right: 1em
|
||||
transform: scale(10%)
|
||||
transition: all 0.5s ease-in-out
|
||||
width: 38px
|
||||
height: 38px
|
||||
&.full
|
||||
margin-right: 2em
|
||||
transform: scale(100%)
|
||||
width: 384px
|
||||
height: 384px
|
||||
@ -1,10 +0,0 @@
|
||||
// Place all the styles related to the Tables controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
||||
#table-component-container-container,
|
||||
#table-component-container,
|
||||
.table {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@ -35,23 +35,27 @@ class GamesController < ApplicationController
|
||||
|
||||
# Player action: pass
|
||||
# TODO: wtf do we need game params for? And why nest hand_type in it?
|
||||
if params[:game]
|
||||
if params[:game][:hand_type] == 'pass'
|
||||
# if params[:game]
|
||||
if params[:hand_type] == 'Pass'
|
||||
@game.set_controlling_player 'next'
|
||||
flash[:notice] = 'Successfully passed.'
|
||||
# Clear play to beat if play returns to owner
|
||||
if @game.play_to_beat.try(:player).try(:id) == @game.controlling_player_id
|
||||
@game.play_to_beat_id = nil
|
||||
end
|
||||
@game.save
|
||||
end
|
||||
end
|
||||
|
||||
# Player action: play_hand
|
||||
if params[:player_card_ids]
|
||||
elsif params[:player_card_ids]
|
||||
@cards_to_play = @game.controlling_player.try(:player_cards).order(:value).find(params[:player_card_ids])
|
||||
# Instantiate the play
|
||||
@play = @game.controlling_player.plays.new
|
||||
@play.game_id = @game.id
|
||||
|
||||
# TODO Bug next player fails if inventory is empty
|
||||
@next_player_id = @game.next_player_id
|
||||
@play.player_cards << @cards_to_play
|
||||
if @play.save
|
||||
@game.set_controlling_player 'next'
|
||||
@game.controlling_player_id = @next_player_id
|
||||
@game.save
|
||||
else
|
||||
# TODO: Does anything need to happen here?
|
||||
@ -74,8 +78,9 @@ class GamesController < ApplicationController
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(@game) }
|
||||
## TODO: Return status message of attempt to play_hand
|
||||
# flash[:notice] = 'I hi'
|
||||
format.html { redirect_to(@game.table) }
|
||||
format.json { render json: @game }
|
||||
end
|
||||
|
||||
@ -104,10 +109,12 @@ class GamesController < ApplicationController
|
||||
|
||||
def play_now
|
||||
# First joinable game or create new game
|
||||
@game = Game.play_now(current_user)
|
||||
@seats = @game.seats.order(:position).map {|s| s.occupied? ? nil : s}
|
||||
@seats.compact.last.sit(current_user)
|
||||
redirect_to @game
|
||||
@game = Game.play_now
|
||||
@seats = @game.table.seats.order(:position).map {|s| s.occupied? ? nil : s}
|
||||
# @seats = @game.table.seats
|
||||
@seat = @seats.compact.last.sit(current_user)
|
||||
@seat.save
|
||||
redirect_to @game.table
|
||||
end
|
||||
|
||||
def join
|
||||
@ -123,12 +130,12 @@ class GamesController < ApplicationController
|
||||
@game.errors.messages.each do |key, msg|
|
||||
flash[key] = msg.join
|
||||
end
|
||||
redirect_to(@game)
|
||||
redirect_to(@game.table)
|
||||
return
|
||||
end
|
||||
flash[:notice] = 'Game started.'
|
||||
|
||||
redirect_to(@game)
|
||||
redirect_to(@game.table)
|
||||
end
|
||||
|
||||
def my_inventory
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
class SeatsController < ApplicationController
|
||||
before_action :set_seat, only: [:show, :edit, :update, :destroy, :sit, :stand]
|
||||
before_action :set_seat, only: [:show, :edit, :update, :destroy,
|
||||
:sit, :stand, :add_bot, :remove_bot, :empty,
|
||||
:remove_player]
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
@ -66,10 +68,38 @@ class SeatsController < ApplicationController
|
||||
# POST /seats/1
|
||||
def sit
|
||||
@message = @seat.sit current_user
|
||||
respond_to do |format|
|
||||
if @seat.save
|
||||
format.html { redirect_to @seat.table, notice: 'Seat was successfully sat in.' }
|
||||
else
|
||||
format.html { redirect_to @seat.table, notice: 'Failed to sit.' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def stand
|
||||
@message = @seat.stand current_user
|
||||
redirect_to @seat.table, notice: @message
|
||||
end
|
||||
|
||||
def add_bot
|
||||
@message = @seat.add_bot
|
||||
redirect_to @seat.table, notice: @message
|
||||
end
|
||||
|
||||
def remove_bot
|
||||
@message = @seat.remove_bot
|
||||
redirect_to @seat.table, notice: @message
|
||||
end
|
||||
|
||||
def empty
|
||||
@message = @seat.empty
|
||||
redirect_to @seat.table, notice: @message
|
||||
end
|
||||
|
||||
def remove_player
|
||||
@message = @seat.remove_player
|
||||
redirect_to @seat.table, notice: @message
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -1,8 +1,26 @@
|
||||
class TablesController < ApplicationController
|
||||
before_action :set_table, only: [:show, :edit, :update, :destroy]
|
||||
before_action :set_table, only: [:show, :edit, :update, :destroy, :new_game]
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
def play_now
|
||||
# First empty seat
|
||||
@seat = Seat.where(user_soft_token: nil).select{|s| !s.player.try("is_bot?")}.first
|
||||
if @seat
|
||||
@seat.sit current_user
|
||||
else
|
||||
@table = Table.create(title: "Table " + current_user.soft_token[0..4])
|
||||
@seat = @table.seats.first
|
||||
@seat.sit current_user
|
||||
end
|
||||
redirect_to @seat.table
|
||||
# @game = Game.play_now(current_user)
|
||||
# @table = @game.table
|
||||
# @seats = @table.seats.order(:position).map {|s| s.occupied? ? nil : s}
|
||||
# @seat = @seats.compact.last.sit(current_user)
|
||||
end
|
||||
|
||||
|
||||
# GET /tables
|
||||
# GET /tables.json
|
||||
def index
|
||||
@ -12,6 +30,29 @@ class TablesController < ApplicationController
|
||||
# GET /tables/1
|
||||
# GET /tables/1.json
|
||||
def show
|
||||
# TODO refactor to ensure play for 2nd and 3rd place
|
||||
|
||||
if @game.controlling_player.try("is_bot?")
|
||||
@game.controlling_player.auto_play
|
||||
@game.save
|
||||
@game.reload
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def new_game
|
||||
@game = @table.add_game
|
||||
begin
|
||||
@game.start
|
||||
rescue
|
||||
flash[:errors] = @game.errors
|
||||
end
|
||||
redirect_to @table
|
||||
end
|
||||
|
||||
def tutorial
|
||||
flash[:notice] = "Tutorial coming soon!"
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
# GET /tables/new
|
||||
@ -67,6 +108,8 @@ class TablesController < ApplicationController
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_table
|
||||
@table = Table.find(params[:id])
|
||||
@game = @table.current_game
|
||||
@seats = @table.seats.order(:id)
|
||||
end
|
||||
|
||||
# Never trust parameters from the scary internet, only allow the white list through.
|
||||
|
||||
@ -40,7 +40,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
# If you have extra params to permit, append them to the sanitizer.
|
||||
def configure_sign_up_params
|
||||
devise_parameter_sanitizer.for(:sign_up) << :soft_token
|
||||
devise_parameter_sanitizer.permit(:sign_up, keys: [:soft_token])
|
||||
end
|
||||
|
||||
# If you have extra params to permit, append them to the sanitizer.
|
||||
|
||||
@ -6,8 +6,8 @@ class Game < ActiveRecord::Base
|
||||
has_many :users, through: :players
|
||||
has_many :player_cards, through: :players
|
||||
has_many :plays, through: :players
|
||||
has_one :controlling_player
|
||||
belongs_to :play_to_beat
|
||||
belongs_to :controlling_player, class_name: "Player", foreign_key: "controlling_player_id"
|
||||
accepts_nested_attributes_for :players
|
||||
#validates :title, presence: true
|
||||
after_create :add_table
|
||||
@ -45,19 +45,16 @@ class Game < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def winner
|
||||
begin
|
||||
self.players.find(self.winner_player_id)
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
self.players.find_by_id(self.winner_player_id)
|
||||
end
|
||||
|
||||
def validate_startable
|
||||
@player_count = players.count
|
||||
errors[:players] = 'Must be at least 2 players.' if @player_count < 2
|
||||
errors[:players] = 'Must be less than 5 players.' if @player_count > 4
|
||||
errors[:status] = 'Game already started...' if self.status.nil? == false
|
||||
errors[:player_cards] = 'Cards already dealt...' unless player_cards.empty?
|
||||
@user_count = players.where.not(soft_token: nil).count
|
||||
errors.add(:players, 'Must be at least 2 players.') if @player_count < 2
|
||||
errors.add(:players, 'Must be less than 5 players.') if @player_count > 4
|
||||
errors.add(:status, 'Game already started...') if self.status.nil? == false
|
||||
errors.add(:player_cards, 'Cards already dealt...') unless player_cards.empty?
|
||||
fail StandardError, errors if errors.count > 0
|
||||
return true
|
||||
end
|
||||
@ -83,6 +80,12 @@ class Game < ActiveRecord::Base
|
||||
new_player = self.players.create(user: user, soft_token: user.soft_token)
|
||||
end
|
||||
|
||||
def add_player_bot
|
||||
# todo return if game is full
|
||||
# return false unless self.joinable?(user)
|
||||
new_player = self.players.create(is_bot: true)
|
||||
end
|
||||
|
||||
def remove_player_from_user(user)
|
||||
return false unless self.has_user? user
|
||||
|
||||
@ -93,7 +96,8 @@ class Game < ActiveRecord::Base
|
||||
end
|
||||
|
||||
if @player
|
||||
@player.destroy
|
||||
@player.user_id = nil
|
||||
@player.soft_token = nil
|
||||
end
|
||||
|
||||
end
|
||||
@ -119,7 +123,7 @@ class Game < ActiveRecord::Base
|
||||
|
||||
|
||||
def full?
|
||||
players.count >= 4
|
||||
# players.count >= 4
|
||||
end
|
||||
|
||||
def set_controlling_player(arg)
|
||||
@ -127,24 +131,27 @@ class Game < ActiveRecord::Base
|
||||
when 'next'
|
||||
self.controlling_player_id = self.next_player_id
|
||||
end
|
||||
|
||||
# Clear play to beat if play returns to owner
|
||||
# if self.play_to_beat.try(:player).try(:id) == self.controlling_player_id
|
||||
# self.play_to_beat_id = nil
|
||||
# end
|
||||
end
|
||||
|
||||
def joinable? user
|
||||
!self.has_user?(user) && !self.full?
|
||||
# !self.has_user?(user) && !self.full?
|
||||
!self.full?
|
||||
end
|
||||
|
||||
def player_ids_by_seat_order
|
||||
player_ids = self.seats.order(:position).select {|s| s.player_id}.map {|s| s.player_id}
|
||||
player_ids = self.seats.order(:position).select {|s| ( s.player.present? && s.player.inventory.count > 0) ? s.player_id : nil}.compact.map {|s| s.player_id}
|
||||
end
|
||||
|
||||
def next_player_id
|
||||
@controlling_player_index = self.player_ids_by_seat_order.index(controlling_player_id)
|
||||
player_ids_by_seat_order[(@controlling_player_index + 1) % self.player_ids.length]
|
||||
end
|
||||
|
||||
# The player whose turn it is
|
||||
def controlling_player
|
||||
self.players.find(self.controlling_player_id)
|
||||
# TODO Fix bug
|
||||
@controlling_player_index ||= 0
|
||||
player_ids_by_seat_order[(@controlling_player_index + 1) % self.player_ids_by_seat_order.length]
|
||||
end
|
||||
|
||||
# The user whose turn it is
|
||||
@ -175,6 +182,14 @@ private
|
||||
def add_table
|
||||
self.table ||= Table.create current_game_id: self.id
|
||||
self.seats = self.table.seats
|
||||
self.seats.each do |seat|
|
||||
# if (seat.user_id || seat.user_soft_token)
|
||||
if (seat.occupied?)
|
||||
new_player = self.players.create(user_id: seat.user_id, soft_token: seat.user_soft_token, is_bot: seat.player.is_bot)
|
||||
seat.player = new_player
|
||||
seat.save
|
||||
end
|
||||
end
|
||||
self.save
|
||||
end
|
||||
|
||||
|
||||
@ -14,9 +14,10 @@ class Play < ActiveRecord::Base
|
||||
after_save :set_controlling_player
|
||||
|
||||
def check_for_winner
|
||||
return if self.game.winner.present?
|
||||
if self.game.over?
|
||||
self.game.winner_player_id = self.player.id
|
||||
self.game.status = "Player #{self.player.id} wins!"
|
||||
self.game.status = "Player #{self.player.display_name} wins!"
|
||||
self.game.save
|
||||
end
|
||||
end
|
||||
@ -60,16 +61,18 @@ class Play < ActiveRecord::Base
|
||||
# current player is not the player to beat
|
||||
if (game.player_to_beat != player)
|
||||
# valid bomb?
|
||||
if (self.hand_type == 'bomb' && game.play_to_beat.try("play").try("hand_type") == 'single' && game.play_to_beat.try("play").try("player_cards")[0].try('rank') == '2')
|
||||
# if (self.hand_type =~ /bomb|double run/ && game.play_to_beat.try("play").try("hand_type") == 'single' && game.play_to_beat.try("play").try("player_cards")[0].try('rank') == '2')
|
||||
if (self.hand_type =~ /bomb|double run/)
|
||||
@truths << true
|
||||
return @truths
|
||||
end
|
||||
# hand_type match?
|
||||
@truths << (self.hand_type == game.play_to_beat.try("play").try("hand_type")) if game.play_to_beat.try("play").try(:hand_type)
|
||||
else
|
||||
# hand_type match? allows partial match i.e. "triple run (suited)"
|
||||
@truths << (self.hand_type.match game.play_to_beat.try("play").try("hand_type")) if game.play_to_beat.try("play").try(:hand_type)
|
||||
# beats?
|
||||
@truths << (self.beats? self.game.play_to_beat.try(:play))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if has_player_cards
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
class PlayToBeat < ActiveRecord::Base
|
||||
belongs_to :game
|
||||
belongs_to :play
|
||||
has_one :player, through: :play
|
||||
end
|
||||
|
||||
@ -15,7 +15,10 @@ class Player < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def display_name
|
||||
self.try(:user).try(:email) || "Guest#{self.soft_token[0..5]}"
|
||||
return user.email if self.user
|
||||
return "BotPlayer" if self.is_bot?
|
||||
return ("Guest" + self.soft_token)[0..9] if self.soft_token
|
||||
return "Empty"
|
||||
end
|
||||
|
||||
def play_hand(cards)
|
||||
@ -28,7 +31,65 @@ class Player < ActiveRecord::Base
|
||||
return false unless self.game.controlling_player == self
|
||||
|
||||
self.game.set_controlling_player 'next'
|
||||
# Clear play to beat if play returns to owner
|
||||
if self.game.play_to_beat.try(:player).try(:id) == self.game.controlling_player_id
|
||||
self.game.play_to_beat_id = nil
|
||||
end
|
||||
self.game.save
|
||||
end
|
||||
|
||||
def runs
|
||||
@runs = self.inventory.chunk_while {|i, j| i.rank.to_i+1 == j.rank.to_i }
|
||||
end
|
||||
|
||||
def triple_runs
|
||||
@triple_runs = self.runs.map{|r| r.length > 2 ? r : nil}.compact
|
||||
end
|
||||
|
||||
def auto_play
|
||||
# TODO not sure this return clause works
|
||||
return false unless self.game.controlling_player == self
|
||||
|
||||
# If first play of game, play lowest card
|
||||
if self.game.plays.empty?
|
||||
@cards_to_play = [self.inventory[0]]
|
||||
return self.play_hand @cards_to_play
|
||||
end
|
||||
|
||||
# If open table
|
||||
if !self.game.play_to_beat
|
||||
@cards_to_play = self.inventory[0..0]
|
||||
else
|
||||
@cards_to_beat = self.game.play_to_beat.play.player_cards
|
||||
case self.game.play_to_beat.play.hand_type
|
||||
when "single"
|
||||
@cards_to_play = self.inventory.where("value > #{@cards_to_beat.min.value}")[0..0]
|
||||
when "double"
|
||||
@doubles = self.inventory.group_by {|card| card.rank}.map{|c| c if c[1].length > 1}.compact
|
||||
if @doubles.present?
|
||||
if @doubles[0][1][0..1].max.value > @cards_to_beat.max.value
|
||||
@cards_to_play = @doubles[0][1][0..1]
|
||||
end
|
||||
end
|
||||
when "triple run"
|
||||
@runs = self.inventory.chunk_while {|i, j| i.rank.to_i+1 == j.rank.to_i }
|
||||
@triple_runs = @runs.map{|r| r.length > 2 ? r : nil}.compact
|
||||
if @triple_runs.present?
|
||||
@cards_to_play = @triple_runs[0][0..2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if @cards_to_play.present?
|
||||
if @cards_to_beat.present?
|
||||
if (@cards_to_play.max_by{|c| c.value}.value > @cards_to_beat.max_by{|c| c.value}.value)
|
||||
return self.play_hand @cards_to_play
|
||||
end
|
||||
else
|
||||
return self.play_hand @cards_to_play
|
||||
end
|
||||
end
|
||||
self.pass
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -6,36 +6,107 @@ class Seat < ActiveRecord::Base
|
||||
|
||||
def sit(current_user)
|
||||
if self.occupied?
|
||||
return "Error. Seat is occupied."
|
||||
return self
|
||||
else
|
||||
# Stand up from any other seats at this table
|
||||
current_user.stand_from(self.table)
|
||||
|
||||
self.reload
|
||||
if self.player == nil
|
||||
self.player_id = self.table.current_game.add_player_from_user(current_user).id
|
||||
end
|
||||
|
||||
self.player.user_id = current_user.id
|
||||
self.player.soft_token = current_user.soft_token
|
||||
self.player.save
|
||||
|
||||
self.user_id = current_user.id
|
||||
self.user_soft_token = current_user.soft_token
|
||||
self.save
|
||||
|
||||
return "Successfully sat."
|
||||
return self.save
|
||||
end
|
||||
end
|
||||
|
||||
def stand(current_user)
|
||||
unless self.occupied_by?(current_user)
|
||||
def stand(user)
|
||||
unless self.occupied_by?(user)
|
||||
return "Error. Seat not occupied by you."
|
||||
else
|
||||
self.table.current_game.remove_player_from_user(current_user)
|
||||
# self.table.current_game.remove_player_from_user(user)
|
||||
self.player.user = nil
|
||||
self.player.soft_token = nil
|
||||
self.player.save
|
||||
self.user_id = nil
|
||||
self.user_soft_token = nil
|
||||
self.player_id = nil
|
||||
# self.player_id = nil
|
||||
self.save
|
||||
return "Successfully stood up."
|
||||
end
|
||||
end
|
||||
|
||||
def add_bot
|
||||
if self.occupied?
|
||||
return "Failed to add Bot seat full"
|
||||
else
|
||||
# self.reload
|
||||
if self.player == nil
|
||||
# add player to game
|
||||
@bot_player = self.table.current_game.players.new(is_bot: true)
|
||||
# @bot_player = self.table.current_game.add_player_from_user(current_user).id
|
||||
self.player = @bot_player
|
||||
self.player.save
|
||||
self.save
|
||||
return "Added Bot"
|
||||
else
|
||||
self.player.is_bot = true
|
||||
self.player.save
|
||||
return "Added Bot"
|
||||
end
|
||||
|
||||
return "Failed to add Bot"
|
||||
end
|
||||
end
|
||||
|
||||
def remove_bot
|
||||
if !self.occupied?
|
||||
return "Failed to remove Bot seat empty"
|
||||
else
|
||||
if self.player.is_bot?
|
||||
self.player.is_bot = false
|
||||
self.player.save
|
||||
return "Removed Bot"
|
||||
end
|
||||
|
||||
return "Failed to remove Bot"
|
||||
end
|
||||
end
|
||||
|
||||
def empty
|
||||
self.player.user = nil
|
||||
self.player.soft_token = nil
|
||||
self.player.is_bot = false
|
||||
self.player.save
|
||||
self.user_id = nil
|
||||
self.user_soft_token = nil
|
||||
# self.player_id = nil
|
||||
self.save
|
||||
return "Successfully stood up."
|
||||
end
|
||||
|
||||
def remove_player
|
||||
if !self.player
|
||||
return "No player to remove"
|
||||
else
|
||||
self.player.destroy
|
||||
self.user_id = nil
|
||||
self.user_soft_token = nil
|
||||
# self.player_id = nil
|
||||
self.save
|
||||
return "Successfully removed player"
|
||||
end
|
||||
end
|
||||
|
||||
def occupied?
|
||||
self.user_id.present? || self.user_soft_token.present?
|
||||
self.user_id.present? || self.user_soft_token.present? || self.try("player").try("is_bot?") == true
|
||||
end
|
||||
|
||||
def occupied_by? user
|
||||
|
||||
@ -3,6 +3,7 @@ class Table < ActiveRecord::Base
|
||||
has_many :seats
|
||||
has_many :users, through: :seats
|
||||
has_many :games
|
||||
has_many :players, through: :games
|
||||
#TODO: Deprecated current_game_id from database.
|
||||
# Instead calculate with self.current_game
|
||||
#
|
||||
@ -12,10 +13,28 @@ class Table < ActiveRecord::Base
|
||||
after_create :add_seats
|
||||
after_create :add_game
|
||||
|
||||
# Returns the newest joinable table or creates a new table if none are found
|
||||
# scope :play_now, lambda { |user|
|
||||
# where(status:nil).joins("LEFT OUTER JOIN players ON players.table_id = tables.id").group("tables.id").having("count(players) < 4").last || Table.create(title: "Game " + user.soft_token[0..4])
|
||||
# }
|
||||
scope :play_now, lambda { |user|
|
||||
# where(status:nil).joins("LEFT OUTER JOIN players ON players.game_id = games.id").group("games.id").having("count(players) < 4").last || Table.create(title: "Game " + user.soft_token[0..4])
|
||||
where(game:nil).last || Table.create(title: "Table " + user.soft_token[0..4])
|
||||
}
|
||||
|
||||
def user_count
|
||||
self.seats.map{|s| s.occupied? ? s : nil}.compact.count
|
||||
end
|
||||
|
||||
def current_game
|
||||
self.games.last
|
||||
end
|
||||
|
||||
|
||||
def add_game
|
||||
self.games.create
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_seats
|
||||
@ -24,7 +43,4 @@ class Table < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def add_game
|
||||
self.games.create if self.current_game_id.blank?
|
||||
end
|
||||
end
|
||||
|
||||
@ -25,6 +25,7 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def stand_from(table)
|
||||
return if table == nil
|
||||
@seats = []
|
||||
if self.id
|
||||
@seats << table.seats.where(user_id: self.id)
|
||||
@ -33,11 +34,7 @@ class User < ActiveRecord::Base
|
||||
@seats << table.seats.where(user_soft_token: self.soft_token)
|
||||
end
|
||||
@seats.flatten.each do |seat|
|
||||
seat.try(:player).try(:destroy)
|
||||
seat.user_id = nil
|
||||
seat.player_id = nil
|
||||
seat.user_soft_token = nil
|
||||
seat.save
|
||||
seat.stand(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,47 +1,47 @@
|
||||
#game-component-container-container= react_component 'Game', props = {id: @game.id, current_user: current_user}, html_options = {id: "game-component-container"}
|
||||
-# #game-component-container-container= react_component 'Game', props = {id: @game.id, current_user: current_user}, html_options = {id: "game-component-container"}
|
||||
|
||||
-# TODO: Remove deprecated commented out code
|
||||
-#%p
|
||||
%b Status:
|
||||
%p
|
||||
= @game.status
|
||||
|
||||
-#%p
|
||||
%p
|
||||
%b Title:
|
||||
= @game.title
|
||||
|
||||
-#- if @game.can_accomodate(current_user)
|
||||
= link_to 'Join', game_join_path(@game)
|
||||
- if @game.can_accomodate(current_user)
|
||||
= link_to 'Join', join_game_path(@game)
|
||||
|
||||
-#- if @game.startable? && @game.already_has?(current_user)
|
||||
= link_to 'Start', game_start_path(@game)
|
||||
- if @game.startable? && @game.already_has?(current_user)
|
||||
= link_to 'Start', start_game_path(@game)
|
||||
|
||||
-#.debug
|
||||
= button_to 'Debug Start', game_start_path(@game), method: :get
|
||||
= link_to 'Edit Game', edit_game_path(@game)
|
||||
|
||||
-#.players
|
||||
.players
|
||||
%b Players:
|
||||
%ol
|
||||
- @game.players.each do |player|
|
||||
%li
|
||||
|
||||
// Show the users email TODO show username instead
|
||||
= player.user.email
|
||||
= player.display_name
|
||||
|
||||
// Show the user which player they are
|
||||
= "Me" if player.user == current_user
|
||||
|
||||
// Show whose turn it is
|
||||
- if @game.controlling_player_id
|
||||
%strong= "My Turn " if @game.controlling_player == player
|
||||
%strong= "Taking Turn " if @game.controlling_player == player
|
||||
|
||||
// Show the players' cards
|
||||
- if player.user == current_user && player.inventory.empty? == false
|
||||
-##inventory
|
||||
|
||||
|
||||
-# TODO better logic, not in view
|
||||
-#- unless @game.status == nil
|
||||
-#.table
|
||||
- unless @game.status == nil
|
||||
.table
|
||||
-# TODO better logic, not in view. Set play to beat = nil; instead of view logic
|
||||
- if @game.play_to_beat && @game.player_to_beat != @game.controlling_player
|
||||
- if @game.play_to_beat.play
|
||||
@ -49,14 +49,14 @@
|
||||
Hand to beat
|
||||
%span.hand-type= @game.play_to_beat.play.hand_type
|
||||
%div= @game.play_to_beat.play.to_s
|
||||
-#- @game.play_to_beat.play.player_cards.each do |card|
|
||||
- @game.play_to_beat.play.player_cards.each do |card|
|
||||
= card.to_s
|
||||
%span.player= @game.play_to_beat.play.player.user.email
|
||||
%span.player= @game.play_to_beat.play.player.display_name
|
||||
- else
|
||||
%h1 Open table
|
||||
|
||||
.controls
|
||||
- if @game.control_user == current_user
|
||||
- if @game.controlling_user == current_user
|
||||
// Play hand form
|
||||
= form_for @game, :url => play_hand_game_path(@game), remote: true do |f|
|
||||
// Provide id of current game
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>ThirteenTienLen</title>
|
||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
|
||||
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
|
||||
<%= csrf_meta_tags %>
|
||||
<%= yield :head %>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@ -5,3 +5,7 @@ This web application was created with
|
||||
<%= link_to('Rails Composer', 'http://railsapps.github.io/rails-composer/') %>
|
||||
from the <%= link_to('RailsApps project', 'http://railsapps.github.io/') %>.
|
||||
</p>
|
||||
<p>
|
||||
The domain name address was obtained from Afraid.org
|
||||
<%= link_to('Free DNS', 'https://freedns.afraid.org/') %>
|
||||
</p>
|
||||
|
||||
18
app/views/tables/_play_to_beat.html.haml
Normal file
18
app/views/tables/_play_to_beat.html.haml
Normal file
@ -0,0 +1,18 @@
|
||||
#play-to-beat
|
||||
%h4 Hand to beat:
|
||||
- if @game.play_to_beat == nil
|
||||
None
|
||||
- else
|
||||
|
||||
%div.hand-type= @game.play_to_beat.play.hand_type.capitalize
|
||||
%span= @game.play_to_beat.play.to_s
|
||||
-# - @game.play_to_beat.play.player_cards.each do |card|
|
||||
= card.to_s
|
||||
%div= @game.play_to_beat.play.try("player").try("display_name")
|
||||
%ol#cards-to-beat
|
||||
- @game.play_to_beat.play.player_cards.reverse.each_with_index do |card, index|
|
||||
%li{style: "z-index: #{100 - index};"}
|
||||
-# TODO: Don't hard code face cards here
|
||||
%img{alt: card.rank + ' ' + card.suit,
|
||||
src: "#{image_path('cards/png/' + (card.rank.gsub('J','jack').gsub('Q','queen').gsub('K','king').gsub('A','ace') + '_of_' + card.suit.downcase + 's.png').gsub('11','jack').gsub('12','queen').gsub('13','king').gsub('14','ace').gsub('15','2'))}" }
|
||||
|
||||
61
app/views/tables/_seat.html.haml
Normal file
61
app/views/tables/_seat.html.haml
Normal file
@ -0,0 +1,61 @@
|
||||
- @game = seat.game
|
||||
.seat{class: "position-#{@seats.index(seat) + 1}"}
|
||||
.seat-controls
|
||||
- if seat.occupied?
|
||||
- if seat.player.is_bot?
|
||||
-# = button_to remove_bot_seat_path(seat) do
|
||||
- "- Bot"
|
||||
- if seat.occupied_by? current_user
|
||||
-# = button_to stand_seat_path(seat), :data => { :confirm => 'Are you sure you want to leave this seat?' } do
|
||||
= button_to stand_seat_path(seat) do
|
||||
- "Leave"
|
||||
- else
|
||||
-# = button_to empty_seat_path(seat), :data => { :confirm => 'Are you sure you want to empty this seat?' } do
|
||||
= button_to empty_seat_path(seat) do
|
||||
- "Empty"
|
||||
- else
|
||||
= button_to sit_seat_path(seat) do
|
||||
- "Sit"
|
||||
= button_to add_bot_seat_path(seat) do
|
||||
- "+ Bot"
|
||||
|
||||
- if seat.player
|
||||
-# = button_to remove_player_seat_path(seat), :data => { :confirm => 'Are you sure you want to remove this player?' } do
|
||||
= button_to remove_player_seat_path(seat) do
|
||||
- "Remove Player"
|
||||
.player{id: "player-#{seat.player.id}", class: @game.controlling_player == seat.player ? "taking-turn" : "",
|
||||
data: {soft_token: seat.player.soft_token} }
|
||||
.user-name= seat.player.display_name
|
||||
- if @game.started?
|
||||
.inventory-count= seat.player.inventory.count
|
||||
|
||||
-# Show player controls if player is owned by current_user
|
||||
- if seat.player.soft_token == current_user.soft_token
|
||||
= form_for(@game,
|
||||
url: play_hand_game_path(@game),
|
||||
method: "post",
|
||||
name: "player_controls_" + seat.player_id.to_s,
|
||||
id: "player_controls_" + seat.player_id.to_s) do |f|
|
||||
%ul#inventory
|
||||
- seat.player.inventory.each do |card|
|
||||
%li
|
||||
%label
|
||||
= check_box_tag 'player_card_ids[]',
|
||||
card.id,
|
||||
false,
|
||||
data: {value: card.id, card_name: card.rank.gsub('11','J') .gsub('12','Q') .gsub('13','K') .gsub('14','A') .gsub('15','2') + ' ' + card.suit}
|
||||
|
||||
-# %input{form: "player_controls_" + card.player_id.to_s,
|
||||
type: "checkbox",
|
||||
name: "player_card_ids[]",
|
||||
data: {value: card.id, card_name: card.rank.gsub('11','J') .gsub('12','Q') .gsub('13','K') .gsub('14','A') .gsub('15','2') + ' ' + card.suit}}
|
||||
= image_tag('cards/png/' + (card.rank.gsub('J','jack').gsub('Q','queen').gsub('K','king').gsub('A','ace') + '_of_' + card.suit.downcase + 's.png').gsub('11','jack') .gsub('12','queen') .gsub('13','king') .gsub('14','ace') .gsub('15','2'))
|
||||
- disabled = @game.controlling_player != seat.player
|
||||
#play-buttons
|
||||
%input{type: "submit", value: "Play Hand", name: "hand_type", disabled: disabled}
|
||||
%input{type: "submit", value: "Pass", name: "hand_type", disabled: disabled}
|
||||
|
||||
- else
|
||||
.inventory
|
||||
- seat.player.inventory.count.times do |index|
|
||||
= image_tag('cards/png/back-pink.png')
|
||||
0
app/views/tables/_seats.html.haml
Normal file
0
app/views/tables/_seats.html.haml
Normal file
@ -6,7 +6,7 @@
|
||||
- @tables.each do |table|
|
||||
.table
|
||||
.title= link_to table.title, table
|
||||
.player-count= "#{table.users.count} Players"
|
||||
.player-count= "#{table.user_count} Players"
|
||||
|
||||
- if policy(table).update?
|
||||
.owner-controls
|
||||
|
||||
@ -3,4 +3,57 @@
|
||||
= link_to 'Edit', edit_table_path(@table)
|
||||
= link_to 'Destroy', game, :method => :delete, :data => { :confirm => 'Are you sure?' }
|
||||
|
||||
#table-component-container-container= react_component 'Table', props = {url: "#{table_path @table}"}, html_options = {id: "table-component-container"}
|
||||
-# #table-component-container-container= react_component 'Table', props = {url: "#{table_path @table}"}, html_options = {id: "table-component-container"}
|
||||
#table-component
|
||||
|
||||
%p= @table.title
|
||||
|
||||
- if @game.already_has?(current_user)
|
||||
- if @game.startable?
|
||||
= button_to 'Start', start_game_path(@game)
|
||||
|
||||
-# - if @game.winner_player_id || @game.nil?
|
||||
-# = button_to 'New Game', new_game_table_path(@table)
|
||||
|
||||
-# - if @game && !@game.startable?
|
||||
#table-controls
|
||||
#newgame= button_to 'New Game', new_game_table_path(@table)
|
||||
|
||||
#qrcode
|
||||
:javascript
|
||||
function gen_qrcode(){
|
||||
var qrcode = new QRCode(document.getElementById("qrcode"), {
|
||||
text: "#{request.original_url}",
|
||||
width: 384,
|
||||
height: 384,
|
||||
colorDark : "#000000",
|
||||
colorLight : "#ffffff00",
|
||||
correctLevel : QRCode.CorrectLevel.H
|
||||
});
|
||||
}
|
||||
gen_qrcode();
|
||||
$('#qrcode').on('click', function(e) {
|
||||
$('#qrcode').toggleClass("full");
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
#game-component
|
||||
- if @game.winner_player_id
|
||||
%h1= @game.status
|
||||
|
||||
#playerList
|
||||
#top
|
||||
= render "seat", seat: @seats[0]
|
||||
#mid
|
||||
= render "seat", seat: @seats[3]
|
||||
|
||||
= render "play_to_beat"
|
||||
|
||||
= render "seat", seat: @seats[1]
|
||||
|
||||
#bot
|
||||
= render "seat", seat: @seats[2]
|
||||
|
||||
:javascript
|
||||
var soft_token = "#{current_user.soft_token}";
|
||||
-# = javascript_include_tag 'table-loader'
|
||||
|
||||
@ -4,4 +4,5 @@
|
||||
#main-menu
|
||||
= link_to 'Play Now', play_now_path
|
||||
= link_to 'Browse Tables', tables_path
|
||||
= link_to 'Tutorial', '#'
|
||||
= link_to 'Tutorial', tutorial_path
|
||||
= link_to 'About', page_path('about')
|
||||
|
||||
106
bin/bundle
106
bin/bundle
@ -1,3 +1,105 @@
|
||||
#!/usr/bin/env ruby
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
# The application 'bundle' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require "rubygems"
|
||||
|
||||
m = Module.new do
|
||||
module_function
|
||||
|
||||
def invoked_as_script?
|
||||
File.expand_path($0) == File.expand_path(__FILE__)
|
||||
end
|
||||
|
||||
def env_var_version
|
||||
ENV["BUNDLER_VERSION"]
|
||||
end
|
||||
|
||||
def cli_arg_version
|
||||
return unless invoked_as_script? # don't want to hijack other binstubs
|
||||
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
|
||||
bundler_version = nil
|
||||
update_index = nil
|
||||
ARGV.each_with_index do |a, i|
|
||||
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
||||
bundler_version = a
|
||||
end
|
||||
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
||||
bundler_version = $1 || ">= 0.a"
|
||||
update_index = i
|
||||
end
|
||||
bundler_version
|
||||
end
|
||||
|
||||
def gemfile
|
||||
gemfile = ENV["BUNDLE_GEMFILE"]
|
||||
return gemfile if gemfile && !gemfile.empty?
|
||||
|
||||
File.expand_path("../../Gemfile", __FILE__)
|
||||
end
|
||||
|
||||
def lockfile
|
||||
lockfile =
|
||||
case File.basename(gemfile)
|
||||
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
|
||||
else "#{gemfile}.lock"
|
||||
end
|
||||
File.expand_path(lockfile)
|
||||
end
|
||||
|
||||
def lockfile_version
|
||||
return unless File.file?(lockfile)
|
||||
lockfile_contents = File.read(lockfile)
|
||||
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
||||
Regexp.last_match(1)
|
||||
end
|
||||
|
||||
def bundler_version
|
||||
@bundler_version ||= begin
|
||||
env_var_version || cli_arg_version ||
|
||||
lockfile_version || "#{Gem::Requirement.default}.a"
|
||||
end
|
||||
end
|
||||
|
||||
def load_bundler!
|
||||
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
||||
|
||||
# must dup string for RG < 1.8 compatibility
|
||||
activate_bundler(bundler_version.dup)
|
||||
end
|
||||
|
||||
def activate_bundler(bundler_version)
|
||||
if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
|
||||
bundler_version = "< 2"
|
||||
end
|
||||
gem_error = activation_error_handling do
|
||||
gem "bundler", bundler_version
|
||||
end
|
||||
return if gem_error.nil?
|
||||
require_error = activation_error_handling do
|
||||
require "bundler/version"
|
||||
end
|
||||
return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
||||
warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
|
||||
exit 42
|
||||
end
|
||||
|
||||
def activation_error_handling
|
||||
yield
|
||||
nil
|
||||
rescue StandardError, LoadError => e
|
||||
e
|
||||
end
|
||||
end
|
||||
|
||||
m.load_bundler!
|
||||
|
||||
if m.invoked_as_script?
|
||||
load Gem.bin_path("bundler", "bundle")
|
||||
end
|
||||
|
||||
23
bin/puma
23
bin/puma
@ -1,4 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
@ -6,11 +8,22 @@
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'pathname'
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
||||
|
||||
load Gem.bin_path('puma', 'puma')
|
||||
if File.file?(bundle_binstub)
|
||||
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
||||
load(bundle_binstub)
|
||||
else
|
||||
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
||||
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
||||
end
|
||||
end
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
|
||||
load Gem.bin_path("puma", "puma")
|
||||
|
||||
23
bin/pumactl
23
bin/pumactl
@ -1,4 +1,6 @@
|
||||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
@ -6,11 +8,22 @@
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'pathname'
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
||||
|
||||
load Gem.bin_path('puma', 'pumactl')
|
||||
if File.file?(bundle_binstub)
|
||||
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
||||
load(bundle_binstub)
|
||||
else
|
||||
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
||||
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
||||
end
|
||||
end
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
|
||||
load Gem.bin_path("puma", "pumactl")
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
#!/usr/bin/env ruby
|
||||
begin
|
||||
load File.expand_path('../spring', __FILE__)
|
||||
rescue LoadError => e
|
||||
raise unless e.message.include?('spring')
|
||||
end
|
||||
if ENV['RAILS_ENV'] == 'development'
|
||||
ENV['PORT'] = '9012'
|
||||
end
|
||||
|
||||
5
bin/rake
5
bin/rake
@ -1,4 +1,9 @@
|
||||
#!/usr/bin/env ruby
|
||||
begin
|
||||
load File.expand_path('../spring', __FILE__)
|
||||
rescue LoadError => e
|
||||
raise unless e.message.include?('spring')
|
||||
end
|
||||
require_relative '../config/boot'
|
||||
require 'rake'
|
||||
Rake.application.run
|
||||
|
||||
@ -5,6 +5,11 @@
|
||||
# The application 'rspec' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
begin
|
||||
load File.expand_path('../spring', __FILE__)
|
||||
rescue LoadError => e
|
||||
raise unless e.message.include?('spring')
|
||||
end
|
||||
|
||||
require 'pathname'
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
# The application 'sass-convert' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'pathname'
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
|
||||
load Gem.bin_path('sass', 'sass-convert')
|
||||
23
bin/spring
23
bin/spring
@ -1,16 +1,17 @@
|
||||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
# The application 'spring' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
require 'pathname'
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
# This file loads Spring without using Bundler, in order to be fast.
|
||||
# It gets overwritten when you run the `spring binstub` command.
|
||||
|
||||
unless defined?(Spring)
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
require 'bundler'
|
||||
|
||||
load Gem.bin_path('spring', 'spring')
|
||||
lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
|
||||
spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
|
||||
if spring
|
||||
Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
|
||||
gem 'spring', spring.version
|
||||
require 'spring/binstub'
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,6 +2,9 @@ require File.expand_path('../boot', __FILE__)
|
||||
|
||||
require 'rails/all'
|
||||
|
||||
# todo unsilence deprecation warnings. Silenced for factory_girl
|
||||
ActiveSupport::Deprecation.silenced = true
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
set :application, "thirteen_tien_len_#{fetch(:stage)}"
|
||||
set :repo_url, 'git@bitbucket.org:jessecfisher/thirteen-tien-len.git'
|
||||
set :repo_url, 'git@git.chefzeppelin.com:jesse/thirteen-tien-len.git'
|
||||
|
||||
# If you want to import assets, you can change default asset dir (default = system)
|
||||
# This directory must be in your shared directory on the server
|
||||
@ -9,31 +9,44 @@ set :assets_dir, %w(public/assets public/system)
|
||||
#set :branch, proc { `git rev-parse --abbrev-ref stash`.chomp }
|
||||
#ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }
|
||||
|
||||
set :deploy_to, "/home/jesse/web/thirteen-tien-len_#{fetch(:stage)}"
|
||||
set :deploy_to, "/home/jesse/srv/thirteen-tien-len_#{fetch(:stage)}"
|
||||
# set :scm, :git
|
||||
|
||||
# set :format, :pretty
|
||||
# set :log_level, :debug
|
||||
# set :pty, true
|
||||
|
||||
set :linked_files, %w{config/database.yml .env}
|
||||
# set :linked_files, %w{config/database.yml .env}
|
||||
|
||||
append :linked_files, "puma.rb"
|
||||
# append :linked_files, "config/master.key"
|
||||
append :linked_files, "config/database.yml"
|
||||
append :linked_files, ".env"
|
||||
|
||||
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/lift-calculator}
|
||||
|
||||
set :rbenv_type, :user # or :system, depends on your rbenv setup
|
||||
set :rbenv_ruby, '2.3.0'
|
||||
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
|
||||
set :rbenv_type, :system # or :system, depends on your rbenv setup
|
||||
# set :rbenv_ruby, '2.6.0'
|
||||
set :rbenv_ruby, File.read('.ruby-version').strip
|
||||
set :rbenv_map_bins, %w{rake gem bundle ruby rails}
|
||||
append :rbenv_map_bins, 'puma', 'pumactl'
|
||||
set :rbenv_roles, :all # default value
|
||||
|
||||
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
|
||||
set :default_env, {
|
||||
'PATH' => 'PATH=/usr/local/rbenv/bin:./bin:$PATH:./bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/core_perl'
|
||||
}
|
||||
# set :keep_releases, 5
|
||||
|
||||
set :nginx_path, '/etc/nginx' # directory containing sites-available and sites-enabled
|
||||
set :nginx_template, 'config/deploy/nginx_conf.erb' # configuration template
|
||||
|
||||
set :rbenv_custom_path, "/usr/local/rbenv"
|
||||
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_custom_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_custom_path)}/bin/rbenv exec"
|
||||
# set :nginx_path, '/etc/nginx' # directory containing sites-available and sites-enabled
|
||||
# set :nginx_template, 'config/deploy/nginx_conf.erb' # configuration template
|
||||
#set :nginx_server_name, 'example.com' # optional, defaults to :application
|
||||
#set :nginx_upstream, 'example-app' # optional, defaults to :application
|
||||
set :nginx_listen, 80 # optional, default is not set
|
||||
set :nginx_roles, :all
|
||||
# set :nginx_listen, 80 # optional, default is not set
|
||||
# set :nginx_roles, :all
|
||||
|
||||
## postgresql
|
||||
set :pg_user, "thirteen_tien_len_#{fetch(:stage)}"
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
set :stage, :production
|
||||
|
||||
set :nginx_server_name, 'tienlen.ga' # optional, defaults to :application
|
||||
set :nginx_server_name, '13.24x7.hk' # optional, defaults to :application
|
||||
|
||||
# Simple Role Syntax
|
||||
# ==================
|
||||
# Supports bulk-adding hosts to roles, the primary
|
||||
# server in each group is considered to be the first
|
||||
# unless any hosts have the primary property set.
|
||||
role :app, %w{jesse@tienlen.ga}
|
||||
role :web, %w{jesse@tienlen.ga}
|
||||
role :db, %w{jesse@tienlen.ga}
|
||||
role :app, %w{jesse@13.24x7.hk}
|
||||
# Supports bulk-adding hosts to roles, the primary
|
||||
role :web, %w{jesse@13.24x7.hk}
|
||||
role :db, %w{jesse@13.24x7.hk}
|
||||
|
||||
# Extended Server Syntax
|
||||
# ======================
|
||||
@ -17,7 +17,7 @@ role :db, %w{jesse@tienlen.ga}
|
||||
# definition into the server list. The second argument
|
||||
# something that quacks like a hash can be used to set
|
||||
# extended properties on the server.
|
||||
server 'tienlen.ga', user: 'jesse', roles: %w{web app db}, my_property: :my_value
|
||||
server '13.24x7.hk', user: 'jesse', roles: %w{web app db}, my_property: :my_value
|
||||
|
||||
# you can set custom ssh options
|
||||
# it's possible to pass any option but you need to keep in mind that net/ssh understand limited list of options
|
||||
|
||||
@ -38,8 +38,8 @@ Rails.application.configure do
|
||||
password: Rails.application.secrets.email_provider_password
|
||||
}
|
||||
# ActionMailer Config
|
||||
config.action_mailer.default_url_options = { host: 'localhost:3000' }
|
||||
config.action_mailer.delivery_method = :smtp
|
||||
config.action_mailer.default_url_options = { host: 'grandpo.ohbah.com:3000' }
|
||||
config.action_mailer.delivery_method = :sendmail
|
||||
config.action_mailer.raise_delivery_errors = true
|
||||
# Send email in development mode?
|
||||
config.action_mailer.perform_deliveries = true
|
||||
@ -54,4 +54,5 @@ Rails.application.configure do
|
||||
|
||||
# Add Rack::LiveReload to the bottom of the middleware stack with the default options.
|
||||
config.middleware.insert_after ActionDispatch::Static, Rack::LiveReload
|
||||
BetterErrors::Middleware.allow_ip! '10.0.0.0/16'
|
||||
end
|
||||
|
||||
@ -22,7 +22,7 @@ Rails.application.configure do
|
||||
# config.action_dispatch.rack_cache = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this).
|
||||
config.serve_static_assets = false
|
||||
config.serve_static_assets = true
|
||||
|
||||
# Compress JavaScripts and CSS.
|
||||
config.assets.js_compressor = :uglifier
|
||||
@ -95,4 +95,7 @@ Rails.application.configure do
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
|
||||
# config.relative_url_root = "/13"
|
||||
# config.action_controller.relative_url_root = '/13'
|
||||
end
|
||||
|
||||
@ -5,7 +5,7 @@ Rails.application.configure do
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
config.cache_classes = true
|
||||
config.cache_classes = false
|
||||
|
||||
# Do not eager load code on boot. This avoids loading your whole application
|
||||
# just for the purpose of running a single test. If you are using a tool that
|
||||
|
||||
@ -6,3 +6,4 @@ Rails.application.config.assets.version = '1.0'
|
||||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
|
||||
# Rails.application.config.assets.precompile += %w( search.js )
|
||||
Rails.application.config.assets.precompile += %w( table-loader.js )
|
||||
|
||||
@ -8,8 +8,8 @@ module DevisePermittedParameters
|
||||
protected
|
||||
|
||||
def configure_permitted_parameters
|
||||
devise_parameter_sanitizer.for(:sign_up) << :name
|
||||
devise_parameter_sanitizer.for(:account_update) << :name
|
||||
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
|
||||
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
# config/initializers/upmin.rb
|
||||
# Extends the Upmin ApplicationController to limit access to users with an admin role.
|
||||
# Depends on Devise for authentication plus role-based authorization.
|
||||
# Be sure to restart your server when you modify this file.
|
||||
module AdminOnly
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
before_action :authenticate_user!
|
||||
before_action :admin_only
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def admin_only
|
||||
unless current_user.admin?
|
||||
redirect_to :back, alert: 'Access denied.'
|
||||
end
|
||||
rescue ActionController::RedirectBackError
|
||||
redirect_to '/', alert: 'Access denied.'
|
||||
end
|
||||
end
|
||||
|
||||
Upmin::ApplicationController.send :include, AdminOnly
|
||||
66
config/nginx/13.whitewizardweb.com.conf
Normal file
66
config/nginx/13.whitewizardweb.com.conf
Normal file
@ -0,0 +1,66 @@
|
||||
upstream thirteen_production {
|
||||
server unix:///home/jesse/srv/thirteen-tien-len_production/shared/tmp/sockets/puma.sock fail_timeout=0;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name 13.whitewizardweb.com 13.24x7.hk 13.mounthoodlodge.com 13.my.to;
|
||||
root /home/jesse/srv/thirteen-tien-len_production/current/public;
|
||||
access_log /home/jesse/srv/thirteen-tien-len_production/shared/log/nginx.access.log;
|
||||
|
||||
try_files $uri @app;
|
||||
|
||||
location @app {
|
||||
proxy_pass http://thirteen_production;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto https;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_redirect off;
|
||||
proxy_next_upstream error timeout invalid_header http_502;
|
||||
|
||||
proxy_connect_timeout 600;
|
||||
proxy_send_timeout 600;
|
||||
proxy_read_timeout 600;
|
||||
send_timeout 600;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
# listen 443 ssl; # managed by Certbot
|
||||
# ssl_certificate /etc/letsencrypt/live/13dev.quaff.top/fullchain.pem; # managed by Certbot
|
||||
# ssl_certificate_key /etc/letsencrypt/live/13dev.quaff.top/privkey.pem; # managed by Certbot
|
||||
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||
|
||||
|
||||
listen 443 ssl; # managed by Certbot
|
||||
ssl_certificate /etc/letsencrypt/live/13.24x7.hk/fullchain.pem; # managed by Certbot
|
||||
ssl_certificate_key /etc/letsencrypt/live/13.24x7.hk/privkey.pem; # managed by Certbot
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||
|
||||
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name 13.whitewizardweb.com;
|
||||
return 301 https://13.whitewizardweb.com$request_uri;
|
||||
}
|
||||
|
||||
|
||||
server {
|
||||
if ($host = 13.24x7.hk) {
|
||||
return 301 https://$host$request_uri;
|
||||
} # managed by Certbot
|
||||
|
||||
|
||||
listen 80;
|
||||
server_name 13.whitewizardweb.com 13.24x7.hk 13.mounthoodlodge.com 13.my.to;
|
||||
return 404; # managed by Certbot
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
upstream 13dev {
|
||||
server localhost:9012;
|
||||
server localhost:9913;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name 13dev.quaff.top;
|
||||
server_name 13dev.owlwphant.icu;
|
||||
root /home/jesse/web/thirteen-tien-len/public;
|
||||
access_log /home/jesse/web/thirteen-tien-len/log/nginx.log;
|
||||
|
||||
@ -27,11 +27,11 @@ server {
|
||||
|
||||
|
||||
|
||||
listen 443 ssl; # managed by Certbot
|
||||
ssl_certificate /etc/letsencrypt/live/13dev.quaff.top/fullchain.pem; # managed by Certbot
|
||||
ssl_certificate_key /etc/letsencrypt/live/13dev.quaff.top/privkey.pem; # managed by Certbot
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||
# listen 443 ssl; # managed by Certbot
|
||||
# ssl_certificate /etc/letsencrypt/live/13dev.quaff.top/fullchain.pem; # managed by Certbot
|
||||
# ssl_certificate_key /etc/letsencrypt/live/13dev.quaff.top/privkey.pem; # managed by Certbot
|
||||
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||
|
||||
}
|
||||
|
||||
@ -1,13 +1,32 @@
|
||||
Rails.application.routes.draw do
|
||||
resources :players
|
||||
resources :tables do
|
||||
member do
|
||||
post 'new_game'
|
||||
post 'end_game'
|
||||
end
|
||||
resources :seats do
|
||||
member do
|
||||
patch 'sit'
|
||||
patch 'stand'
|
||||
end
|
||||
end
|
||||
resources :games
|
||||
resources :games do
|
||||
# member do
|
||||
# post :join
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
resources :seats do
|
||||
member do
|
||||
post 'sit'
|
||||
post 'stand'
|
||||
post 'add_bot'
|
||||
post 'remove_bot'
|
||||
post 'empty'
|
||||
post 'remove_player'
|
||||
end
|
||||
end
|
||||
|
||||
resources :games do
|
||||
@ -15,7 +34,7 @@ Rails.application.routes.draw do
|
||||
get 'my-inventory'
|
||||
post 'start'
|
||||
post 'join'
|
||||
patch 'play_hand'
|
||||
post 'play_hand'
|
||||
end
|
||||
resources :seats do
|
||||
member do
|
||||
@ -25,9 +44,9 @@ Rails.application.routes.draw do
|
||||
end
|
||||
end
|
||||
|
||||
mount Upmin::Engine => '/admin'
|
||||
root to: 'visitors#index'
|
||||
get '/play-now', to: 'games#play_now', as: 'play_now'
|
||||
get '/play-now', to: 'tables#play_now', as: 'play_now'
|
||||
get '/tutorial', to: 'tables#tutorial', as: 'tutorial'
|
||||
devise_for :users, controllers: { registrations: "users/registrations" }
|
||||
resources :users
|
||||
get '/loaderio-456644f4db1fcd1e8578be882d2fc476.txt', to: redirect('/assets/loaderio-456644f4db1fcd1e8578be882d2fc476.txt')
|
||||
|
||||
@ -12,12 +12,12 @@
|
||||
|
||||
development:
|
||||
admin_name: Wizard of Hearts
|
||||
admin_email: jesse@quaff.top
|
||||
admin_email: jesse@chefzeppelin.com
|
||||
admin_password: changeme
|
||||
admin_soft_token: SeedToken
|
||||
email_provider_username: <%= ENV["GMAIL_USERNAME"] %>
|
||||
email_provider_password: <%= ENV["GMAIL_PASSWORD"] %>
|
||||
domain_name: 13dev.quaff.top
|
||||
domain_name: localhost
|
||||
secret_key_base: 31b41a9c65cd195a147284c28603ad690792213a13157935f4de1fb232ce3283a44ec52f4d5e9a3c0df041e4b19536d739246616d26d147081dc1c906288771d
|
||||
|
||||
test:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class DeviseCreateUsers < ActiveRecord::Migration
|
||||
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table(:users) do |t|
|
||||
## Database authenticatable
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddNameToUsers < ActiveRecord::Migration
|
||||
class AddNameToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :name, :string
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddConfirmableToUsers < ActiveRecord::Migration
|
||||
class AddConfirmableToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :confirmation_token, :string
|
||||
add_column :users, :confirmed_at, :datetime
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddRoleToUsers < ActiveRecord::Migration
|
||||
class AddRoleToUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :role, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class DeviseInvitableAddToUsers < ActiveRecord::Migration
|
||||
class DeviseInvitableAddToUsers < ActiveRecord::Migration[5.2]
|
||||
def up
|
||||
change_table :users do |t|
|
||||
t.string :invitation_token
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreateGames < ActiveRecord::Migration
|
||||
class CreateGames < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :games do |t|
|
||||
t.string :title
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreatePlayers < ActiveRecord::Migration
|
||||
class CreatePlayers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :players do |t|
|
||||
t.references :game, index: true
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreatePlayerCards < ActiveRecord::Migration
|
||||
class CreatePlayerCards < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :player_cards do |t|
|
||||
t.references :player, index: true
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddStatusToGames < ActiveRecord::Migration
|
||||
class AddStatusToGames < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :games, :status, :string
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddAttrsToPlayerCards < ActiveRecord::Migration
|
||||
class AddAttrsToPlayerCards < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :player_cards, :value, :integer
|
||||
add_column :player_cards, :rank, :string
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddControlPlayerIdToGame < ActiveRecord::Migration
|
||||
class AddControlPlayerIdToGame < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :games, :control_player_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreatePlays < ActiveRecord::Migration
|
||||
class CreatePlays < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :plays do |t|
|
||||
t.references :game, index: true
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddPlayIdToPlayerCard < ActiveRecord::Migration
|
||||
class AddPlayIdToPlayerCard < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :player_cards, :play_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddPlayToBeatToGame < ActiveRecord::Migration
|
||||
class AddPlayToBeatToGame < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_reference :games, :play_to_beat, index: true
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class PlayToBeat < ActiveRecord::Migration
|
||||
class PlayToBeat < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :play_to_beats do |t|
|
||||
t.integer :game_id
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddWinnerPlayerIdToGame < ActiveRecord::Migration
|
||||
class AddWinnerPlayerIdToGame < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :games, :winner_player_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class RenameControlPlayerIdToControllingPlayerId < ActiveRecord::Migration
|
||||
class RenameControlPlayerIdToControllingPlayerId < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
rename_column :games, :control_player_id, :controlling_player_id
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreateTables < ActiveRecord::Migration
|
||||
class CreateTables < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :tables do |t|
|
||||
t.string :title
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class CreateSeats < ActiveRecord::Migration
|
||||
class CreateSeats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :seats do |t|
|
||||
t.references :table, index: true
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddCurrentGameIdToTable < ActiveRecord::Migration
|
||||
class AddCurrentGameIdToTable < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :tables, :current_game_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddTableIdToGames < ActiveRecord::Migration
|
||||
class AddTableIdToGames < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :games, :table_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddSoftTokenToUsersAndPlayers < ActiveRecord::Migration
|
||||
class AddSoftTokenToUsersAndPlayers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :soft_token, :string
|
||||
add_column :players, :soft_token, :string
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddPositionToSeats < ActiveRecord::Migration
|
||||
class AddPositionToSeats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :seats, :position, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddUserSoftTokenToSeats < ActiveRecord::Migration
|
||||
class AddUserSoftTokenToSeats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :seats, :user_soft_token, :string
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddGameIdToSeats < ActiveRecord::Migration
|
||||
class AddGameIdToSeats < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :seats, :game_id, :integer
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
class AddPlayerIdToSeat < ActiveRecord::Migration
|
||||
class AddPlayerIdToSeat < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :seats, :player_id, :integer
|
||||
end
|
||||
|
||||
5
db/migrate/20191024023437_add_win_count_to_user.rb
Normal file
5
db/migrate/20191024023437_add_win_count_to_user.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddWinCountToUser < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :users, :win_count, :integer, default: 0
|
||||
end
|
||||
end
|
||||
5
db/migrate/20211108045859_add_is_bot_to_player.rb
Normal file
5
db/migrate/20211108045859_add_is_bot_to_player.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddIsBotToPlayer < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :players, :is_bot, :boolean, default: false
|
||||
end
|
||||
end
|
||||
55
db/schema.rb
55
db/schema.rb
@ -1,4 +1,3 @@
|
||||
# encoding: UTF-8
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
@ -11,12 +10,12 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160222131306) do
|
||||
ActiveRecord::Schema.define(version: 2021_11_08_045859) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "games", force: true do |t|
|
||||
create_table "games", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
@ -25,18 +24,17 @@ ActiveRecord::Schema.define(version: 20160222131306) do
|
||||
t.integer "play_to_beat_id"
|
||||
t.integer "winner_player_id"
|
||||
t.integer "table_id"
|
||||
t.index ["play_to_beat_id"], name: "index_games_on_play_to_beat_id"
|
||||
end
|
||||
|
||||
add_index "games", ["play_to_beat_id"], name: "index_games_on_play_to_beat_id", using: :btree
|
||||
|
||||
create_table "play_to_beats", force: true do |t|
|
||||
create_table "play_to_beats", force: :cascade do |t|
|
||||
t.integer "game_id"
|
||||
t.integer "play_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "player_cards", force: true do |t|
|
||||
create_table "player_cards", force: :cascade do |t|
|
||||
t.integer "player_id"
|
||||
t.integer "card_id"
|
||||
t.datetime "created_at"
|
||||
@ -45,33 +43,31 @@ ActiveRecord::Schema.define(version: 20160222131306) do
|
||||
t.string "rank"
|
||||
t.string "suit"
|
||||
t.integer "play_id"
|
||||
t.index ["card_id"], name: "index_player_cards_on_card_id"
|
||||
t.index ["player_id"], name: "index_player_cards_on_player_id"
|
||||
end
|
||||
|
||||
add_index "player_cards", ["card_id"], name: "index_player_cards_on_card_id", using: :btree
|
||||
add_index "player_cards", ["player_id"], name: "index_player_cards_on_player_id", using: :btree
|
||||
|
||||
create_table "players", force: true do |t|
|
||||
create_table "players", force: :cascade do |t|
|
||||
t.integer "game_id"
|
||||
t.integer "user_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "soft_token"
|
||||
t.boolean "is_bot", default: false
|
||||
t.index ["game_id"], name: "index_players_on_game_id"
|
||||
t.index ["user_id"], name: "index_players_on_user_id"
|
||||
end
|
||||
|
||||
add_index "players", ["game_id"], name: "index_players_on_game_id", using: :btree
|
||||
add_index "players", ["user_id"], name: "index_players_on_user_id", using: :btree
|
||||
|
||||
create_table "plays", force: true do |t|
|
||||
create_table "plays", force: :cascade do |t|
|
||||
t.integer "game_id"
|
||||
t.integer "player_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.index ["game_id"], name: "index_plays_on_game_id"
|
||||
t.index ["player_id"], name: "index_plays_on_player_id"
|
||||
end
|
||||
|
||||
add_index "plays", ["game_id"], name: "index_plays_on_game_id", using: :btree
|
||||
add_index "plays", ["player_id"], name: "index_plays_on_player_id", using: :btree
|
||||
|
||||
create_table "seats", force: true do |t|
|
||||
create_table "seats", force: :cascade do |t|
|
||||
t.integer "table_id"
|
||||
t.integer "user_id"
|
||||
t.datetime "created_at"
|
||||
@ -80,19 +76,18 @@ ActiveRecord::Schema.define(version: 20160222131306) do
|
||||
t.string "user_soft_token"
|
||||
t.integer "game_id"
|
||||
t.integer "player_id"
|
||||
t.index ["table_id"], name: "index_seats_on_table_id"
|
||||
t.index ["user_id"], name: "index_seats_on_user_id"
|
||||
end
|
||||
|
||||
add_index "seats", ["table_id"], name: "index_seats_on_table_id", using: :btree
|
||||
add_index "seats", ["user_id"], name: "index_seats_on_user_id", using: :btree
|
||||
|
||||
create_table "tables", force: true do |t|
|
||||
create_table "tables", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "current_game_id"
|
||||
end
|
||||
|
||||
create_table "users", force: true do |t|
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: ""
|
||||
t.string "reset_password_token"
|
||||
@ -120,12 +115,12 @@ ActiveRecord::Schema.define(version: 20160222131306) do
|
||||
t.string "invited_by_type"
|
||||
t.integer "invitations_count", default: 0
|
||||
t.string "soft_token"
|
||||
t.integer "win_count", default: 0
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["invitation_token"], name: "index_users_on_invitation_token", unique: true
|
||||
t.index ["invitations_count"], name: "index_users_on_invitations_count"
|
||||
t.index ["invited_by_id"], name: "index_users_on_invited_by_id"
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||
add_index "users", ["invitation_token"], name: "index_users_on_invitation_token", unique: true, using: :btree
|
||||
add_index "users", ["invitations_count"], name: "index_users_on_invitations_count", using: :btree
|
||||
add_index "users", ["invited_by_id"], name: "index_users_on_invited_by_id", using: :btree
|
||||
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
|
||||
|
||||
end
|
||||
|
||||
@ -2,11 +2,31 @@
|
||||
# As a user
|
||||
# I want to add a bot to a table
|
||||
# So I can play against the computer
|
||||
feature 'Add bot', type: :feature, js: true do
|
||||
feature 'Add bot', type: :feature do
|
||||
before(:each) do
|
||||
@table = FactoryGirl.create :table
|
||||
visit table_path @table
|
||||
end
|
||||
# Scenario: User can add a bot if there is room at the table
|
||||
# Given I can edit the table
|
||||
# When I see the table with an empty seat
|
||||
# Then I see a button to add a bot
|
||||
scenario 'visitor can add a bot if the seat is empty' do
|
||||
@button = page.find_button('+ Bot', match: :first).click
|
||||
expect(page).to have_content "BotPlayer"
|
||||
|
||||
end
|
||||
|
||||
scenario 'visitor can not add a bot if the seat is occupied by bot' do
|
||||
@button = page.find_button('+ Bot', match: :first).click
|
||||
page.assert_selector('button', text: '+ Bot', count: 3)
|
||||
end
|
||||
|
||||
scenario 'visitor can not add a bot if the seat is occupied by visitor' do
|
||||
@button = page.find_button('Sit', match: :first).click
|
||||
page.assert_selector('button', text: '+ Bot', count: 3)
|
||||
end
|
||||
|
||||
scenario 'user can add a bot if the table is not full' do
|
||||
skip "To be implemented"
|
||||
#signin('test@example.com', 'please123')
|
||||
|
||||
35
spec/features/bots/bot_play_spec.rb
Normal file
35
spec/features/bots/bot_play_spec.rb
Normal file
@ -0,0 +1,35 @@
|
||||
# Feature: Bot takes turns
|
||||
# As a player
|
||||
# I want bots to take turns
|
||||
# So I can play against the computer
|
||||
feature 'Bot takes turn', type: :feature do
|
||||
before(:each) do
|
||||
@table = FactoryGirl.create :table
|
||||
@game = @table.current_game
|
||||
visit table_path @table
|
||||
end
|
||||
|
||||
scenario 'bot player passes' do
|
||||
@button = page.find_button('+ Bot', match: :first).click
|
||||
expect(page).to have_content "BotPlayer"
|
||||
@button = page.find_button('Sit', match: :first).click
|
||||
click_button "Start"
|
||||
click_button 'Pass'
|
||||
expect(page).to have_content "Bot is passes"
|
||||
end
|
||||
|
||||
scenario 'bot player plays single' do
|
||||
@button = page.find_button('+ Bot', match: :first).click
|
||||
expect(page).to have_content "BotPlayer"
|
||||
@button = page.find_button('Sit', match: :first).click
|
||||
click_button "Start"
|
||||
@game = @table.current_game
|
||||
if @game.controlling_player.soft_token == page.current_user.soft_token
|
||||
@card_to_play = @game.controlling_player.inventory.first
|
||||
find("[data-card-name='#{@card_to_play.to_s}']").click
|
||||
click_button 'Play Hand'
|
||||
end
|
||||
expect(@game.play_to_beat.player.is_bot?).to eq true
|
||||
expect(@game.play_to_beat.hand_type).to eq "single"
|
||||
end
|
||||
end
|
||||
22
spec/features/bots/remove_bot_players_spec.rb
Normal file
22
spec/features/bots/remove_bot_players_spec.rb
Normal file
@ -0,0 +1,22 @@
|
||||
# Feature: Remove bot from seat
|
||||
# As a user
|
||||
# I want to remove a bot from a sea
|
||||
feature 'Remove bot', type: :feature do
|
||||
before(:each) do
|
||||
@table = FactoryGirl.create :table
|
||||
visit table_path @table
|
||||
end
|
||||
# Scenario: Visitor can remove a bot from seat
|
||||
# Given I can edit the table
|
||||
# When I see the seat with a bot
|
||||
# Then I see a button to remove a bot
|
||||
scenario 'visitor can remove a bot from a seat' do
|
||||
@button = page.find_button('+ Bot', match: :first).click
|
||||
page.assert_selector('button', text: '+ Bot', count: 3)
|
||||
expect(page).to have_content "BotPlayer"
|
||||
@button = page.find_button('- Bot', match: :first).click
|
||||
expect(page).to have_content "Removed Bot"
|
||||
page.assert_selector('button', text: '+ Bot', count: 4)
|
||||
end
|
||||
|
||||
end
|
||||
@ -1,18 +1,16 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.feature "EndOfGames", type: :feature, js: true do
|
||||
RSpec.feature "EndOfGames", type: :feature do
|
||||
# Given I am in a started game
|
||||
before(:each) do
|
||||
before(:all) do
|
||||
# If test is unable to click correct card, use wider window
|
||||
# page.driver.browser.manage.window.resize_to(1640, 1090)
|
||||
@game = setup_game
|
||||
@game.reload
|
||||
@player = @game.controlling_player
|
||||
signin(@player.user.email,'password')
|
||||
visit table_path @game.table
|
||||
end
|
||||
# And it is my turn
|
||||
# And I play my last cards
|
||||
# Then I win the game
|
||||
scenario 'I win the game' do
|
||||
|
||||
# Play lowest card
|
||||
# Other players always pass
|
||||
# Play next lowest card
|
||||
@ -39,14 +37,39 @@ RSpec.feature "EndOfGames", type: :feature, js: true do
|
||||
@game.reload
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# And it is my turn
|
||||
# And I play my last cards
|
||||
# Then I win the game
|
||||
scenario 'I win the game' do
|
||||
# After I play my last card(s)
|
||||
# Expect that I am the winner
|
||||
@game.reload
|
||||
expect(@game.winner).to eq @player
|
||||
click_button "New Game"
|
||||
expect(page).to have_content "Game started"
|
||||
end
|
||||
|
||||
scenario 'I start a new game at the same table' do
|
||||
click_button "New Game"
|
||||
expect(page).to have_content "Game started"
|
||||
end
|
||||
|
||||
describe 'I lose the game' do
|
||||
pending
|
||||
# Another player plays their last card(s)
|
||||
# Expect that they are the winner
|
||||
end
|
||||
|
||||
describe 'I win 2nd place' do
|
||||
pending
|
||||
# Another player plays their last card(s)
|
||||
# Expect that they are the winner
|
||||
end
|
||||
|
||||
describe 'Play to beat clears appropriately' do
|
||||
pending
|
||||
# Another player plays their last card(s)
|
||||
# Expect that they are the winner
|
||||
end
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# As a visitor
|
||||
# I want to quickly join a game
|
||||
# So I can play
|
||||
feature 'Play now', :devise, js: true do
|
||||
feature 'Play now', :devise do
|
||||
# Scenario: Visitor can play now
|
||||
# Given I am not signed in
|
||||
# When I click Play Now
|
||||
@ -16,6 +16,7 @@ feature 'Play now', :devise, js: true do
|
||||
end
|
||||
it 'creates and joins a new game' do
|
||||
#TODO: Fix race condition
|
||||
sleep 2
|
||||
expect(page).to have_content "Hand to beat"
|
||||
#Game title derived from visitor soft_token
|
||||
expect(page).to have_content "#{Game.last.players.first.soft_token[0..4]}"
|
||||
@ -26,25 +27,30 @@ feature 'Play now', :devise, js: true do
|
||||
|
||||
context 'visitor joins an existing game' do
|
||||
before do
|
||||
FactoryGirl.create :game
|
||||
@game = Game.last
|
||||
FactoryGirl.create :table
|
||||
@table = Table.last
|
||||
visit root_path
|
||||
expect(Game.all.count).to eq 1
|
||||
# expect(Game.all.count).to eq 1
|
||||
click_link 'Play Now'
|
||||
end
|
||||
|
||||
it 'shows and starts the game' do
|
||||
#TODO: Deprecated it shows the game title
|
||||
#expect(page).to have_content "Test Game"
|
||||
expect(page).to have_content "Hand to beat"
|
||||
# expect(page).to have_content "Hand to beat"
|
||||
# TODO fix race condition
|
||||
sleep 8
|
||||
#it 'is located at the correct url' do
|
||||
expect(current_path).to eq game_path(@game)
|
||||
expect(page).to have_current_path(table_path(@table))
|
||||
expect(page).to have_content "Guest"
|
||||
expect(current_path).to eq table_path(@table)
|
||||
|
||||
#it 'shows the visitor as a player' do
|
||||
@game = Game.last
|
||||
@player = @game.players.last
|
||||
@playerComponent = page.find("#player-1")
|
||||
@playerComponent = page.find_all(".seat").first
|
||||
#TODO: have_content @player.display_name
|
||||
expect(@playerComponent.text).to have_content("Guest#{@player.soft_token[0..5]}")
|
||||
expect(@playerComponent).to have_content("Guest#{@player.soft_token[0..4]}")
|
||||
|
||||
#it 'shows other players' do
|
||||
# Add another player
|
||||
@ -61,8 +67,7 @@ feature 'Play now', :devise, js: true do
|
||||
visit current_path
|
||||
visit current_path
|
||||
visit current_path
|
||||
expect(page).to have_content 'Inventory'
|
||||
expect(Game.all.count).to eq 1
|
||||
expect(page).to have_content 'Hand to beat'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,13 +2,13 @@ require 'rails_helper'
|
||||
include Warden::Test::Helpers
|
||||
Warden.test_mode!
|
||||
|
||||
feature 'Play a hand', type: :feature, js: true do
|
||||
feature 'Play a hand', type: :feature do
|
||||
before(:each) do
|
||||
@game = setup_game
|
||||
@game.reload
|
||||
@player = @game.controlling_player
|
||||
signin(@player.user.email,'password')
|
||||
visit game_path @game
|
||||
visit table_path @game.table
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
@ -32,13 +32,12 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# Play the highest card
|
||||
@card_to_play = @player.inventory.last
|
||||
find_card(@card_to_play).click
|
||||
#click_button 'Play Hand'
|
||||
click_button "play_hand_button_#{@player.id}"
|
||||
click_button 'Play Hand'
|
||||
|
||||
# No play to beat, because play was invalid
|
||||
expect(@game.play_to_beat).to eq(nil)
|
||||
# TODO: This scenario is causing other scenarios to fail unless we slow down here
|
||||
sleep 1
|
||||
# sleep 1
|
||||
# TODO: Flash messages
|
||||
#expect(page).to have_content "First hand must contain the lowest card: #{@game.lowest_card.to_s}"
|
||||
end
|
||||
@ -49,9 +48,10 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# Then I see the hand to beat is this play
|
||||
scenario 'first play contains lowest card' do
|
||||
@card_to_play = @game.lowest_card
|
||||
# If test can't click card enable js and click coordinates
|
||||
# find_card(@card_to_play).click(x: 0, y: 0)
|
||||
find_card(@card_to_play).click
|
||||
#click_button 'Play Hand'
|
||||
click_button "play_hand_button_#{@player.id}"
|
||||
click_button 'Play Hand'
|
||||
expect(cards_to_beat).to eq @game.lowest_card.to_s
|
||||
end
|
||||
|
||||
@ -63,6 +63,7 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# Store initial state of players inventory
|
||||
@player_inventory = @player.inventory.join(' ')
|
||||
@card_to_play = @player.inventory.first
|
||||
expect(page).to have_css("#inventory [data-card-name='#{@card_to_play.to_s}']")
|
||||
find_card(@card_to_play).click
|
||||
click_button 'Play Hand'
|
||||
#wait_for_ajax
|
||||
@ -70,8 +71,7 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# Played hand is rendered
|
||||
expect(cards_to_beat).to eq @game.lowest_card.to_s
|
||||
# Player inventory is rendered without played cards
|
||||
#TODO: Deprecated have_content for inventory. Write new expectation.
|
||||
expect(page.find("#player_controls_#{@player.id}")).to_not have_content(@card_to_play.to_s)
|
||||
expect(page).not_to have_css("#inventory [data-card-name='#{@card_to_play.to_s}']")
|
||||
end
|
||||
|
||||
# Scenario: Invalid cards do not leave the players inventory
|
||||
@ -89,16 +89,15 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
@cards_to_play << @player.inventory.first
|
||||
|
||||
# Select each card to play
|
||||
@cards_to_play.map {|card| find("[data-card-name='#{card.to_s}'] ~ img").click }
|
||||
#click_button 'Play Hand'
|
||||
click_button "play_hand_button_#{@player.id}"
|
||||
@cards_to_play.map {|card| find("[data-card-name='#{card.to_s}']").click }
|
||||
click_button 'Play Hand'
|
||||
|
||||
# Played hand is rendered
|
||||
# TODO: Flash messages
|
||||
#expect(page).to have_content("Invalid pair")
|
||||
expect(page).to have_content("Invalid pair")
|
||||
# Player inventory is rendered with played cards
|
||||
@initial_player_inventory.each do |card|
|
||||
expect(page).to have_selector("[data-card-name='#{card.to_s}'] ~ img")
|
||||
expect(page).to have_css("#inventory input[data-card-name='#{card.to_s}']")
|
||||
end
|
||||
# TODO: This scenario is causing other scenarios to fail unless we slow down here
|
||||
sleep 1
|
||||
@ -123,7 +122,7 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
click_button 'Play Hand'
|
||||
expect(page).to have_content "Hand to beat"
|
||||
expect(cards_to_beat).to eq @card_to_play.to_s
|
||||
expect(page).to have_selector("#player-#{@next_player_id}.has-control")
|
||||
expect(page).to have_selector("#player-#{@next_player_id}.taking-turn")
|
||||
end
|
||||
|
||||
# Scenario: Player can not play an invalid hand on their turn
|
||||
@ -134,17 +133,16 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
#@game.reload
|
||||
@cards_to_play = [@game.controlling_player.player_cards.order(:value).first.to_s, @game.controlling_player.player_cards.order(:value).last.to_s]
|
||||
@cards_to_play.each do |card|
|
||||
find("[data-card-name='#{card.to_s}'] ~ img").click
|
||||
find("[data-card-name='#{card.to_s}']").click
|
||||
end
|
||||
#click_button 'Play Hand'
|
||||
click_button "play_hand_button_#{@player.id}"
|
||||
click_button 'Play Hand'
|
||||
# controlling_player plays an invalid hand
|
||||
# expect invalid hand message
|
||||
#:TODO: Flash messages
|
||||
#expect(page).to have_content("Invalid pair.")
|
||||
# expect inventory to remain unchanged
|
||||
@game.controlling_player.inventory.each do |card|
|
||||
expect(page).to have_selector("[data-card-name='#{card.to_s}'] ~ img")
|
||||
expect(page).to have_selector("[data-card-name='#{card.to_s}']")
|
||||
end
|
||||
# TODO: This scenario is causing other scenarios to fail unless we slow down here
|
||||
sleep 1
|
||||
@ -161,26 +159,28 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
@non_controlling_player = @game.players.where.not(id: @game.controlling_player_id).first
|
||||
login_as(@non_controlling_player.user, scope: :user)
|
||||
visit game_path @game
|
||||
#expect(page).to_not have_button 'Play Hand'
|
||||
elem = page.find "input#play_hand_button_#{@non_controlling_player.id}"
|
||||
expect(elem.disabled?).to be true
|
||||
# TODO: Submit a POST request
|
||||
expect(page).to_not have_button 'Play Hand'
|
||||
# click_button 'Play Hand'
|
||||
# expect(page).to have_content "not your turn"
|
||||
end
|
||||
|
||||
# Scenario: Player can pass when it is their turn
|
||||
# Given I am the active player
|
||||
# When I pass
|
||||
# Then I see an successful pass message
|
||||
# scenario 'active player can pass', js: true do
|
||||
scenario 'active player can pass' do
|
||||
@current_user = @game.controlling_player
|
||||
#click_button 'Pass'
|
||||
click_button "pass_hand_button_#{@player.id}"
|
||||
# accept_confirm do
|
||||
click_button 'Pass'
|
||||
# end
|
||||
# click_button "pass_hand_button_#{@player.id}"
|
||||
## TODO: Flash messages
|
||||
#expect(page).to have_content 'Successfully passed.'
|
||||
expect(page).to have_content 'Successfully passed.'
|
||||
# Expect active player should rotate
|
||||
# expect(page).to_not have_button 'Play Hand'
|
||||
elem = page.find "input#play_hand_button_#{@player.id}"
|
||||
expect(elem.disabled?).to be false
|
||||
# elem = page.find "input#play_hand_button_#{@player.id}"
|
||||
# expect(elem.disabled?).to be false
|
||||
|
||||
@new_controlling_player = @game.controlling_player
|
||||
expect(@game.controlling_player).to_not eq(@controlling_player)
|
||||
@ -197,9 +197,9 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
@game.reload
|
||||
@player = @game.controlling_player
|
||||
@card_to_play = @player.inventory.first
|
||||
find("[data-card-name='#{@card_to_play.to_s}'] ~ img").click
|
||||
#click_button 'Play Hand'
|
||||
click_button "play_hand_button_#{@player.id}"
|
||||
find("[data-card-name='#{@card_to_play.to_s}']").click
|
||||
click_button 'Play Hand'
|
||||
# click_button "play_hand_button_#{@player.id}"
|
||||
|
||||
#TODO: Fix race condition
|
||||
sleep 4
|
||||
@ -212,13 +212,11 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
@game.controlling_player_id = @player.id
|
||||
@game.save
|
||||
@game.reload
|
||||
visit game_path @game
|
||||
visit table_path @game.table
|
||||
|
||||
# Expect active player should rotate
|
||||
#expect(page).to have_button 'Play Hand'
|
||||
expect(page).to have_button "play_hand_button_#{@player.id}"
|
||||
#expect(@game.player_to_beat).to eq(@game.controlling_player)
|
||||
expect(page).to have_content 'Hand to beat: None'
|
||||
expect(page).to have_button 'Play Hand'
|
||||
expect(@game.player_to_beat).to eq(@game.controlling_player)
|
||||
expect(page).to have_content "Hand to beat:\nNone"
|
||||
end
|
||||
|
||||
# Scenario: Player wins the game
|
||||
@ -227,10 +225,13 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
# And I am the first player to do so
|
||||
# Then I see a 1st place winner message
|
||||
scenario 'first place winner' do
|
||||
@card_to_play = @player.inventory.first
|
||||
@player.inventory[1..12].map{|card| card.destroy}
|
||||
# play last card
|
||||
pending "TBD"
|
||||
find_card(@card_to_play).click
|
||||
click_button 'Play Hand'
|
||||
expect(@player.inventory.count).to eq 0
|
||||
expect(page).to have_content "Winner: #{@player.display_name}"
|
||||
expect(page).to have_content "Player #{@player.display_name} wins!"
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# As a visitor
|
||||
# I want to sit in a seat
|
||||
# So I can be at a table and play a game
|
||||
feature 'Seats', :devise, js: true do
|
||||
feature 'Seats', :devise do
|
||||
context "As a visitor" do
|
||||
before(:each) do
|
||||
@table = FactoryGirl.create :table
|
||||
@ -15,43 +15,45 @@ feature 'Seats', :devise, js: true do
|
||||
end
|
||||
|
||||
it 'sit button is disabled for unavailable seats' do
|
||||
@sit_buttons = page.find_all('button', text: 'Sit')
|
||||
expect(@sit_buttons.length).to eq 4
|
||||
@button = page.find_button('Sit', match: :first)
|
||||
@button.click
|
||||
expect(page).to have_content "Guest"
|
||||
expect(@button.disabled?).to eq true
|
||||
@sit_buttons = page.find_all('button', text: 'Sit')
|
||||
expect(@sit_buttons.length).to eq 3
|
||||
end
|
||||
|
||||
it 'has a stand button if current user is seated' do
|
||||
@button = page.find_button('Sit', match: :first)
|
||||
@button.click
|
||||
expect(page).to have_content "Guest"
|
||||
@buttons = page.find_all('button', text: 'Stand')
|
||||
@buttons = page.find_all('button', text: 'Leave')
|
||||
expect(@buttons.length).to eq 1
|
||||
end
|
||||
|
||||
scenario 'table seats match up with game seats' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.find(:css, ".game-seat.position-1")).to have_content "Guest"
|
||||
expect(page.find(:css, ".seat.position-1 .player")).to have_content "Guest"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.find(:css, ".game-seat.position-2")).to have_content "Guest"
|
||||
expect(page.find(:css, ".seat.position-2 .player")).to have_content "Guest"
|
||||
end
|
||||
|
||||
#TODO: User can only occupy one seat per table
|
||||
scenario 'visitor changes seats' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.find(:css, ".game-seat.position-1")).to have_content "Guest"
|
||||
expect(page.find(:css, ".seat.position-1")).to have_content "Guest"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.find(:css, ".game-seat.position-2")).to have_content "Guest"
|
||||
expect(page.find(:css, ".seat.position-2")).to have_content "Guest"
|
||||
expect(page.text.scan('Guest').count).to eq 1
|
||||
end
|
||||
|
||||
scenario 'visitor can join the current game' do
|
||||
click_button 'Sit', match: :first
|
||||
sleep 3
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.text.scan('Guest').count).to eq 1
|
||||
end
|
||||
@ -60,12 +62,15 @@ feature 'Seats', :devise, js: true do
|
||||
find_all(:button, "Sit")
|
||||
end
|
||||
|
||||
scenario 'visitor can leave the current game' do
|
||||
# scenario 'visitor can leave the current game', js: true do
|
||||
scenario 'seated visitor can leave the current game' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content 'Guest'
|
||||
expect(page.text.scan('Guest').count).to eq 1
|
||||
click_button 'Stand', match: :first
|
||||
expect(page.find('.game-seat.position-1')).to have_content 'Sit'
|
||||
# accept_confirm do
|
||||
click_button 'Leave', match: :first
|
||||
# end
|
||||
expect(page.find('.seat.position-1')).to have_content 'Sit'
|
||||
expect(sit_buttons.length).to eq 4
|
||||
expect(page.text.scan('Guest').count).to eq 0
|
||||
end
|
||||
@ -81,27 +86,24 @@ feature 'Seats', :devise, js: true do
|
||||
end
|
||||
|
||||
scenario 'user can sit at the table' do
|
||||
#TODO: Fix race condition
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
end
|
||||
|
||||
scenario 'user can join the current game' do
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
expect(page.text.scan(@user.email).count).to eq 1
|
||||
end
|
||||
|
||||
# scenario 'user can leave the current game', js: true do
|
||||
scenario 'user can leave the current game' do
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
expect(page.text.scan(@user.email).count).to eq 1
|
||||
click_button 'Stand', match: :first
|
||||
expect(page).to have_content "Sit"
|
||||
sleep 1
|
||||
# accept_confirm do
|
||||
click_button 'Leave', match: :first
|
||||
# end
|
||||
expect(page.text.scan(@user.email).count).to eq 0
|
||||
end
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ feature 'Table index', :devise do
|
||||
# Given I am not signed in
|
||||
# When I click browse tables
|
||||
# Then I see an index of tables
|
||||
scenario 'I can see all the tables', js: true do
|
||||
scenario 'I can see all the tables' do
|
||||
5.times { FactoryGirl.create :table }
|
||||
visit root_path
|
||||
click_link 'Browse Tables'
|
||||
@ -24,7 +24,7 @@ feature 'Table index', :devise do
|
||||
# Given I am signed in
|
||||
# When I click browse tables
|
||||
# Then I see an index of tables
|
||||
scenario 'I can see all the tables', js: true do
|
||||
scenario 'I can see all the tables' do
|
||||
@user = FactoryGirl.create :user
|
||||
signin(@user.email,'password')
|
||||
|
||||
|
||||
@ -10,23 +10,26 @@ feature 'Table show', :devise do
|
||||
click_link @table.title
|
||||
end
|
||||
|
||||
scenario 'visitor can sit at the table', js: true do
|
||||
scenario 'visitor can sit at the table' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
end
|
||||
|
||||
scenario 'visitor can join the current game', js: true do
|
||||
scenario 'visitor can join the current game' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.text.scan('Guest').count).to eq 1
|
||||
end
|
||||
|
||||
scenario 'visitor can leave the current game', js: true do
|
||||
# scenario 'visitor can leave the current game', js: true do
|
||||
scenario 'visitor can leave the current game' do
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content "Guest"
|
||||
expect(page.text.scan('Guest').count).to eq 1
|
||||
# accept_confirm do
|
||||
click_button 'Stand', match: :first
|
||||
expect(page.find('.game-seat.position-1')).to have_content "Sit"
|
||||
# end
|
||||
expect(page.find('.seat.position-1')).to have_content "Sit"
|
||||
expect(page.text.scan('Guest').count).to eq 0
|
||||
end
|
||||
|
||||
@ -40,27 +43,30 @@ feature 'Table show', :devise do
|
||||
visit table_path @table
|
||||
end
|
||||
|
||||
scenario 'user can sit at the table', js: true do
|
||||
scenario 'user can sit at the table' do
|
||||
#TODO: Fix race condition
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
end
|
||||
|
||||
scenario 'user can join the current game', js: true do
|
||||
scenario 'user can join the current game' do
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
expect(page.text.scan(@user.email).count).to eq 1
|
||||
end
|
||||
|
||||
scenario 'user can leave the current game', js: true do
|
||||
# scenario 'user can leave the current game', js: true do
|
||||
scenario 'user can leave the current game' do
|
||||
expect(page).to have_content "Sit"
|
||||
click_button 'Sit', match: :first
|
||||
expect(page).to have_content @user.email
|
||||
expect(page.text.scan(@user.email).count).to eq 1
|
||||
# accept_confirm do
|
||||
click_button 'Stand', match: :first
|
||||
expect(page.find('.game-seat.position-1')).to have_content "Sit"
|
||||
# end
|
||||
expect(page.find('.seat.position-1')).to have_content "Sit"
|
||||
expect(page.text.scan(@user.email).count).to eq 0
|
||||
end
|
||||
|
||||
|
||||
@ -13,18 +13,18 @@ feature 'Table show', :devise do
|
||||
# Given I am not signed in
|
||||
# When I visit a table
|
||||
# Then I see the table attributes
|
||||
scenario 'visitor can see the table', js: true do
|
||||
expect(page).to have_selector "#table-#{@table.id} > h1", @table.title
|
||||
scenario 'visitor can see the table' do
|
||||
expect(page).to have_text @table.title
|
||||
end
|
||||
|
||||
scenario 'visitor can see the seats', js: true do
|
||||
scenario 'visitor can see the seats' do
|
||||
#TODO: Race condition exists without have_content
|
||||
expect(page).to have_content "Sit"
|
||||
expect(page).to have_button "Sit"
|
||||
@seat_count = page.find_all(".seat").length
|
||||
expect(@seat_count).to eq @table.seats.count
|
||||
end
|
||||
|
||||
scenario 'visitor can see the current game', js: true do
|
||||
scenario 'visitor can see the current game' do
|
||||
#TODO: Write a better expectation
|
||||
expect(page).to have_content "Hand to beat"
|
||||
end
|
||||
@ -43,14 +43,14 @@ feature 'Table show', :devise do
|
||||
# Given I am signed in
|
||||
# When I click a table
|
||||
# Then I see the table attributes
|
||||
scenario 'user can see the table', js: true do
|
||||
scenario 'user can see the table' do
|
||||
expect(page).to have_content "Sign out"
|
||||
expect(page).to have_selector "#table-#{@table.id} > h1", @table.title
|
||||
expect(page).to have_content @table.title
|
||||
expect(current_path).to eq table_path(@table)
|
||||
end
|
||||
|
||||
scenario 'user can see the current game', js: true do
|
||||
expect(page).to have_content "Sit"
|
||||
scenario 'user can see the current game' do
|
||||
expect(page).to have_button "Sit"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -9,8 +9,7 @@ feature 'Sign in', :devise do
|
||||
# Then I see an invalid credentials message
|
||||
scenario 'user cannot sign in if not registered' do
|
||||
signin('test@example.com', 'password')
|
||||
expect(page).to have_content
|
||||
I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email'
|
||||
expect(page).to have_content(/#{I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email'}/i)
|
||||
end
|
||||
|
||||
# Scenario: User can sign in with valid credentials
|
||||
@ -21,7 +20,7 @@ feature 'Sign in', :devise do
|
||||
scenario 'user can sign in with valid credentials' do
|
||||
user = FactoryGirl.create(:user)
|
||||
signin(user.email, user.password)
|
||||
expect(page).to have_content I18n.t 'devise.sessions.signed_in'
|
||||
expect(page).to have_content(/#{I18n.t 'devise.sessions.signed_in'}/i)
|
||||
end
|
||||
|
||||
# Scenario: User cannot sign in with wrong email
|
||||
@ -32,8 +31,7 @@ feature 'Sign in', :devise do
|
||||
scenario 'user cannot sign in with wrong email' do
|
||||
user = FactoryGirl.create(:user)
|
||||
signin('invalid@email.com', user.password)
|
||||
expect(page).to have_content
|
||||
I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email'
|
||||
expect(page).to have_content(/#{I18n.t 'devise.failure.not_found_in_database', authentication_keys: 'email'}/i)
|
||||
end
|
||||
|
||||
# Scenario: User cannot sign in with wrong password
|
||||
@ -44,7 +42,6 @@ feature 'Sign in', :devise do
|
||||
scenario 'user cannot sign in with wrong password' do
|
||||
user = FactoryGirl.create(:user)
|
||||
signin(user.email, 'invalidpass')
|
||||
expect(page).to have_content
|
||||
I18n.t 'devise.failure.invalid', authentication_keys: 'email'
|
||||
expect(page).to have_content(/#{I18n.t 'devise.failure.invalid', authentication_keys: 'email'}/i)
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,7 +2,7 @@ require 'rails_helper'
|
||||
include Warden::Test::Helpers
|
||||
Warden.test_mode!
|
||||
|
||||
feature 'Join a game', type: :feature, js: true do
|
||||
feature 'Join a game', type: :feature do
|
||||
# before(:each) do
|
||||
# @game = setup_game
|
||||
# @game.reload
|
||||
@ -24,7 +24,7 @@ feature 'Join a game', type: :feature, js: true do
|
||||
@game = FactoryGirl.create :game
|
||||
@user = FactoryGirl.create :user
|
||||
login_as(@user, scope: :user)
|
||||
visit game_path @game
|
||||
visit table_path @game.table
|
||||
click_button "Sit", match: :first
|
||||
expect(page).to have_content @user.display_name
|
||||
end
|
||||
@ -37,7 +37,7 @@ feature 'Join a game', type: :feature, js: true do
|
||||
@game = FactoryGirl.create :game
|
||||
@user = FactoryGirl.create :user
|
||||
login_as(@user, scope: :user)
|
||||
visit game_path @game
|
||||
visit table_path @game.table
|
||||
click_button "Sit", match: :first
|
||||
expect(page).to have_content @user.display_name
|
||||
click_button "Sit", match: :first
|
||||
|
||||
@ -2,13 +2,11 @@ require 'rails_helper'
|
||||
include Warden::Test::Helpers
|
||||
Warden.test_mode!
|
||||
|
||||
feature 'Play a hand', type: :feature, js: true do
|
||||
feature 'Play a hand', type: :feature do
|
||||
before(:each) do
|
||||
@game = setup_visitor_game
|
||||
visit game_path @game
|
||||
visit table_path @game.table
|
||||
click_button "Sit", match: :first
|
||||
#TODO: Fix race condition
|
||||
sleep 2
|
||||
click_button "Start"
|
||||
@game.reload
|
||||
end
|
||||
@ -18,14 +16,10 @@ feature 'Play a hand', type: :feature, js: true do
|
||||
end
|
||||
|
||||
scenario 'player can see their own 13 card faces' do
|
||||
#TODO: Fix race condition
|
||||
sleep 2
|
||||
expect(page.find_all("#inventory img").length).to eq(13)
|
||||
end
|
||||
|
||||
scenario 'player can see other players 13 card backs' do
|
||||
#TODO: Remove race condition
|
||||
sleep 2
|
||||
inventories = page.find_all(".inventory")
|
||||
inventories.each do |inventory|
|
||||
#TODO: This test should verify that other players card fronts are NOT seen
|
||||
|
||||
@ -7,18 +7,19 @@ feature 'Join game', :devise do
|
||||
# Given I am not signed in
|
||||
# When I visit a joinable game
|
||||
# Then I see a join button
|
||||
scenario 'visitor can join a game', js: true do
|
||||
visit new_game_path
|
||||
fill_in 'game_title', with: 'Test Game'
|
||||
click_button 'Create Game'
|
||||
scenario 'visitor can join a game' do
|
||||
visit new_table_path
|
||||
fill_in 'table_title', with: 'Test Game'
|
||||
click_button 'Create Table'
|
||||
puts current_path
|
||||
expect(page).to have_button("Sit")
|
||||
click_button 'Sit', match: :first
|
||||
#TODO: Fix this asynchronous race condition
|
||||
visit current_path
|
||||
@game = Game.find(current_path.split('/').last)
|
||||
@player = @game.players.last
|
||||
@playerComponent = page.find("#player-1")
|
||||
expect(@playerComponent.text).to have_content("Guest#{@player.soft_token[0..5]}")
|
||||
@table = Table.find(current_path.split('/').last)
|
||||
@player = @table.current_game.players.last
|
||||
@playerComponent = page.find_all(".seat").first
|
||||
expect(@playerComponent.text).to have_content("Guest#{@player.soft_token[0..4]}")
|
||||
end
|
||||
|
||||
scenario 'visitor can join a game in progress' do
|
||||
|
||||
@ -17,17 +17,16 @@ feature 'Navigation links', :devise do
|
||||
# Given I am a visitor
|
||||
# When I click a navigation link
|
||||
# Then I see the proper web page
|
||||
scenario 'follow navigation links', js: :true do
|
||||
# scenario 'follow navigation links', js: :true do
|
||||
scenario 'follow navigation links' do
|
||||
visit root_path
|
||||
@links = {
|
||||
'Play Now': '"/games/1"',
|
||||
'Play Now': '"/tables/1"',
|
||||
'Browse Tables': 'tables_path',
|
||||
#'Tutorial': 'tutorial_path'
|
||||
}
|
||||
@links.each do |link|
|
||||
click_link link[0]
|
||||
#TODO: Remove race condition
|
||||
sleep 1
|
||||
expect(page.current_path).to eq(eval(link[1]))
|
||||
visit root_path
|
||||
end
|
||||
|
||||
@ -17,14 +17,15 @@ feature 'Sign Up', :devise do
|
||||
# Scenario: Visitor joins a game and then signs up
|
||||
# Given I am not signed in
|
||||
# When I join a game and then sign up
|
||||
# Then I should see myself in that game
|
||||
scenario 'visitor joins a game and then signs up', js: true do
|
||||
visit new_game_path
|
||||
fill_in 'game_title', with: 'Test Game'
|
||||
click_button 'Create Game'
|
||||
# Then I should see my registered name
|
||||
scenario 'visitor joins a game and then signs up' do
|
||||
pending
|
||||
visit new_table_path
|
||||
fill_in 'table_title', with: 'Test Game'
|
||||
click_button 'Create Table'
|
||||
click_button 'Sit', match: :first
|
||||
sign_up_with('test@example.com', 'please123', 'please123')
|
||||
visit games_path
|
||||
visit tables_path
|
||||
click_link 'Test Game'
|
||||
expect(page).to have_content('test@example.com')
|
||||
end
|
||||
|
||||
@ -2,7 +2,8 @@ require 'rails_helper'
|
||||
|
||||
RSpec.describe Game, type: :model do
|
||||
before(:each) do
|
||||
@game = FactoryGirl.create(:game)
|
||||
@table = FactoryGirl.create :table
|
||||
@game = @table.current_game
|
||||
@user1 = FactoryGirl.create(:user)
|
||||
@user2 = FactoryGirl.create(:user)
|
||||
end
|
||||
@ -13,10 +14,6 @@ RSpec.describe Game, type: :model do
|
||||
it { should respond_to(:play_to_beat) }
|
||||
it { should respond_to(:winner) }
|
||||
|
||||
it '#title returns a string' do
|
||||
expect(@game.title).to match 'Test Game'
|
||||
end
|
||||
|
||||
it 'has a winner' do
|
||||
# Start the game
|
||||
@player1 = @user1.sit_in(@game.seats.first)
|
||||
@ -29,6 +26,7 @@ RSpec.describe Game, type: :model do
|
||||
@player.play_hand [card]
|
||||
@game.reload
|
||||
while (@game.controlling_player != @player) do
|
||||
break if @game.over?
|
||||
@game.controlling_player.pass
|
||||
@game.reload
|
||||
end
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
RSpec.describe Play, type: :model do
|
||||
before(:each) do
|
||||
@game = setup_game
|
||||
@ -24,11 +25,11 @@ RSpec.describe Play, type: :model do
|
||||
|
||||
end
|
||||
it '#player_cards returns a PlayerCard collection' do
|
||||
expect(@play.player_cards.class).to eq(PlayerCard::ActiveRecord_Associations_CollectionProxy)
|
||||
expect(@play.player_cards.class.to_s).to eq("PlayerCard::ActiveRecord_Associations_CollectionProxy")
|
||||
end
|
||||
|
||||
it '#hand returns a PlayerCard collection' do
|
||||
expect(@play.hand.class).to eq(PlayerCard::ActiveRecord_Associations_CollectionProxy)
|
||||
expect(@play.hand.class.to_s).to eq("PlayerCard::ActiveRecord_Associations_CollectionProxy")
|
||||
end
|
||||
|
||||
it '#hand_type returns a string' do
|
||||
@ -362,14 +363,15 @@ RSpec.describe Play, type: :model do
|
||||
@diamond3 = PlayerCard.new(rank: "3", suit: "Diamond", value: 3)
|
||||
@heart3 = PlayerCard.new(rank: "3", suit: "Heart", value: 4)
|
||||
@cards_to_play = [@spade3, @club3, @diamond3, @heart3]
|
||||
@play = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_beat)
|
||||
@play = Play.new(game_id: @game.id, player_id: @game.controlling_player_id, player_cards: @cards_to_play)
|
||||
|
||||
expect(@play.hand_type).to eq('bomb')
|
||||
#TODO: Refactor this test to only test the @play.beats? method
|
||||
#TODO: Move other expectations to another test
|
||||
#TODO: Test every validation of a play
|
||||
#TODO: Refactor @play.valid? method
|
||||
expect(@play.beats? @play_to_beat).to eq(false)
|
||||
#TODO: Refactor @play.valid? method to account for beats?
|
||||
pending('#EXPECT invalid play Refactor @play.valid? method to account for beats?')
|
||||
expect(@play.valid?).to eq(false)
|
||||
end
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user