diff --git a/Gemfile b/Gemfile index 8a731f6c..ac50d369 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index b5f6c307..a69a5bb0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/create.rb b/app/create.rb index 9609d557..094b64a0 100644 --- a/app/create.rb +++ b/app/create.rb @@ -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? diff --git a/environment.rb b/environment.rb index 80c979e5..efc87e11 100644 --- a/environment.rb +++ b/environment.rb @@ -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'] diff --git a/models/site.rb b/models/site.rb index 8e0cadfe..14e3ad47 100644 --- a/models/site.rb +++ b/models/site.rb @@ -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] diff --git a/tests/acceptance/admin_tests.rb b/tests/acceptance/admin_tests.rb index 32698e2d..62a3ebe5 100644 --- a/tests/acceptance/admin_tests.rb +++ b/tests/acceptance/admin_tests.rb @@ -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 ' + 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 diff --git a/tests/acceptance/education_tests.rb b/tests/acceptance/education_tests.rb index c3bcdaed..3ab5678d 100644 --- a/tests/acceptance/education_tests.rb +++ b/tests/acceptance/education_tests.rb @@ -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 diff --git a/tests/acceptance/environment.rb b/tests/acceptance/environment.rb index c8154237..3aac7259 100644 --- a/tests/acceptance/environment.rb +++ b/tests/acceptance/environment.rb @@ -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 diff --git a/tests/acceptance/signup_tests.rb b/tests/acceptance/signup_tests.rb index 154ff899..14ad4cc5 100644 --- a/tests/acceptance/signup_tests.rb +++ b/tests/acceptance/signup_tests.rb @@ -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 diff --git a/tests/acceptance/supporter_tests.rb b/tests/acceptance/supporter_tests.rb index 949c4b21..1b456acb 100644 --- a/tests/acceptance/supporter_tests.rb +++ b/tests/acceptance/supporter_tests.rb @@ -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 diff --git a/tests/admin_tests.rb b/tests/admin_tests.rb deleted file mode 100644 index fff3ee02..00000000 --- a/tests/admin_tests.rb +++ /dev/null @@ -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 ' - 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 diff --git a/tests/api_tests.rb b/tests/api_tests.rb index 462eb91d..0f40adf2 100644 --- a/tests/api_tests.rb +++ b/tests/api_tests.rb @@ -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 diff --git a/tests/site_file_tests.rb b/tests/site_file_tests.rb index f8d1dbf0..a44d567d 100644 --- a/tests/site_file_tests.rb +++ b/tests/site_file_tests.rb @@ -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 diff --git a/tests/webhook_tests.rb b/tests/webhook_tests.rb index 36fce9b1..4c88fea2 100644 --- a/tests/webhook_tests.rb +++ b/tests/webhook_tests.rb @@ -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