Update gems, modernize test stack, fix flaky tests

This commit is contained in:
Kyle Drake 2019-09-21 01:19:47 -07:00
parent e223b687b2
commit 69c32d17ed
14 changed files with 583 additions and 578 deletions

View file

@ -71,13 +71,14 @@ group :test do
gem 'mocha', require: nil
gem 'rake', require: nil
gem 'poltergeist'
gem 'capybara_minitest_spec'
gem 'capybara', require: nil #, '2.10.1', require: nil
gem 'rack_session_access', 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 'mock_redis'
gem 'simplecov', require: nil
gem 'm'
gem 'apparition'
gem 'poltergeist', require: nil
end

View file

@ -15,21 +15,25 @@ GEM
specs:
acme-client (0.6.3)
faraday (~> 0.9, >= 0.9.1)
activesupport (5.2.3)
activesupport (6.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
zeitwerk (~> 2.1, >= 2.1.8)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
annoy (0.5.6)
highline (>= 1.5.0)
ansi (1.5.0)
apparition (0.4.0)
capybara (~> 3.13, < 4)
websocket-driver (>= 0.6.5)
base32 (0.3.2)
bcrypt (3.1.13)
builder (3.2.3)
byebug (11.0.1)
capybara (3.25.0)
capybara (3.29.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
@ -37,9 +41,6 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (~> 1.5)
xpath (~> 3.2)
capybara_minitest_spec (1.0.7)
capybara (>= 2)
minitest (>= 4)
certified (1.0.0)
climate_control (0.2.0)
cliver (0.3.2)
@ -57,21 +58,15 @@ GEM
crass (1.0.4)
dante (0.2.0)
docile (1.3.2)
domain_name (0.5.20180417)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
drydock (0.6.9)
equatable (0.6.1)
erubis (2.7.0)
exifr (1.3.6)
fabrication (2.20.2)
facter (2.5.1)
faker (1.9.4)
i18n (>= 0.7)
pastel (~> 0.7.2)
thor (~> 0.20.0)
tty-pager (~> 0.12.0)
tty-screen (~> 0.6.5)
tty-tree (~> 0.3.0)
facter (2.5.6)
faker (2.4.0)
i18n (~> 1.6.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday_middleware (0.13.1)
@ -83,12 +78,12 @@ GEM
sax-machine (>= 1.0)
ffi (1.11.1)
filesize (0.2.0)
fspath (3.1.1)
fspath (3.1.2)
gandi (3.3.28)
hashie
xmlrpc
geoip (1.6.4)
hashdiff (0.4.0)
hashdiff (1.0.0)
hashie (3.6.0)
highline (2.0.2)
hiredis (0.6.3)
@ -100,23 +95,24 @@ GEM
http-cookie (~> 1.0)
http-form_data (~> 2.0)
http_parser.rb (~> 0.6.0)
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
http-form_data (2.1.1)
http_parser.rb (0.6.0)
i18n (1.6.0)
concurrent-ruby (~> 1.0)
image_optim (0.26.4)
image_optim (0.26.5)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
image_size (>= 1.5, < 3)
in_threads (~> 1.3)
progress (~> 3.0, >= 3.0.1)
image_optim_pack (0.5.3)
image_optim_pack (0.6.0)
fspath (>= 2.1, < 4)
image_optim (~> 0.19)
image_size (2.0.1)
in_threads (1.5.2)
image_size (2.0.2)
in_threads (1.5.3)
io-extra (1.3.0)
ipaddress (0.8.3)
json (2.2.0)
@ -132,13 +128,13 @@ GEM
mini_mime (>= 0.1.1)
metaclass (0.0.4)
method_source (0.9.2)
mime-types (3.2.2)
mime-types (3.3)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_mime (1.0.1)
mime-types-data (3.2019.0904)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.11.3)
minitest-reporters (1.3.6)
minitest-reporters (1.3.8)
ansi
builder
minitest (>= 5.0)
@ -146,15 +142,15 @@ GEM
mocha (1.9.0)
metaclass (~> 0.0.1)
mock_redis (0.21.0)
monetize (1.9.1)
monetize (1.9.2)
money (~> 6.12)
money (6.13.4)
i18n (>= 0.6.4, <= 2)
msgpack (1.3.0)
msgpack (1.3.1)
multi_json (1.13.1)
multipart-post (2.1.1)
mustermann (1.0.3)
net-http-persistent (3.0.1)
net-http-persistent (3.1.0)
connection_pool (~> 2.2)
net-scp (2.0.0)
net-ssh (>= 2.6.5, < 6.0.0)
@ -166,24 +162,21 @@ GEM
nokogumbo (2.0.1)
nokogiri (~> 1.8, >= 1.8.4)
ox (2.11.0)
pastel (0.7.3)
equatable (~> 0.6)
tty-color (~> 0.5)
paypal-recurring (1.1.0)
pg (1.1.4)
poltergeist (1.18.1)
capybara (>= 2.1, < 4)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
progress (3.5.1)
progress (3.5.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-byebug (3.7.0)
byebug (~> 11.0)
pry (~> 0.10)
public_suffix (3.1.1)
puma (4.1.0)
public_suffix (4.0.1)
puma (4.1.1)
nio4r (~> 2.0)
rack (2.0.7)
rack-cache (1.9.0)
@ -202,13 +195,14 @@ GEM
redis (3.3.5)
redis-namespace (1.6.0)
redis (>= 3.0.4)
regexp_parser (1.5.1)
rest-client (2.0.2)
regexp_parser (1.6.0)
rest-client (2.1.0)
http-accept (>= 1.7.0, < 2.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rinku (2.0.6)
rmagick (3.2.0)
rmagick (4.0.0)
ruby-progressbar (1.10.1)
rye (0.9.13)
annoy
@ -218,7 +212,7 @@ GEM
net-ssh (>= 2.0.13)
sysinfo (>= 0.8.1)
safe_yaml (1.0.5)
sanitize (5.0.0)
sanitize (5.1.0)
crass (~> 1.0.2)
nokogiri (>= 1.8.0)
nokogumbo (~> 2.0)
@ -228,7 +222,7 @@ GEM
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sax-machine (1.3.2)
sequel (5.22.0)
sequel (5.24.0)
sequel_pg (1.12.2)
pg (>= 0.18.0)
sequel (>= 4.38.0)
@ -256,15 +250,10 @@ GEM
sinatra-xsendfile (0.4.2)
sinatra (>= 0.9.1)
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)
faraday (~> 0.13)
net-http-persistent (~> 3.0)
stripe-ruby-mock (2.5.6)
stripe-ruby-mock (2.5.8)
dante (>= 0.2.0)
multi_json (~> 1.0)
stripe (>= 2.0.3)
@ -280,22 +269,12 @@ GEM
thread_safe (0.3.6)
tilt (2.0.9)
timecop (0.9.1)
tins (1.20.3)
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)
tins (1.21.1)
tzinfo (1.2.5)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.6.0)
unicode_utils (1.4.0)
uuidtools (2.1.5)
webmock (3.5.1)
addressable (>= 2.3.6)
@ -304,10 +283,11 @@ GEM
websocket-driver (0.7.1)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4)
will_paginate (3.1.7)
will_paginate (3.1.8)
xmlrpc (0.3.0)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.1.10)
zipruby (0.3.6)
PLATFORMS
@ -317,10 +297,10 @@ DEPENDENCIES
acme-client (= 0.6.3)
activesupport
addressable
apparition
base32
bcrypt
capybara
capybara_minitest_spec
certified
coveralls
dav4rack!
@ -377,7 +357,7 @@ DEPENDENCIES
sinatra-flash
sinatra-xsendfile
stripe (= 4.2.0)
stripe-ruby-mock (= 2.5.6)
stripe-ruby-mock (= 2.5.8)
terrapin
thread
tilt

