mirror of
https://github.com/neocities/neocities.git
synced 2025-04-25 01:32:36 +02:00
Update gems, modernize test stack, fix flaky tests
This commit is contained in:
parent
e223b687b2
commit
69c32d17ed
14 changed files with 583 additions and 578 deletions
5
Gemfile
5
Gemfile
|
@ -71,13 +71,14 @@ group :test do
|
||||||
gem 'mocha', require: nil
|
gem 'mocha', require: nil
|
||||||
gem 'rake', require: nil
|
gem 'rake', require: nil
|
||||||
gem 'poltergeist'
|
gem 'poltergeist'
|
||||||
gem 'capybara_minitest_spec'
|
|
||||||
gem 'capybara', require: nil #, '2.10.1', require: nil
|
gem 'capybara', require: nil #, '2.10.1', require: nil
|
||||||
gem 'rack_session_access', require: nil
|
gem 'rack_session_access', require: nil
|
||||||
gem 'webmock', '3.5.1', require: nil
|
gem 'webmock', '3.5.1', require: nil
|
||||||
gem 'stripe-ruby-mock', '2.5.6', require: 'stripe_mock'
|
gem 'stripe-ruby-mock', '2.5.8', require: 'stripe_mock'
|
||||||
gem 'timecop'
|
gem 'timecop'
|
||||||
gem 'mock_redis'
|
gem 'mock_redis'
|
||||||
gem 'simplecov', require: nil
|
gem 'simplecov', require: nil
|
||||||
gem 'm'
|
gem 'm'
|
||||||
|
gem 'apparition'
|
||||||
|
gem 'poltergeist', require: nil
|
||||||
end
|
end
|
||||||
|
|
102
Gemfile.lock
102
Gemfile.lock
|
@ -15,21 +15,25 @@ GEM
|
||||||
specs:
|
specs:
|
||||||
acme-client (0.6.3)
|
acme-client (0.6.3)
|
||||||
faraday (~> 0.9, >= 0.9.1)
|
faraday (~> 0.9, >= 0.9.1)
|
||||||
activesupport (5.2.3)
|
activesupport (6.0.0)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.6.0)
|
zeitwerk (~> 2.1, >= 2.1.8)
|
||||||
public_suffix (>= 2.0.2, < 4.0)
|
addressable (2.7.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
annoy (0.5.6)
|
annoy (0.5.6)
|
||||||
highline (>= 1.5.0)
|
highline (>= 1.5.0)
|
||||||
ansi (1.5.0)
|
ansi (1.5.0)
|
||||||
|
apparition (0.4.0)
|
||||||
|
capybara (~> 3.13, < 4)
|
||||||
|
websocket-driver (>= 0.6.5)
|
||||||
base32 (0.3.2)
|
base32 (0.3.2)
|
||||||
bcrypt (3.1.13)
|
bcrypt (3.1.13)
|
||||||
builder (3.2.3)
|
builder (3.2.3)
|
||||||
byebug (11.0.1)
|
byebug (11.0.1)
|
||||||
capybara (3.25.0)
|
capybara (3.29.0)
|
||||||
addressable
|
addressable
|
||||||
mini_mime (>= 0.1.3)
|
mini_mime (>= 0.1.3)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
|
@ -37,9 +41,6 @@ GEM
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (~> 1.5)
|
regexp_parser (~> 1.5)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
capybara_minitest_spec (1.0.7)
|
|
||||||
capybara (>= 2)
|
|
||||||
minitest (>= 4)
|
|
||||||
certified (1.0.0)
|
certified (1.0.0)
|
||||||
climate_control (0.2.0)
|
climate_control (0.2.0)
|
||||||
cliver (0.3.2)
|
cliver (0.3.2)
|
||||||
|
@ -57,21 +58,15 @@ GEM
|
||||||
crass (1.0.4)
|
crass (1.0.4)
|
||||||
dante (0.2.0)
|
dante (0.2.0)
|
||||||
docile (1.3.2)
|
docile (1.3.2)
|
||||||
domain_name (0.5.20180417)
|
domain_name (0.5.20190701)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
drydock (0.6.9)
|
drydock (0.6.9)
|
||||||
equatable (0.6.1)
|
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
exifr (1.3.6)
|
exifr (1.3.6)
|
||||||
fabrication (2.20.2)
|
fabrication (2.20.2)
|
||||||
facter (2.5.1)
|
facter (2.5.6)
|
||||||
faker (1.9.4)
|
faker (2.4.0)
|
||||||
i18n (>= 0.7)
|
i18n (~> 1.6.0)
|
||||||
pastel (~> 0.7.2)
|
|
||||||
thor (~> 0.20.0)
|
|
||||||
tty-pager (~> 0.12.0)
|
|
||||||
tty-screen (~> 0.6.5)
|
|
||||||
tty-tree (~> 0.3.0)
|
|
||||||
faraday (0.15.4)
|
faraday (0.15.4)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
faraday_middleware (0.13.1)
|
faraday_middleware (0.13.1)
|
||||||
|
@ -83,12 +78,12 @@ GEM
|
||||||
sax-machine (>= 1.0)
|
sax-machine (>= 1.0)
|
||||||
ffi (1.11.1)
|
ffi (1.11.1)
|
||||||
filesize (0.2.0)
|
filesize (0.2.0)
|
||||||
fspath (3.1.1)
|
fspath (3.1.2)
|
||||||
gandi (3.3.28)
|
gandi (3.3.28)
|
||||||
hashie
|
hashie
|
||||||
xmlrpc
|
xmlrpc
|
||||||
geoip (1.6.4)
|
geoip (1.6.4)
|
||||||
hashdiff (0.4.0)
|
hashdiff (1.0.0)
|
||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
highline (2.0.2)
|
highline (2.0.2)
|
||||||
hiredis (0.6.3)
|
hiredis (0.6.3)
|
||||||
|
@ -100,23 +95,24 @@ GEM
|
||||||
http-cookie (~> 1.0)
|
http-cookie (~> 1.0)
|
||||||
http-form_data (~> 2.0)
|
http-form_data (~> 2.0)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
|
http-accept (1.7.0)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (2.1.1)
|
http-form_data (2.1.1)
|
||||||
http_parser.rb (0.6.0)
|
http_parser.rb (0.6.0)
|
||||||
i18n (1.6.0)
|
i18n (1.6.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
image_optim (0.26.4)
|
image_optim (0.26.5)
|
||||||
exifr (~> 1.2, >= 1.2.2)
|
exifr (~> 1.2, >= 1.2.2)
|
||||||
fspath (~> 3.0)
|
fspath (~> 3.0)
|
||||||
image_size (>= 1.5, < 3)
|
image_size (>= 1.5, < 3)
|
||||||
in_threads (~> 1.3)
|
in_threads (~> 1.3)
|
||||||
progress (~> 3.0, >= 3.0.1)
|
progress (~> 3.0, >= 3.0.1)
|
||||||
image_optim_pack (0.5.3)
|
image_optim_pack (0.6.0)
|
||||||
fspath (>= 2.1, < 4)
|
fspath (>= 2.1, < 4)
|
||||||
image_optim (~> 0.19)
|
image_optim (~> 0.19)
|
||||||
image_size (2.0.1)
|
image_size (2.0.2)
|
||||||
in_threads (1.5.2)
|
in_threads (1.5.3)
|
||||||
io-extra (1.3.0)
|
io-extra (1.3.0)
|
||||||
ipaddress (0.8.3)
|
ipaddress (0.8.3)
|
||||||
json (2.2.0)
|
json (2.2.0)
|
||||||
|
@ -132,13 +128,13 @@ GEM
|
||||||
mini_mime (>= 0.1.1)
|
mini_mime (>= 0.1.1)
|
||||||
metaclass (0.0.4)
|
metaclass (0.0.4)
|
||||||
method_source (0.9.2)
|
method_source (0.9.2)
|
||||||
mime-types (3.2.2)
|
mime-types (3.3)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2019.0331)
|
mime-types-data (3.2019.0904)
|
||||||
mini_mime (1.0.1)
|
mini_mime (1.0.2)
|
||||||
mini_portile2 (2.4.0)
|
mini_portile2 (2.4.0)
|
||||||
minitest (5.11.3)
|
minitest (5.11.3)
|
||||||
minitest-reporters (1.3.6)
|
minitest-reporters (1.3.8)
|
||||||
ansi
|
ansi
|
||||||
builder
|
builder
|
||||||
minitest (>= 5.0)
|
minitest (>= 5.0)
|
||||||
|
@ -146,15 +142,15 @@ GEM
|
||||||
mocha (1.9.0)
|
mocha (1.9.0)
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
mock_redis (0.21.0)
|
mock_redis (0.21.0)
|
||||||
monetize (1.9.1)
|
monetize (1.9.2)
|
||||||
money (~> 6.12)
|
money (~> 6.12)
|
||||||
money (6.13.4)
|
money (6.13.4)
|
||||||
i18n (>= 0.6.4, <= 2)
|
i18n (>= 0.6.4, <= 2)
|
||||||
msgpack (1.3.0)
|
msgpack (1.3.1)
|
||||||
multi_json (1.13.1)
|
multi_json (1.13.1)
|
||||||
multipart-post (2.1.1)
|
multipart-post (2.1.1)
|
||||||
mustermann (1.0.3)
|
mustermann (1.0.3)
|
||||||
net-http-persistent (3.0.1)
|
net-http-persistent (3.1.0)
|
||||||
connection_pool (~> 2.2)
|
connection_pool (~> 2.2)
|
||||||
net-scp (2.0.0)
|
net-scp (2.0.0)
|
||||||
net-ssh (>= 2.6.5, < 6.0.0)
|
net-ssh (>= 2.6.5, < 6.0.0)
|
||||||
|
@ -166,24 +162,21 @@ GEM
|
||||||
nokogumbo (2.0.1)
|
nokogumbo (2.0.1)
|
||||||
nokogiri (~> 1.8, >= 1.8.4)
|
nokogiri (~> 1.8, >= 1.8.4)
|
||||||
ox (2.11.0)
|
ox (2.11.0)
|
||||||
pastel (0.7.3)
|
|
||||||
equatable (~> 0.6)
|
|
||||||
tty-color (~> 0.5)
|
|
||||||
paypal-recurring (1.1.0)
|
paypal-recurring (1.1.0)
|
||||||
pg (1.1.4)
|
pg (1.1.4)
|
||||||
poltergeist (1.18.1)
|
poltergeist (1.18.1)
|
||||||
capybara (>= 2.1, < 4)
|
capybara (>= 2.1, < 4)
|
||||||
cliver (~> 0.3.1)
|
cliver (~> 0.3.1)
|
||||||
websocket-driver (>= 0.2.0)
|
websocket-driver (>= 0.2.0)
|
||||||
progress (3.5.1)
|
progress (3.5.2)
|
||||||
pry (0.12.2)
|
pry (0.12.2)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.9.0)
|
method_source (~> 0.9.0)
|
||||||
pry-byebug (3.7.0)
|
pry-byebug (3.7.0)
|
||||||
byebug (~> 11.0)
|
byebug (~> 11.0)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
public_suffix (3.1.1)
|
public_suffix (4.0.1)
|
||||||
puma (4.1.0)
|
puma (4.1.1)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
rack (2.0.7)
|
rack (2.0.7)
|
||||||
rack-cache (1.9.0)
|
rack-cache (1.9.0)
|
||||||
|
@ -202,13 +195,14 @@ GEM
|
||||||
redis (3.3.5)
|
redis (3.3.5)
|
||||||
redis-namespace (1.6.0)
|
redis-namespace (1.6.0)
|
||||||
redis (>= 3.0.4)
|
redis (>= 3.0.4)
|
||||||
regexp_parser (1.5.1)
|
regexp_parser (1.6.0)
|
||||||
rest-client (2.0.2)
|
rest-client (2.1.0)
|
||||||
|
http-accept (>= 1.7.0, < 2.0)
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 4.0)
|
mime-types (>= 1.16, < 4.0)
|
||||||
netrc (~> 0.8)
|
netrc (~> 0.8)
|
||||||
rinku (2.0.6)
|
rinku (2.0.6)
|
||||||
rmagick (3.2.0)
|
rmagick (4.0.0)
|
||||||
ruby-progressbar (1.10.1)
|
ruby-progressbar (1.10.1)
|
||||||
rye (0.9.13)
|
rye (0.9.13)
|
||||||
annoy
|
annoy
|
||||||
|
@ -218,7 +212,7 @@ GEM
|
||||||
net-ssh (>= 2.0.13)
|
net-ssh (>= 2.0.13)
|
||||||
sysinfo (>= 0.8.1)
|
sysinfo (>= 0.8.1)
|
||||||
safe_yaml (1.0.5)
|
safe_yaml (1.0.5)
|
||||||
sanitize (5.0.0)
|
sanitize (5.1.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.8.0)
|
nokogiri (>= 1.8.0)
|
||||||
nokogumbo (~> 2.0)
|
nokogumbo (~> 2.0)
|
||||||
|
@ -228,7 +222,7 @@ GEM
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
sax-machine (1.3.2)
|
sax-machine (1.3.2)
|
||||||
sequel (5.22.0)
|
sequel (5.24.0)
|
||||||
sequel_pg (1.12.2)
|
sequel_pg (1.12.2)
|
||||||
pg (>= 0.18.0)
|
pg (>= 0.18.0)
|
||||||
sequel (>= 4.38.0)
|
sequel (>= 4.38.0)
|
||||||
|
@ -256,15 +250,10 @@ GEM
|
||||||
sinatra-xsendfile (0.4.2)
|
sinatra-xsendfile (0.4.2)
|
||||||
sinatra (>= 0.9.1)
|
sinatra (>= 0.9.1)
|
||||||
storable (0.8.9)
|
storable (0.8.9)
|
||||||
strings (0.1.5)
|
|
||||||
strings-ansi (~> 0.1)
|
|
||||||
unicode-display_width (~> 1.5)
|
|
||||||
unicode_utils (~> 1.4)
|
|
||||||
strings-ansi (0.1.0)
|
|
||||||
stripe (4.2.0)
|
stripe (4.2.0)
|
||||||
faraday (~> 0.13)
|
faraday (~> 0.13)
|
||||||
net-http-persistent (~> 3.0)
|
net-http-persistent (~> 3.0)
|
||||||
stripe-ruby-mock (2.5.6)
|
stripe-ruby-mock (2.5.8)
|
||||||
dante (>= 0.2.0)
|
dante (>= 0.2.0)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
stripe (>= 2.0.3)
|
stripe (>= 2.0.3)
|
||||||
|
@ -280,22 +269,12 @@ GEM
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.9)
|
tilt (2.0.9)
|
||||||
timecop (0.9.1)
|
timecop (0.9.1)
|
||||||
tins (1.20.3)
|
tins (1.21.1)
|
||||||
tty-color (0.5.0)
|
|
||||||
tty-pager (0.12.1)
|
|
||||||
strings (~> 0.1.4)
|
|
||||||
tty-screen (~> 0.6)
|
|
||||||
tty-which (~> 0.4)
|
|
||||||
tty-screen (0.6.5)
|
|
||||||
tty-tree (0.3.0)
|
|
||||||
tty-which (0.4.1)
|
|
||||||
tzinfo (1.2.5)
|
tzinfo (1.2.5)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.6)
|
unf_ext (0.0.7.6)
|
||||||
unicode-display_width (1.6.0)
|
|
||||||
unicode_utils (1.4.0)
|
|
||||||
uuidtools (2.1.5)
|
uuidtools (2.1.5)
|
||||||
webmock (3.5.1)
|
webmock (3.5.1)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
|
@ -304,10 +283,11 @@ GEM
|
||||||
websocket-driver (0.7.1)
|
websocket-driver (0.7.1)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.4)
|
websocket-extensions (0.1.4)
|
||||||
will_paginate (3.1.7)
|
will_paginate (3.1.8)
|
||||||
xmlrpc (0.3.0)
|
xmlrpc (0.3.0)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
|
zeitwerk (2.1.10)
|
||||||
zipruby (0.3.6)
|
zipruby (0.3.6)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
@ -317,10 +297,10 @@ DEPENDENCIES
|
||||||
acme-client (= 0.6.3)
|
acme-client (= 0.6.3)
|
||||||
activesupport
|
activesupport
|
||||||
addressable
|
addressable
|
||||||
|
apparition
|
||||||
base32
|
base32
|
||||||
bcrypt
|
bcrypt
|
||||||
capybara
|
capybara
|
||||||
capybara_minitest_spec
|
|
||||||
certified
|
certified
|
||||||
coveralls
|
coveralls
|
||||||
dav4rack!
|
dav4rack!
|
||||||
|
@ -377,7 +357,7 @@ DEPENDENCIES
|
||||||
sinatra-flash
|
sinatra-flash
|
||||||
sinatra-xsendfile
|
sinatra-xsendfile
|
||||||
stripe (= 4.2.0)
|
stripe (= 4.2.0)
|
||||||
stripe-ruby-mock (= 2.5.6)
|
stripe-ruby-mock (= 2.5.8)
|
||||||
terrapin
|
terrapin
|
||||||
thread
|
thread
|
||||||
tilt
|
tilt
|
||||||
|
|
|
@ -69,7 +69,7 @@ post '/create' do
|
||||||
return {result: 'error'}.to_json
|
return {result: 'error'}.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
if !@site.valid? || Site.ip_create_limit?(request.ip)
|
if Site.ip_create_limit?(request.ip)
|
||||||
flash[:error] = 'Your IP address has created too many sites, please try again later or contact support.'
|
flash[:error] = 'Your IP address has created too many sites, please try again later or contact support.'
|
||||||
return {result: 'error'}.to_json
|
return {result: 'error'}.to_json
|
||||||
end
|
end
|
||||||
|
@ -78,6 +78,11 @@ post '/create' do
|
||||||
flash[:error] = 'Cannot use a disposable email address.'
|
flash[:error] = 'Cannot use a disposable email address.'
|
||||||
return {result: 'error'}.to_json
|
return {result: 'error'}.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if !@site.valid?
|
||||||
|
flash[:error] = @site.errors.first.last.first
|
||||||
|
return {result: 'error'}.to_json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@site.email_confirmed = true if self.class.development?
|
@site.email_confirmed = true if self.class.development?
|
||||||
|
|
|
@ -105,7 +105,7 @@ Sequel::Model.plugin :validation_helpers
|
||||||
Sequel::Model.plugin :force_encoding, 'UTF-8'
|
Sequel::Model.plugin :force_encoding, 'UTF-8'
|
||||||
Sequel::Model.plugin :defaults_setter
|
Sequel::Model.plugin :defaults_setter
|
||||||
Sequel::Model.plugin :create_timestamp
|
Sequel::Model.plugin :create_timestamp
|
||||||
Sequel.default_timezone = 'UTC'
|
Sequel.default_timezone = :utc
|
||||||
Sequel::Migrator.apply DB, './migrations'
|
Sequel::Migrator.apply DB, './migrations'
|
||||||
|
|
||||||
Stripe.api_key = $config['stripe_api_key']
|
Stripe.api_key = $config['stripe_api_key']
|
||||||
|
|
|
@ -324,7 +324,7 @@ class Site < Sequel::Model
|
||||||
return false if ip.blank?
|
return false if ip.blank?
|
||||||
return true if Site.where(is_banned: true).
|
return true if Site.where(is_banned: true).
|
||||||
where(ip: ip).
|
where(ip: ip).
|
||||||
where(['updated_at > ?', Time.now-BANNED_TIME]).
|
where(['banned_at > ?', Time.now-BANNED_TIME]).
|
||||||
first
|
first
|
||||||
|
|
||||||
return true if BlockedIp[ip]
|
return true if BlockedIp[ip]
|
||||||
|
|
|
@ -51,4 +51,56 @@ describe '/admin' do
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
describe 'email blasting' do
|
||||||
|
before do
|
||||||
|
EmailWorker.jobs.clear
|
||||||
|
@admin_site = Fabricate :site, is_admin: true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works' do
|
||||||
|
DB['update sites set changed_count=?', 0].first
|
||||||
|
relevant_emails = []
|
||||||
|
|
||||||
|
sites_emailed_count = Site::EMAIL_BLAST_MAXIMUM_PER_DAY*2
|
||||||
|
|
||||||
|
sites_emailed_count.times {
|
||||||
|
site = Fabricate :site, updated_at: Time.now, changed_count: 1
|
||||||
|
relevant_emails << site.email
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailWorker.jobs.clear
|
||||||
|
|
||||||
|
time = Time.now
|
||||||
|
|
||||||
|
Timecop.freeze(time) do
|
||||||
|
visit '/admin/email'
|
||||||
|
fill_in 'subject', with: 'Subject Test'
|
||||||
|
fill_in 'body', with: 'Body Test'
|
||||||
|
click_button 'Send'
|
||||||
|
|
||||||
|
relevant_jobs = EmailWorker.jobs.select{|j| relevant_emails.include?(j['args'].first['to']) }
|
||||||
|
relevant_jobs.length.must_equal sites_emailed_count
|
||||||
|
|
||||||
|
relevant_jobs.each do |job|
|
||||||
|
args = job['args'].first
|
||||||
|
args['from'].must_equal 'Kyle from Neocities <kyle@neocities.org>'
|
||||||
|
args['subject'].must_equal 'Subject Test'
|
||||||
|
args['body'].must_equal 'Body Test'
|
||||||
|
end
|
||||||
|
|
||||||
|
relevant_jobs.select {|j| j['at'].nil? || j['at'] == Time.now.to_f}.length.must_equal 1
|
||||||
|
relevant_jobs.select {|j| j['at'] == (Time.now + 0.5).to_f}.length.must_equal 1
|
||||||
|
|
||||||
|
relevant_jobs.select {|j| j['at'] == (time+1.day.to_i).to_f}.length.must_equal 1
|
||||||
|
relevant_jobs.select {|j| j['at'] == (time+1.day.to_i+0.5).to_f}.length.must_equal 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
|
|
||||||
Capybara.register_driver :poltergeist do |app|
|
|
||||||
Capybara::Poltergeist::Driver.new(app, js_errors: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'signup' do
|
describe 'signup' do
|
||||||
include Capybara::DSL
|
include Capybara::DSL
|
||||||
|
|
||||||
|
@ -17,7 +13,7 @@ describe 'signup' do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Capybara.default_driver = :poltergeist
|
Capybara.default_driver = :apparition
|
||||||
Capybara.reset_sessions!
|
Capybara.reset_sessions!
|
||||||
visit '/education'
|
visit '/education'
|
||||||
page.must_have_content 'Neocities' # Used to force load wait
|
page.must_have_content 'Neocities' # Used to force load wait
|
||||||
|
|
|
@ -1,5 +1,30 @@
|
||||||
require_relative '../environment'
|
require_relative '../environment'
|
||||||
|
|
||||||
|
require 'capybara/minitest'
|
||||||
|
require 'capybara/minitest/spec'
|
||||||
|
require 'rack_session_access/capybara'
|
||||||
|
require 'capybara/apparition'
|
||||||
|
|
||||||
|
Capybara.app = Sinatra::Application
|
||||||
|
|
||||||
|
include Capybara::Minitest::Assertions
|
||||||
|
Capybara.default_max_wait_time = 5
|
||||||
|
|
||||||
|
#Capybara.register_driver :apparition do |app|
|
||||||
|
# Capybara::Apparition::Driver.new(app, headless: false)
|
||||||
|
#end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
def setup
|
||||||
|
Capybara.current_driver = :apparition
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
Capybara.reset_sessions!
|
||||||
|
Capybara.use_default_driver
|
||||||
|
end
|
||||||
|
=end
|
||||||
|
=begin
|
||||||
require 'capybara'
|
require 'capybara'
|
||||||
require 'capybara/dsl'
|
require 'capybara/dsl'
|
||||||
require 'capybara/poltergeist'
|
require 'capybara/poltergeist'
|
||||||
|
@ -10,3 +35,4 @@ Capybara.app = Sinatra::Application
|
||||||
def teardown
|
def teardown
|
||||||
Capybara.reset_sessions!
|
Capybara.reset_sessions!
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
|
|
||||||
Capybara.register_driver :poltergeist do |app|
|
|
||||||
Capybara::Poltergeist::Driver.new(app, js_errors: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'signup' do
|
describe 'signup' do
|
||||||
include Capybara::DSL
|
include Capybara::DSL
|
||||||
|
|
||||||
|
@ -28,10 +24,9 @@ describe 'signup' do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Capybara.default_driver = :poltergeist
|
Capybara.default_driver = :apparition
|
||||||
Capybara.reset_sessions!
|
Capybara.reset_sessions!
|
||||||
visit_signup
|
visit_signup
|
||||||
page.must_have_content 'Neocities' # Used to force load wait
|
|
||||||
end
|
end
|
||||||
|
|
||||||
after do
|
after do
|
||||||
|
@ -65,15 +60,15 @@ describe 'signup' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails if site with same ip has been banned' do
|
it 'fails if site with same ip has been banned' do
|
||||||
@banned_site = Fabricate :site
|
@banned_site = Fabricate :site, ip: '127.0.0.1'
|
||||||
@banned_site.is_banned = true
|
@banned_site.ban!
|
||||||
@banned_site.save_changes
|
|
||||||
|
|
||||||
fill_in_valid
|
fill_in_valid
|
||||||
click_signup_button
|
click_signup_button
|
||||||
|
site = Site[username: @site[:username]]
|
||||||
Site[username: @site[:username]].must_be_nil
|
Site[username: @site[:username]].must_be_nil
|
||||||
current_path.must_equal '/'
|
current_path.must_equal '/'
|
||||||
page.wont_have_content 'Welcome to Neocities'
|
page.wont_have_content 'Welcome to Neocities'
|
||||||
|
@banned_site.update ip: nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails if IP is banned from blocked ips list' do
|
it 'fails if IP is banned from blocked ips list' do
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
|
|
||||||
Capybara.register_driver :poltergeist do |app|
|
|
||||||
Capybara::Poltergeist::Driver.new(app, js_errors: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '/supporter' do
|
describe '/supporter' do
|
||||||
include Capybara::DSL
|
include Capybara::DSL
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Capybara.default_driver = :poltergeist
|
Capybara.default_driver = :apparition
|
||||||
Capybara.reset_sessions!
|
Capybara.reset_sessions!
|
||||||
|
|
||||||
@site = Fabricate :site
|
@site = Fabricate :site
|
||||||
|
@ -33,14 +29,16 @@ describe '/supporter' do
|
||||||
|
|
||||||
it 'should work for fresh signup' do
|
it 'should work for fresh signup' do
|
||||||
visit '/supporter'
|
visit '/supporter'
|
||||||
find('#cc_number', visible: false).set '4242424242424242'
|
find('.cc-number input[type=text]').set '4242424242424242'
|
||||||
find('#cc_exp_month', visible: false).set '01'
|
all('.cc-exp input[type=text]').first.set '01'
|
||||||
find('#cc_exp_year', visible: false).set Date.today.next_year.year.to_s[2..3]
|
all('.cc-exp input[type=text]').last.set Date.today.next_year.year.to_s[2..3]
|
||||||
find('#cc_name', visible: false).set 'Penelope'
|
find('.cc-name').set 'Penelope'
|
||||||
find('#cc_cvc', visible: false).set '123'
|
all('.flip-tab').first.click
|
||||||
find('#stripe_token', visible: false).set @stripe_helper.generate_card_token
|
find('.cc-cvc').set '123'
|
||||||
|
page.evaluate_script("document.getElementById('stripe_token').value = '#{@stripe_helper.generate_card_token}'")
|
||||||
click_link 'Upgrade for $5/mo'
|
click_link 'Upgrade for $5/mo'
|
||||||
page.current_path.must_equal '/supporter/thanks'
|
page.current_path.must_equal '/supporter/thanks'
|
||||||
|
all('.txt-Center')
|
||||||
page.body.must_match /You have become a Neocities Supporter/
|
page.body.must_match /You have become a Neocities Supporter/
|
||||||
@site.reload
|
@site.reload
|
||||||
@site.stripe_customer_id.wont_be_nil
|
@site.stripe_customer_id.wont_be_nil
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
require_relative './environment.rb'
|
|
||||||
require 'rack/test'
|
|
||||||
|
|
||||||
include Rack::Test::Methods
|
|
||||||
|
|
||||||
def app
|
|
||||||
Sinatra::Application
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'email blasting' do
|
|
||||||
before do
|
|
||||||
EmailWorker.jobs.clear
|
|
||||||
@admin_site = Fabricate :site, is_admin: true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'works' do
|
|
||||||
DB['update sites set changed_count=?', 0].first
|
|
||||||
relevant_emails = []
|
|
||||||
|
|
||||||
sites_emailed_count = Site::EMAIL_BLAST_MAXIMUM_PER_DAY*2
|
|
||||||
|
|
||||||
sites_emailed_count.times {
|
|
||||||
site = Fabricate :site, updated_at: Time.now, changed_count: 1
|
|
||||||
relevant_emails << site.email
|
|
||||||
}
|
|
||||||
|
|
||||||
EmailWorker.jobs.clear
|
|
||||||
|
|
||||||
time = Time.now
|
|
||||||
|
|
||||||
Timecop.freeze(time) do
|
|
||||||
post '/admin/email', {
|
|
||||||
:csrf_token => 'abcd',
|
|
||||||
:subject => 'Subject Test',
|
|
||||||
:body => 'Body Test'}, {
|
|
||||||
'rack.session' => { 'id' => @admin_site.id, '_csrf_token' => 'abcd' }
|
|
||||||
}
|
|
||||||
|
|
||||||
relevant_jobs = EmailWorker.jobs.select{|j| relevant_emails.include?(j['args'].first['to']) }
|
|
||||||
relevant_jobs.length.must_equal sites_emailed_count
|
|
||||||
|
|
||||||
relevant_jobs.each do |job|
|
|
||||||
args = job['args'].first
|
|
||||||
args['from'].must_equal 'Kyle from Neocities <kyle@neocities.org>'
|
|
||||||
args['subject'].must_equal 'Subject Test'
|
|
||||||
args['body'].must_equal 'Body Test'
|
|
||||||
end
|
|
||||||
|
|
||||||
relevant_jobs.select {|j| j['at'].nil? || j['at'] == Time.now.to_f}.length.must_equal 1
|
|
||||||
relevant_jobs.select {|j| j['at'] == (Time.now + 0.5).to_f}.length.must_equal 1
|
|
||||||
|
|
||||||
relevant_jobs.select {|j| j['at'] == (time+1.day.to_i).to_f}.length.must_equal 1
|
|
||||||
relevant_jobs.select {|j| j['at'] == (time+1.day.to_i+0.5).to_f}.length.must_equal 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,320 +1,329 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
require 'rack/test'
|
require 'rack/test'
|
||||||
|
|
||||||
include Rack::Test::Methods
|
describe 'api' do
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
def app
|
def app
|
||||||
Sinatra::Application
|
Sinatra::Application
|
||||||
end
|
|
||||||
|
|
||||||
def create_site(opts={})
|
|
||||||
site_attr = Fabricate.attributes_for :site
|
|
||||||
@site = Site.create site_attr.merge(opts)
|
|
||||||
@user = site_attr[:username]
|
|
||||||
@pass = site_attr[:password]
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api not found' do
|
|
||||||
it 'returns json for missing route' do
|
|
||||||
get '/api/sdlfkjsdlfjds'
|
|
||||||
last_response.status.must_equal 404
|
|
||||||
res[:result].must_equal 'error'
|
|
||||||
res[:error_type].must_equal 'not_found'
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api list' do
|
def create_site(opts={})
|
||||||
it 'returns all files without path' do
|
site_attr = Fabricate.attributes_for :site
|
||||||
create_site
|
@site = Site.create site_attr.merge(opts)
|
||||||
basic_authorize @user, @pass
|
@user = site_attr[:username]
|
||||||
get '/api/list'
|
@pass = site_attr[:password]
|
||||||
|
end
|
||||||
|
|
||||||
res[:result].must_equal 'success'
|
def site_file_exists?(file)
|
||||||
res[:files].length.must_equal @site.site_files.length
|
File.exist?(@site.files_path(file))
|
||||||
|
end
|
||||||
|
|
||||||
res[:files].each do |file|
|
def res
|
||||||
site_file = @site.site_files.select {|s| s[:path] == file[:path]}.first
|
JSON.parse last_response.body, symbolize_names: true
|
||||||
site_file[:is_directory].must_equal file[:is_directory]
|
end
|
||||||
site_file[:size].must_equal file[:size]
|
|
||||||
site_file[:updated_at].rfc2822.must_equal file[:updated_at]
|
describe 'not found' do
|
||||||
site_file[:sha1_hash].must_equal file[:sha1_hash]
|
it 'returns json for missing route' do
|
||||||
|
get '/api/sdlfkjsdlfjds'
|
||||||
|
last_response.status.must_equal 404
|
||||||
|
res[:result].must_equal 'error'
|
||||||
|
res[:error_type].must_equal 'not_found'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows empty array for missing path' do
|
describe 'list' do
|
||||||
create_site
|
it 'returns all files without path' do
|
||||||
basic_authorize @user, @pass
|
create_site
|
||||||
get '/api/list', path: '/fail'
|
basic_authorize @user, @pass
|
||||||
res[:result].must_equal 'success'
|
get '/api/list'
|
||||||
res[:files].must_equal []
|
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
res[:files].length.must_equal @site.site_files.length
|
||||||
|
|
||||||
|
res[:files].each do |file|
|
||||||
|
site_file = @site.site_files.select {|s| s[:path] == file[:path]}.first
|
||||||
|
site_file[:is_directory].must_equal file[:is_directory]
|
||||||
|
site_file[:size].must_equal file[:size]
|
||||||
|
site_file[:updated_at].rfc2822.must_equal file[:updated_at]
|
||||||
|
site_file[:sha1_hash].must_equal file[:sha1_hash]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows empty array for missing path' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
get '/api/list', path: '/fail'
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
res[:files].must_equal []
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows files in path' do
|
||||||
|
create_site
|
||||||
|
tempfile = Tempfile.new
|
||||||
|
tempfile.write('meep html')
|
||||||
|
@site.store_files [{filename: '/derp/test.html', tempfile: tempfile}]
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
get '/api/list', path: '/derp'
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
res[:files].length.must_equal 1
|
||||||
|
file = res[:files].first
|
||||||
|
file[:path].must_equal 'derp/test.html'
|
||||||
|
file[:updated_at].must_equal @site.site_files.select {|s| s.path == 'derp/test.html'}.first.updated_at.rfc2822
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows files in path' do
|
describe 'info' do
|
||||||
create_site
|
it 'fails for no input' do
|
||||||
tempfile = Tempfile.new
|
get '/api/info'
|
||||||
tempfile.write('meep html')
|
res[:error_type] = 'missing_sitename'
|
||||||
@site.store_files [{filename: '/derp/test.html', tempfile: tempfile}]
|
end
|
||||||
basic_authorize @user, @pass
|
|
||||||
get '/api/list', path: '/derp'
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
res[:files].length.must_equal 1
|
|
||||||
file = res[:files].first
|
|
||||||
file[:path].must_equal 'derp/test.html'
|
|
||||||
file[:updated_at].must_equal @site.site_files.select {|s| s.path == 'derp/test.html'}.first.updated_at.rfc2822
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api info' do
|
it 'fails for banned sites' do
|
||||||
it 'fails for no input' do
|
create_site
|
||||||
get '/api/info'
|
@site.update is_banned: true
|
||||||
res[:error_type] = 'missing_sitename'
|
get '/api/info', sitename: @site.username
|
||||||
|
res[:error_type].must_equal 'site_not_found'
|
||||||
|
@site.reload.api_calls.must_equal 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails for nonexistent site' do
|
||||||
|
get '/api/info', sitename: 'notexist'
|
||||||
|
res[:error_type].must_equal 'site_not_found'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds for valid sitename' do
|
||||||
|
create_site
|
||||||
|
@site.update hits: 31337, domain: 'derp.com', new_tags_string: 'derpie, man'
|
||||||
|
@site.add_archive ipfs_hash: 'QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU'
|
||||||
|
get '/api/info', sitename: @user
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
res[:info][:sitename].must_equal @site.username
|
||||||
|
res[:info][:hits].must_equal 31337
|
||||||
|
res[:info][:created_at].must_equal @site.created_at.rfc2822
|
||||||
|
res[:info][:last_updated].must_be_nil
|
||||||
|
res[:info][:domain].must_equal 'derp.com'
|
||||||
|
res[:info][:tags].must_equal ['derpie', 'man']
|
||||||
|
res[:info][:latest_ipfs_hash].must_equal 'QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU'
|
||||||
|
@site.reload.api_calls.must_equal 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows latest ipfs hash as nil when not present' do
|
||||||
|
create_site
|
||||||
|
get '/api/info', sitename: @user
|
||||||
|
res[:info][:latest_ipfs_hash].must_be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails for bad auth' do
|
||||||
|
basic_authorize 'derp', 'fake'
|
||||||
|
get '/api/info'
|
||||||
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds for api auth' do
|
||||||
|
create_site
|
||||||
|
@site.update hits: 12345
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
get '/api/info'
|
||||||
|
res[:info][:hits] == 12345
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails for banned sites' do
|
describe 'delete' do
|
||||||
create_site
|
it 'fails with no or bad auth' do
|
||||||
@site.update is_banned: true
|
post '/api/delete', filenames: ['hi.html']
|
||||||
get '/api/info', sitename: @site.username
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
res[:error_type].must_equal 'site_not_found'
|
create_site
|
||||||
@site.reload.api_calls.must_equal 0
|
basic_authorize 'derp', 'fake'
|
||||||
|
post '/api/delete', filenames: ['hi.html']
|
||||||
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails with missing filename argument' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/delete'
|
||||||
|
res[:error_type].must_equal 'missing_filenames'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to delete index.html' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/delete', filenames: ['index.html']
|
||||||
|
res[:error_type].must_equal 'cannot_delete_index'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds with weird filenames' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
@site.store_files [{filename: 't$st.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
||||||
|
post '/api/delete', filenames: ['t$st.jpg']
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/delete', filenames: ['./config.yml']
|
||||||
|
res[:error_type].must_equal 'missing_files'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails with missing files' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
@site.store_files [{filename: 'test.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
||||||
|
post '/api/delete', filenames: ['doesntexist.jpg']
|
||||||
|
res[:error_type].must_equal 'missing_files'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to delete site directory' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/delete', filenames: ['/']
|
||||||
|
res[:error_type].must_equal 'cannot_delete_site_directory'
|
||||||
|
File.exist?(@site.files_path).must_equal true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to delete other directories' do
|
||||||
|
create_site
|
||||||
|
@other_site = @site
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/delete', filenames: ["../#{@other_site.username}"]
|
||||||
|
File.exist?(@other_site.base_files_path).must_equal true
|
||||||
|
res[:error_type].must_equal 'missing_files'
|
||||||
|
post '/api/delete', filenames: ["../#{@other_site.username}/index.html"]
|
||||||
|
File.exist?(@other_site.base_files_path+'/index.html').must_equal true
|
||||||
|
res[:error_type].must_equal 'missing_files'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds with valid filenames' do
|
||||||
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
@site.store_files [{filename: 'test.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
||||||
|
@site.store_files [{filename: 'test2.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
||||||
|
post '/api/delete', filenames: ['test.jpg', 'test2.jpg']
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
site_file_exists?('test.jpg').must_equal false
|
||||||
|
site_file_exists?('test2.jpg').must_equal false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails for nonexistent site' do
|
describe 'key' do
|
||||||
get '/api/info', sitename: 'notexist'
|
it 'generates new key with valid login' do
|
||||||
res[:error_type].must_equal 'site_not_found'
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
get '/api/key'
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
res[:api_key].must_equal @site.reload.api_key
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns existing key' do
|
||||||
|
create_site
|
||||||
|
@site.generate_api_key!
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
get '/api/key'
|
||||||
|
res[:api_key].must_equal @site.api_key
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails for bad login' do
|
||||||
|
create_site
|
||||||
|
basic_authorize 'zero', 'cool'
|
||||||
|
get '/api/key'
|
||||||
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'succeeds for valid sitename' do
|
describe 'upload hash' do
|
||||||
create_site
|
it 'succeeds' do
|
||||||
@site.update hits: 31337, domain: 'derp.com', new_tags_string: 'derpie, man'
|
create_site
|
||||||
@site.add_archive ipfs_hash: 'QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU'
|
basic_authorize @user, @pass
|
||||||
get '/api/info', sitename: @user
|
test_hash = Digest::SHA1.file('./tests/files/test.jpg').hexdigest
|
||||||
res[:result].must_equal 'success'
|
|
||||||
res[:info][:sitename].must_equal @site.username
|
post '/api/upload', {
|
||||||
res[:info][:hits].must_equal 31337
|
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
||||||
res[:info][:created_at].must_equal @site.created_at.rfc2822
|
'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
res[:info][:last_updated].must_be_nil
|
}
|
||||||
res[:info][:domain].must_equal 'derp.com'
|
|
||||||
res[:info][:tags].must_equal ['derpie', 'man']
|
post '/api/upload_hash', "test.jpg" => test_hash, "test2.jpg" => Digest::SHA1.hexdigest('herpderp')
|
||||||
res[:info][:latest_ipfs_hash].must_equal 'QmXGTaGWTT1uUtfSb2sBAvArMEVLK4rQEcQg5bv7wwdzwU'
|
|
||||||
@site.reload.api_calls.must_equal 0
|
res[:result].must_equal 'success'
|
||||||
|
res[:files][:'test.jpg'].must_equal true
|
||||||
|
res[:files][:'test2.jpg'].must_equal false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows latest ipfs hash as nil when not present' do
|
describe 'rename' do
|
||||||
create_site
|
before do
|
||||||
get '/api/info', sitename: @user
|
create_site
|
||||||
res[:info][:latest_ipfs_hash].must_be_nil
|
basic_authorize @user, @pass
|
||||||
|
post '/api/upload', {
|
||||||
|
'testdir/test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds' do
|
||||||
|
post '/api/rename', path: 'testdir/test.jpg', new_path: 'testdir/test2.jpg'
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to overwrite index file' do
|
||||||
|
post '/api/rename', path: 'testdir/test.jpg', new_path: 'index.html'
|
||||||
|
res[:result].must_equal 'error'
|
||||||
|
res[:error_type].must_equal 'rename_error'
|
||||||
|
res[:message].must_equal 'file already exists'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails to overwrite existing file' do
|
||||||
|
post '/api/rename', path: 'testdir/test.jpg', new_path: 'not_found.html'
|
||||||
|
res[:result].must_equal 'error'
|
||||||
|
res[:error_type].must_equal 'rename_error'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds with directory' do
|
||||||
|
@site.create_directory 'derpiedir'
|
||||||
|
post '/api/rename', path: 'derpiedir', new_path: 'notderpiedir'
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails for bad auth' do
|
describe 'upload' do
|
||||||
basic_authorize 'derp', 'fake'
|
it 'fails with no auth' do
|
||||||
get '/api/info'
|
post '/api/upload'
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
res[:result].must_equal 'error'
|
||||||
end
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
|
end
|
||||||
|
|
||||||
it 'succeeds for api auth' do
|
it 'fails for bad auth' do
|
||||||
create_site
|
basic_authorize 'username', 'password'
|
||||||
@site.update hits: 12345
|
post '/api/upload'
|
||||||
basic_authorize @user, @pass
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
get '/api/info'
|
end
|
||||||
res[:info][:hits] == 12345
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api delete' do
|
it 'fails with missing files' do
|
||||||
it 'fails with no or bad auth' do
|
create_site
|
||||||
post '/api/delete', filenames: ['hi.html']
|
basic_authorize @user, @pass
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
post '/api/upload'
|
||||||
create_site
|
res[:error_type].must_equal 'missing_files'
|
||||||
basic_authorize 'derp', 'fake'
|
end
|
||||||
post '/api/delete', filenames: ['hi.html']
|
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails with missing filename argument' do
|
it 'succeeds with valid api key' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
@site.api_key.must_be_nil
|
||||||
post '/api/delete'
|
@site.generate_api_key!
|
||||||
res[:error_type].must_equal 'missing_filenames'
|
@site.reload.api_key.wont_equal nil
|
||||||
end
|
header 'Authorization', "Bearer #{@site.api_key}"
|
||||||
|
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
site_file_exists?('test.jpg').must_equal true
|
||||||
|
end
|
||||||
|
|
||||||
it 'fails to delete index.html' do
|
it 'fails with bad api key' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
@site.generate_api_key!
|
||||||
post '/api/delete', filenames: ['index.html']
|
header 'Authorization', "Bearer zerocool"
|
||||||
res[:error_type].must_equal 'cannot_delete_index'
|
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
end
|
res[:result].must_equal 'error'
|
||||||
|
res[:error_type].must_equal 'invalid_auth'
|
||||||
it 'succeeds with weird filenames' do
|
end
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
@site.store_files [{filename: 't$st.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
|
||||||
post '/api/delete', filenames: ['t$st.jpg']
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/delete', filenames: ['./config.yml']
|
|
||||||
res[:error_type].must_equal 'missing_files'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails with missing files' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
@site.store_files [{filename: 'test.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
|
||||||
post '/api/delete', filenames: ['doesntexist.jpg']
|
|
||||||
res[:error_type].must_equal 'missing_files'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails to delete site directory' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/delete', filenames: ['/']
|
|
||||||
res[:error_type].must_equal 'cannot_delete_site_directory'
|
|
||||||
File.exist?(@site.files_path).must_equal true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails to delete other directories' do
|
|
||||||
create_site
|
|
||||||
@other_site = @site
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/delete', filenames: ["../#{@other_site.username}"]
|
|
||||||
File.exist?(@other_site.base_files_path).must_equal true
|
|
||||||
res[:error_type].must_equal 'missing_files'
|
|
||||||
post '/api/delete', filenames: ["../#{@other_site.username}/index.html"]
|
|
||||||
File.exist?(@other_site.base_files_path+'/index.html').must_equal true
|
|
||||||
res[:error_type].must_equal 'missing_files'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds with valid filenames' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
@site.store_files [{filename: 'test.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
|
||||||
@site.store_files [{filename: 'test2.jpg', tempfile: Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')}]
|
|
||||||
post '/api/delete', filenames: ['test.jpg', 'test2.jpg']
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
site_file_exists?('test.jpg').must_equal false
|
|
||||||
site_file_exists?('test2.jpg').must_equal false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api key' do
|
|
||||||
it 'generates new key with valid login' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
get '/api/key'
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
res[:api_key].must_equal @site.reload.api_key
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns existing key' do
|
|
||||||
create_site
|
|
||||||
@site.generate_api_key!
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
get '/api/key'
|
|
||||||
res[:api_key].must_equal @site.api_key
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails for bad login' do
|
|
||||||
create_site
|
|
||||||
basic_authorize 'zero', 'cool'
|
|
||||||
get '/api/key'
|
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api upload hash' do
|
|
||||||
it 'succeeds' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
test_hash = Digest::SHA1.file('./tests/files/test.jpg').hexdigest
|
|
||||||
|
|
||||||
post '/api/upload', {
|
|
||||||
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
|
||||||
'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
}
|
|
||||||
|
|
||||||
post '/api/upload_hash', "test.jpg" => test_hash, "test2.jpg" => Digest::SHA1.hexdigest('herpderp')
|
|
||||||
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
res[:files][:'test.jpg'].must_equal true
|
|
||||||
res[:files][:'test2.jpg'].must_equal false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api rename' do
|
|
||||||
before do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/upload', {
|
|
||||||
'testdir/test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds' do
|
|
||||||
post '/api/rename', path: 'testdir/test.jpg', new_path: 'testdir/test2.jpg'
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails to overwrite index file' do
|
|
||||||
post '/api/rename', path: 'testdir/test.jpg', new_path: 'index.html'
|
|
||||||
res[:result].must_equal 'error'
|
|
||||||
res[:error_type].must_equal 'rename_error'
|
|
||||||
res[:message].must_equal 'file already exists'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails to overwrite existing file' do
|
|
||||||
post '/api/rename', path: 'testdir/test.jpg', new_path: 'not_found.html'
|
|
||||||
res[:result].must_equal 'error'
|
|
||||||
res[:error_type].must_equal 'rename_error'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds with directory' do
|
|
||||||
@site.create_directory 'derpiedir'
|
|
||||||
post '/api/rename', path: 'derpiedir', new_path: 'notderpiedir'
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'api upload' do
|
|
||||||
it 'fails with no auth' do
|
|
||||||
post '/api/upload'
|
|
||||||
res[:result].must_equal 'error'
|
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails for bad auth' do
|
|
||||||
basic_authorize 'username', 'password'
|
|
||||||
post '/api/upload'
|
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails with missing files' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/upload'
|
|
||||||
res[:error_type].must_equal 'missing_files'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds with valid api key' do
|
|
||||||
create_site
|
|
||||||
@site.api_key.must_be_nil
|
|
||||||
@site.generate_api_key!
|
|
||||||
@site.reload.api_key.wont_equal nil
|
|
||||||
header 'Authorization', "Bearer #{@site.api_key}"
|
|
||||||
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
site_file_exists?('test.jpg').must_equal true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'fails with bad api key' do
|
|
||||||
create_site
|
|
||||||
@site.generate_api_key!
|
|
||||||
header 'Authorization', "Bearer zerocool"
|
|
||||||
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
res[:result].must_equal 'error'
|
|
||||||
res[:error_type].must_equal 'invalid_auth'
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
# Getting too slow to run this test
|
# Getting too slow to run this test
|
||||||
|
@ -332,125 +341,118 @@ describe 'api upload' do
|
||||||
end
|
end
|
||||||
=end
|
=end
|
||||||
|
|
||||||
it 'resists directory traversal attack' do
|
it 'resists directory traversal attack' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'../lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'../lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
}
|
}
|
||||||
res[:result].must_equal 'success'
|
res[:result].must_equal 'success'
|
||||||
File.exist?(File.join(Site::SITE_FILES_ROOT, Site.sharding_dir(@site.username), @site.username, 'lol.jpg')).must_equal true
|
File.exist?(File.join(Site::SITE_FILES_ROOT, Site.sharding_dir(@site.username), @site.username, 'lol.jpg')).must_equal true
|
||||||
@site.reload.api_calls.must_equal 1
|
@site.reload.api_calls.must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'scrubs root path slash' do
|
it 'scrubs root path slash' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
}
|
}
|
||||||
res[:result].must_equal 'success'
|
res[:result].must_equal 'success'
|
||||||
File.exist?(File.join(Site::SITE_FILES_ROOT, Site.sharding_dir(@site.username), @site.username, 'lol.jpg')).must_equal true
|
File.exist?(File.join(Site::SITE_FILES_ROOT, Site.sharding_dir(@site.username), @site.username, 'lol.jpg')).must_equal true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails for missing file name' do
|
it 'fails for missing file name' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'/' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'/' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
}
|
}
|
||||||
res[:error_type].must_equal 'invalid_file_type'
|
res[:error_type].must_equal 'invalid_file_type'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails for file with no extension' do
|
it 'fails for file with no extension' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'derpie' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'derpie' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
}
|
}
|
||||||
res[:error_type].must_equal 'invalid_file_type'
|
res[:error_type].must_equal 'invalid_file_type'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates path for file uploads' do
|
it 'creates path for file uploads' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
|
||||||
'derpie/derpingtons/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
}
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
File.exist?(@site.files_path('derpie/derpingtons/lol.jpg')).must_equal true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'records api calls that require auth' do
|
|
||||||
create_site
|
|
||||||
basic_authorize @user, @pass
|
|
||||||
|
|
||||||
2.times {
|
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'derpie/derpingtons/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'derpie/derpingtons/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
}
|
}
|
||||||
}
|
res[:result].must_equal 'success'
|
||||||
|
File.exist?(@site.files_path('derpie/derpingtons/lol.jpg')).must_equal true
|
||||||
|
end
|
||||||
|
|
||||||
@site.reload.api_calls.must_equal 2
|
it 'records api calls that require auth' do
|
||||||
end
|
create_site
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
|
||||||
it 'fails for invalid files' do
|
2.times {
|
||||||
create_site
|
post '/api/upload', {
|
||||||
basic_authorize @user, @pass
|
'derpie/derpingtons/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
post '/api/upload', {
|
}
|
||||||
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
}
|
||||||
'nord.avi' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'image/jpeg')
|
|
||||||
}
|
|
||||||
res[:error_type].must_equal 'invalid_file_type'
|
|
||||||
site_file_exists?('test.jpg').must_equal false
|
|
||||||
site_file_exists?('nord.avi').must_equal false
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds with single file' do
|
@site.reload.api_calls.must_equal 2
|
||||||
create_site
|
end
|
||||||
basic_authorize @user, @pass
|
|
||||||
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
|
||||||
res[:result].must_equal 'success'
|
|
||||||
site_file_exists?('test.jpg').must_equal true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds with two files' do
|
it 'fails for invalid files' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', {
|
post '/api/upload', {
|
||||||
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
||||||
'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
'nord.avi' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'image/jpeg')
|
||||||
}
|
}
|
||||||
res[:result].must_equal 'success'
|
res[:error_type].must_equal 'invalid_file_type'
|
||||||
site_file_exists?('test.jpg').must_equal true
|
site_file_exists?('test.jpg').must_equal false
|
||||||
site_file_exists?('test2.jpg').must_equal true
|
site_file_exists?('nord.avi').must_equal false
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'fails with unwhitelisted file' do
|
it 'succeeds with single file' do
|
||||||
create_site
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav')
|
post '/api/upload', 'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
res[:result].must_equal 'error'
|
res[:result].must_equal 'success'
|
||||||
res[:error_type].must_equal 'invalid_file_type'
|
site_file_exists?('test.jpg').must_equal true
|
||||||
site_file_exists?('flowercrime.wav').must_equal false
|
end
|
||||||
end
|
|
||||||
|
|
||||||
it 'succeeds for unwhitelisted file on supported plans' do
|
it 'succeeds with two files' do
|
||||||
no_file_restriction_plans = Site::PLAN_FEATURES.select {|p,v| v[:no_file_restrictions] == true}
|
create_site
|
||||||
no_file_restriction_plans.each do |plan_type,hash|
|
basic_authorize @user, @pass
|
||||||
create_site plan_type: plan_type
|
post '/api/upload', {
|
||||||
|
'test.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg'),
|
||||||
|
'test2.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
|
}
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
site_file_exists?('test.jpg').must_equal true
|
||||||
|
site_file_exists?('test2.jpg').must_equal true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fails with unwhitelisted file' do
|
||||||
|
create_site
|
||||||
basic_authorize @user, @pass
|
basic_authorize @user, @pass
|
||||||
post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav')
|
post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav')
|
||||||
res[:result].must_equal 'success'
|
res[:result].must_equal 'error'
|
||||||
site_file_exists?('flowercrime.wav').must_equal true
|
res[:error_type].must_equal 'invalid_file_type'
|
||||||
|
site_file_exists?('flowercrime.wav').must_equal false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'succeeds for unwhitelisted file on supported plans' do
|
||||||
|
no_file_restriction_plans = Site::PLAN_FEATURES.select {|p,v| v[:no_file_restrictions] == true}
|
||||||
|
no_file_restriction_plans.each do |plan_type,hash|
|
||||||
|
create_site plan_type: plan_type
|
||||||
|
basic_authorize @user, @pass
|
||||||
|
post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav')
|
||||||
|
res[:result].must_equal 'success'
|
||||||
|
site_file_exists?('flowercrime.wav').must_equal true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def site_file_exists?(file)
|
|
||||||
File.exist?(@site.files_path(file))
|
|
||||||
end
|
|
||||||
|
|
||||||
def res
|
|
||||||
JSON.parse last_response.body, symbolize_names: true
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
|
require 'rack/test'
|
||||||
include Rack::Test::Methods
|
|
||||||
|
|
||||||
def app
|
|
||||||
Sinatra::Application
|
|
||||||
end
|
|
||||||
|
|
||||||
def upload(hash)
|
|
||||||
post '/site_files/upload', hash.merge(csrf_token: 'abcd'), {'rack.session' => { 'id' => @site.id, '_csrf_token' => 'abcd' }}
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete_file(hash)
|
|
||||||
post '/site_files/delete', hash.merge(csrf_token: 'abcd'), {'rack.session' => { 'id' => @site.id, '_csrf_token' => 'abcd' }}
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'site_files' do
|
describe 'site_files' do
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
def app
|
||||||
|
Sinatra::Application
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload(hash)
|
||||||
|
post '/site_files/upload', hash.merge(csrf_token: 'abcd'), {'rack.session' => { 'id' => @site.id, '_csrf_token' => 'abcd' }}
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_file(hash)
|
||||||
|
post '/site_files/delete', hash.merge(csrf_token: 'abcd'), {'rack.session' => { 'id' => @site.id, '_csrf_token' => 'abcd' }}
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@site = Fabricate :site
|
@site = Fabricate :site
|
||||||
ThumbnailWorker.jobs.clear
|
ThumbnailWorker.jobs.clear
|
||||||
|
@ -32,9 +33,10 @@ describe 'site_files' do
|
||||||
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
upload 'files[]' => uploaded_file
|
upload 'files[]' => uploaded_file
|
||||||
|
|
||||||
@site.site_files.last.path.must_equal 'test.jpg'
|
testfile = @site.site_files_dataset.where(path: 'test.jpg').first
|
||||||
@site.site_files.last.rename('derp.jpg')
|
testfile.wont_equal nil
|
||||||
@site.site_files.last.path.must_equal('derp.jpg')
|
testfile.rename 'derp.jpg'
|
||||||
|
@site.site_files_dataset.where(path: 'derp.jpg').first.wont_equal nil
|
||||||
PurgeCacheWorker.jobs.first['args'].last.must_equal '/test.jpg'
|
PurgeCacheWorker.jobs.first['args'].last.must_equal '/test.jpg'
|
||||||
File.exist?(@site.files_path('derp.jpg')).must_equal true
|
File.exist?(@site.files_path('derp.jpg')).must_equal true
|
||||||
end
|
end
|
||||||
|
@ -43,21 +45,25 @@ describe 'site_files' do
|
||||||
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
upload 'files[]' => uploaded_file
|
upload 'files[]' => uploaded_file
|
||||||
|
|
||||||
@site.site_files.last.path.must_equal 'test.jpg'
|
testfile = @site.site_files_dataset.where(path: 'test.jpg').first
|
||||||
res = @site.site_files.last.rename('dasharezone.exe')
|
res = testfile.rename('dasharezone.exe')
|
||||||
res.must_equal [false, 'unsupported file type']
|
res.must_equal [false, 'unsupported file type']
|
||||||
@site.site_files.last.path.must_equal('test.jpg')
|
@site.site_files_dataset.where(path: 'test.jpg').first.wont_equal nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
it 'works for directory' do
|
it 'works for directory' do
|
||||||
@site.create_directory 'dirone'
|
@site.create_directory 'dirone'
|
||||||
@site.site_files.last.path.must_equal 'dirone'
|
@site.site_files.select {|sf| sf.path == 'dirone'}.length.must_equal 1
|
||||||
@site.site_files.last.is_directory.must_equal true
|
|
||||||
res = @site.site_files.last.rename('dasharezone')
|
dirone = @site.site_files_dataset.where(path: 'dirone').first
|
||||||
|
dirone.wont_equal nil
|
||||||
|
dirone.is_directory.must_equal true
|
||||||
|
res = dirone.rename('dasharezone')
|
||||||
res.must_equal [true, nil]
|
res.must_equal [true, nil]
|
||||||
@site.site_files.last.path.must_equal('dasharezone')
|
dasharezone = @site.site_files_dataset.where(path: 'dasharezone').first
|
||||||
@site.site_files.last.is_directory.must_equal true
|
dasharezone.wont_equal nil
|
||||||
|
dasharezone.is_directory.must_equal true
|
||||||
|
|
||||||
PurgeCacheWorker.jobs.first['args'].last.must_equal 'dirone'
|
PurgeCacheWorker.jobs.first['args'].last.must_equal 'dirone'
|
||||||
PurgeCacheWorker.jobs.last['args'].last.must_equal 'dasharezone'
|
PurgeCacheWorker.jobs.last['args'].last.must_equal 'dasharezone'
|
||||||
|
@ -91,14 +97,14 @@ describe 'site_files' do
|
||||||
'files[]' => Rack::Test::UploadedFile.new('./tests/files/index.html', 'image/jpeg')
|
'files[]' => Rack::Test::UploadedFile.new('./tests/files/index.html', 'image/jpeg')
|
||||||
)
|
)
|
||||||
|
|
||||||
res = @site.site_files.last.rename('test/test.jpg')
|
res = @site.site_files_dataset.where(path: 'test/index.html').first.rename('test/test.jpg')
|
||||||
res.must_equal [false, 'file already exists']
|
res.must_equal [false, 'file already exists']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'doesnt wipe out existing dir' do
|
it 'doesnt wipe out existing dir' do
|
||||||
@site.create_directory 'dirone'
|
@site.create_directory 'dirone'
|
||||||
@site.create_directory 'dirtwo'
|
@site.create_directory 'dirtwo'
|
||||||
res = @site.site_files.last.rename 'dirone'
|
res = @site.site_files.select{|sf| sf.path == 'dirtwo'}.first.rename 'dirone'
|
||||||
res.must_equal [false, 'directory already exists']
|
res.must_equal [false, 'directory already exists']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -110,17 +116,17 @@ describe 'site_files' do
|
||||||
it 'works with unicode characters' do
|
it 'works with unicode characters' do
|
||||||
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
upload 'files[]' => uploaded_file
|
upload 'files[]' => uploaded_file
|
||||||
@site.site_files.last.rename("HELL💩؋.jpg")
|
@site.site_files_dataset.where(path: 'test.jpg').first.rename("HELL💩؋.jpg")
|
||||||
@site.site_files.last.path.must_equal "HELL💩؋.jpg"
|
@site.site_files_dataset.where(path: "HELL💩؋.jpg").first.wont_equal nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'scrubs weird carriage return shit characters' do
|
it 'scrubs weird carriage return shit characters' do
|
||||||
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
|
||||||
upload 'files[]' => uploaded_file
|
upload 'files[]' => uploaded_file
|
||||||
proc {
|
proc {
|
||||||
@site.site_files.last.rename("\r\n\t.jpg")
|
@site.site_files_dataset.where(path: 'test.jpg').first.rename("\r\n\t.jpg")
|
||||||
}.must_raise ArgumentError
|
}.must_raise ArgumentError
|
||||||
@site.site_files.last.path.must_equal "test.jpg"
|
@site.site_files_dataset.where(path: 'test.jpg').first.wont_equal nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
require_relative './environment.rb'
|
require_relative './environment.rb'
|
||||||
require 'rack/test'
|
require 'rack/test'
|
||||||
|
|
||||||
include Rack::Test::Methods
|
|
||||||
|
|
||||||
def app
|
|
||||||
Sinatra::Application
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'tipping' do
|
describe 'tipping' do
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
def app
|
||||||
|
Sinatra::Application
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
EmailWorker.jobs.clear
|
EmailWorker.jobs.clear
|
||||||
@site = Fabricate :site
|
@site = Fabricate :site
|
||||||
|
|
Loading…
Add table
Reference in a new issue