require_relative 'test_helper' class FilesAdminTest < Minitest::Test include Rack::Test::Methods include AdminLogin def app AsxpioWeb end def setup skip 'TEST_DATABASE_URL not set' unless TestDb.available? TestDb.clean_users! DB.connection[:public_files].delete DB.connection[:audit_log].delete ENV['PUBLIC_S3_BUCKET'] = 'public' ENV['PUBLIC_BASE_URL'] = 'https://s3.example/public' end def teardown %w[PUBLIC_S3_BUCKET PUBLIC_BASE_URL PUBLIC_MAX_MB PUBLIC_QUOTA_MB].each { |k| ENV.delete(k) } end def token get '/admin/files' last_response.body[/name="authenticity_token" value="([^"]+)"/, 1] || (get('/admin'); last_response.body[/name="authenticity_token" value="([^"]+)"/, 1]) end def upload(name, data = 'hello') Rack::Test::UploadedFile.new(StringIO.new(data), 'application/octet-stream', true, original_filename: name) end # Runs the block with S3 puts and deletes recorded instead of sent. def recording puts_to, deleted = [], [] S3.client.stub(:put_object, ->(**o) { puts_to << o }) do S3.client.stub(:delete_object, ->(**o) { deleted << o }) { yield puts_to, deleted } end end def as(flags) u = User.create(username: 'user1', password: 'user-password-1') UserPermission.create(user_id: u.id, area: 'files', **flags.to_h { |f| [:"can_#{f}", true] }) admin_login!(username: 'user1', password: 'user-password-1') end def test_clean_name assert_equal 'My-report-v2.pdf', PublicFile.clean_name('C:\\tmp\\My report (v2).PDF') assert_equal 'passwd', PublicFile.clean_name('../../etc/passwd') assert_equal 'file.png', PublicFile.clean_name('отчёт.png') assert_equal 'file', PublicFile.clean_name('') end def test_publish_inline_and_download admin_login! recording do |puts_to, _| post '/admin/files', { authenticity_token: token, note: 'for the client', files: [upload('Spec sheet.pdf', '%PDF-1.4'), upload('page.html', ''), upload('logo.svg', '')] } assert last_response.redirect? pdf, html, svg = puts_to assert_equal %w[public public public], puts_to.map { |o| o[:bucket] } assert_match %r{\A[0-9a-f]{8}/Spec-sheet\.pdf\z}, pdf[:key] assert_equal ['application/pdf', 'inline'], pdf.values_at(:content_type, :content_disposition) [html, svg].each do |o| assert_equal 'application/octet-stream', o[:content_type] assert_match(/\Aattachment; filename=/, o[:content_disposition]) end end row = PublicFile.first(filename: 'Spec-sheet.pdf') assert_equal [8, true, 'for the client', ENV['ADMIN_USER']], [row.size, row.inline, row.note, row.uploaded_by] assert_equal Digest::SHA256.hexdigest('%PDF-1.4'), row.sha256 assert_equal "https://s3.example/public/#{row.key}", row.url get '/admin/files' assert_includes last_response.body, row.url assert_equal 3, DB.connection[:audit_log].where(action: 'files.upload').count get '/admin' assert_includes last_response.body, '