View file

@ -69,7 +69,7 @@ post '/create' do
return {result: 'error'}.to_json
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.'
return {result: 'error'}.to_json
end
@ -78,6 +78,11 @@ post '/create' do
flash[:error] = 'Cannot use a disposable email address.'
return {result: 'error'}.to_json
end
if !@site.valid?
flash[:error] = @site.errors.first.last.first
return {result: 'error'}.to_json
end
end
@site.email_confirmed = true if self.class.development?

View file

@ -105,7 +105,7 @@ Sequel::Model.plugin :validation_helpers
Sequel::Model.plugin :force_encoding, 'UTF-8'
Sequel::Model.plugin :defaults_setter
Sequel::Model.plugin :create_timestamp
Sequel.default_timezone = 'UTC'
Sequel.default_timezone = :utc
Sequel::Migrator.apply DB, './migrations'
Stripe.api_key = $config['stripe_api_key']

View file

@ -324,7 +324,7 @@ class Site < Sequel::Model
return false if ip.blank?
return true if Site.where(is_banned: true).
where(ip: ip).
where(['updated_at > ?', Time.now-BANNED_TIME]).
where(['banned_at > ?', Time.now-BANNED_TIME]).
first
return true if BlockedIp[ip]

View file

@ -51,4 +51,56 @@ describe '/admin' do
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

View file

@ -1,9 +1,5 @@
require_relative './environment.rb'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
describe 'signup' do
include Capybara::DSL
@ -17,7 +13,7 @@ describe 'signup' do
end
before do
Capybara.default_driver = :poltergeist
Capybara.default_driver = :apparition
Capybara.reset_sessions!
visit '/education'
page.must_have_content 'Neocities' # Used to force load wait

View file

@ -1,5 +1,30 @@
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/dsl'
require 'capybara/poltergeist'
@ -10,3 +35,4 @@ Capybara.app = Sinatra::Application
def teardown
Capybara.reset_sessions!
end
=end

View file

@ -1,9 +1,5 @@
require_relative './environment.rb'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
describe 'signup' do
include Capybara::DSL
@ -28,10 +24,9 @@ describe 'signup' do
end
before do
Capybara.default_driver = :poltergeist
Capybara.default_driver = :apparition
Capybara.reset_sessions!
visit_signup
page.must_have_content 'Neocities' # Used to force load wait
end
after do
@ -65,15 +60,15 @@ describe 'signup' do
end
it 'fails if site with same ip has been banned' do
@banned_site = Fabricate :site
@banned_site.is_banned = true
@banned_site.save_changes
@banned_site = Fabricate :site, ip: '127.0.0.1'
@banned_site.ban!
fill_in_valid
click_signup_button
site = Site[username: @site[:username]]
Site[username: @site[:username]].must_be_nil
current_path.must_equal '/'
page.wont_have_content 'Welcome to Neocities'
@banned_site.update ip: nil
end
it 'fails if IP is banned from blocked ips list' do

View file

@ -1,14 +1,10 @@
require_relative './environment.rb'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: false)
end
describe '/supporter' do
include Capybara::DSL
before do
Capybara.default_driver = :poltergeist
Capybara.default_driver = :apparition
Capybara.reset_sessions!
@site = Fabricate :site
@ -33,14 +29,16 @@ describe '/supporter' do
it 'should work for fresh signup' do
visit '/supporter'
find('#cc_number', visible: false).set '4242424242424242'
find('#cc_exp_month', visible: false).set '01'
find('#cc_exp_year', visible: false).set Date.today.next_year.year.to_s[2..3]
find('#cc_name', visible: false).set 'Penelope'
find('#cc_cvc', visible: false).set '123'
find('#stripe_token', visible: false).set @stripe_helper.generate_card_token
find('.cc-number input[type=text]').set '4242424242424242'
all('.cc-exp input[type=text]').first.set '01'
all('.cc-exp input[type=text]').last.set Date.today.next_year.year.to_s[2..3]
find('.cc-name').set 'Penelope'
all('.flip-tab').first.click
find('.cc-cvc').set '123'
page.evaluate_script("document.getElementById('stripe_token').value = '#{@stripe_helper.generate_card_token}'")
click_link 'Upgrade for $5/mo'
page.current_path.must_equal '/supporter/thanks'
all('.txt-Center')
page.body.must_match /You have become a Neocities Supporter/
@site.reload
@site.stripe_customer_id.wont_be_nil

View file

@ -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

View file

@ -1,320 +1,329 @@
require_relative './environment.rb'
require 'rack/test'
include Rack::Test::Methods
describe 'api' do
include Rack::Test::Methods
def app
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'
def app
Sinatra::Application
end
end
describe 'api list' do
it 'returns all files without path' do
create_site
basic_authorize @user, @pass
get '/api/list'
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
res[:result].must_equal 'success'
res[:files].length.must_equal @site.site_files.length
def site_file_exists?(file)
File.exist?(@site.files_path(file))
end
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]
def res
JSON.parse last_response.body, symbolize_names: true
end
describe '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
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 []
describe 'list' do
it 'returns all files without path' do
create_site
basic_authorize @user, @pass
get '/api/list'
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
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
describe 'info' do
it 'fails for no input' do
get '/api/info'
res[:error_type] = 'missing_sitename'
end
describe 'api info' do
it 'fails for no input' do
get '/api/info'
res[:error_type] = 'missing_sitename'
it 'fails for banned sites' do
create_site
@site.update is_banned: true
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
it 'fails for banned sites' do
create_site
@site.update is_banned: true
get '/api/info', sitename: @site.username
res[:error_type].must_equal 'site_not_found'
@site.reload.api_calls.must_equal 0
describe 'delete' do
it 'fails with no or bad auth' do
post '/api/delete', filenames: ['hi.html']
res[:error_type].must_equal 'invalid_auth'
create_site
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
it 'fails for nonexistent site' do
get '/api/info', sitename: 'notexist'
res[:error_type].must_equal 'site_not_found'
describe '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
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
describe '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
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
describe '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
it 'fails for bad auth' do
basic_authorize 'derp', 'fake'
get '/api/info'
res[:error_type].must_equal 'invalid_auth'
end
describe '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 'succeeds for api auth' do
create_site
@site.update hits: 12345
basic_authorize @user, @pass
get '/api/info'
res[:info][:hits] == 12345
end
end
it 'fails for bad auth' do
basic_authorize 'username', 'password'
post '/api/upload'
res[:error_type].must_equal 'invalid_auth'
end
describe 'api delete' do
it 'fails with no or bad auth' do
post '/api/delete', filenames: ['hi.html']
res[:error_type].must_equal 'invalid_auth'
create_site
basic_authorize 'derp', 'fake'
post '/api/delete', filenames: ['hi.html']
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 'fails with missing filename argument' do
create_site
basic_authorize @user, @pass
post '/api/delete'
res[:error_type].must_equal 'missing_filenames'
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 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
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
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
# Getting too slow to run this test
@ -332,125 +341,118 @@ describe 'api upload' do
end
=end
it 'resists directory traversal attack' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'../lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
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
@site.reload.api_calls.must_equal 1
end
it 'resists directory traversal attack' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'../lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
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
@site.reload.api_calls.must_equal 1
end
it 'scrubs root path slash' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
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
end
it 'scrubs root path slash' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
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
end
it 'fails for missing file name' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'/' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
res[:error_type].must_equal 'invalid_file_type'
end
it 'fails for missing file name' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'/' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
res[:error_type].must_equal 'invalid_file_type'
end
it 'fails for file with no extension' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'derpie' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
res[:error_type].must_equal 'invalid_file_type'
end
it 'fails for file with no extension' do
create_site
basic_authorize @user, @pass
post '/api/upload', {
'derpie' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
res[:error_type].must_equal 'invalid_file_type'
end
it 'creates path for file uploads' do
create_site
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 {
it 'creates path for file uploads' do
create_site
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
@site.reload.api_calls.must_equal 2
end
it 'records api calls that require auth' do
create_site
basic_authorize @user, @pass
it 'fails for invalid files' do
create_site
basic_authorize @user, @pass
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
2.times {
post '/api/upload', {
'derpie/derpingtons/lol.jpg' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
}
}
it 'succeeds with single file' do
create_site
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
@site.reload.api_calls.must_equal 2
end
it 'succeeds with two files' do
create_site
basic_authorize @user, @pass
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 for invalid files' do
create_site
basic_authorize @user, @pass
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 'fails with unwhitelisted file' do
create_site
basic_authorize @user, @pass
post '/api/upload', 'flowercrime.wav' => Rack::Test::UploadedFile.new('./tests/files/flowercrime.wav', 'audio/x-wav')
res[:result].must_equal 'error'
res[:error_type].must_equal 'invalid_file_type'
site_file_exists?('flowercrime.wav').must_equal false
end
it 'succeeds with single file' do
create_site
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 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
it 'succeeds with two files' do
create_site
basic_authorize @user, @pass
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
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
res[:result].must_equal 'error'
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
def site_file_exists?(file)
File.exist?(@site.files_path(file))
end
def res
JSON.parse last_response.body, symbolize_names: true
end

View file

@ -1,20 +1,21 @@
require_relative './environment.rb'
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
require 'rack/test'
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
@site = Fabricate :site
ThumbnailWorker.jobs.clear
@ -32,9 +33,10 @@ describe 'site_files' do
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
upload 'files[]' => uploaded_file
@site.site_files.last.path.must_equal 'test.jpg'
@site.site_files.last.rename('derp.jpg')
@site.site_files.last.path.must_equal('derp.jpg')
testfile = @site.site_files_dataset.where(path: 'test.jpg').first
testfile.wont_equal nil
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'
File.exist?(@site.files_path('derp.jpg')).must_equal true
end
@ -43,21 +45,25 @@ describe 'site_files' do
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
upload 'files[]' => uploaded_file
@site.site_files.last.path.must_equal 'test.jpg'
res = @site.site_files.last.rename('dasharezone.exe')
testfile = @site.site_files_dataset.where(path: 'test.jpg').first
res = testfile.rename('dasharezone.exe')
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
it 'works for directory' do
@site.create_directory 'dirone'
@site.site_files.last.path.must_equal 'dirone'
@site.site_files.last.is_directory.must_equal true
res = @site.site_files.last.rename('dasharezone')
@site.site_files.select {|sf| sf.path == 'dirone'}.length.must_equal 1
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]
@site.site_files.last.path.must_equal('dasharezone')
@site.site_files.last.is_directory.must_equal true
dasharezone = @site.site_files_dataset.where(path: 'dasharezone').first
dasharezone.wont_equal nil
dasharezone.is_directory.must_equal true
PurgeCacheWorker.jobs.first['args'].last.must_equal 'dirone'
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')
)
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']
end
it 'doesnt wipe out existing dir' do
@site.create_directory 'dirone'
@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']
end
@ -110,17 +116,17 @@ describe 'site_files' do
it 'works with unicode characters' do
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
upload 'files[]' => uploaded_file
@site.site_files.last.rename("HELL💩؋.jpg")
@site.site_files.last.path.must_equal "HELL💩؋.jpg"
@site.site_files_dataset.where(path: 'test.jpg').first.rename("HELL💩؋.jpg")
@site.site_files_dataset.where(path: "HELL💩؋.jpg").first.wont_equal nil
end
it 'scrubs weird carriage return shit characters' do
uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg')
upload 'files[]' => uploaded_file
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
@site.site_files.last.path.must_equal "test.jpg"
@site.site_files_dataset.where(path: 'test.jpg').first.wont_equal nil
end
end

View file

@ -1,13 +1,13 @@
require_relative './environment.rb'
require 'rack/test'
include Rack::Test::Methods
def app
Sinatra::Application
end
describe 'tipping' do
include Rack::Test::Methods
def app
Sinatra::Application
end
before do
EmailWorker.jobs.clear
@site = Fabricate :site