REFACTOR: uploads controller specs to requests (#5907)

This commit is contained in:
OsamaSayegh 2018-06-04 06:13:52 +03:00 committed by Guo Xiang Tan
parent cfea837e88
commit e58ed247f2
2 changed files with 87 additions and 95 deletions

BIN
spec/fixtures/images/image_no_extension vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,17 +1,14 @@
require 'rails_helper' require 'rails_helper'
describe UploadsController do describe UploadsController do
describe '#create' do
context '.create' do
it 'requires you to be logged in' do it 'requires you to be logged in' do
post :create, format: :json post "/uploads.json"
expect(response.status).to eq(403) expect(response.status).to eq(403)
end end
context 'logged in' do context 'logged in' do
let!(:user) { sign_in(Fabricate(:user)) }
before { @user = log_in :user }
let(:logo) do let(:logo) do
Rack::Test::UploadedFile.new(file_from_fixtures("logo.png")) Rack::Test::UploadedFile.new(file_from_fixtures("logo.png"))
@ -26,151 +23,132 @@ describe UploadsController do
end end
it 'expects a type' do it 'expects a type' do
expect do post "/uploads.json", params: { file: logo }
post :create, params: { format: :json, file: logo } expect(response.status).to eq(400)
end.to raise_error(ActionController::ParameterMissing)
end
it 'can look up long urls' do
upload = Fabricate(:upload)
post :lookup_urls, params: { short_urls: [upload.short_url], format: :json }
result = JSON.parse(response.body)
expect(result[0]["url"]).to eq(upload.url)
end end
it 'is successful with an image' do it 'is successful with an image' do
Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything) post "/uploads.json", params: { file: logo, type: "avatar" }
post :create, params: { file: logo, type: "avatar", format: :json }
expect(response.status).to eq 200 expect(response.status).to eq 200
expect(JSON.parse(response.body)["id"]).to be expect(JSON.parse(response.body)["id"]).to be_present
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(1)
end end
it 'is successful with an attachment' do it 'is successful with an attachment' do
SiteSetting.authorized_extensions = "*" SiteSetting.authorized_extensions = "*"
Jobs.expects(:enqueue).never post "/uploads.json", params: { file: text_file, type: "composer" }
post :create, params: { file: text_file, type: "composer", format: :json }
expect(response.status).to eq 200 expect(response.status).to eq 200
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(0)
id = JSON.parse(response.body)["id"] id = JSON.parse(response.body)["id"]
expect(id).to be expect(id).to be
end end
it 'is successful with api' do it 'is successful with api' do
SiteSetting.authorized_extensions = "*" SiteSetting.authorized_extensions = "*"
controller.stubs(:is_api?).returns(true) api_key = Fabricate(:api_key, user: user).key
FinalDestination.stubs(:lookup_ip).returns("1.2.3.4")
Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything)
url = "http://example.com/image.png" url = "http://example.com/image.png"
png = File.read(Rails.root + "spec/fixtures/images/logo.png") png = File.read(Rails.root + "spec/fixtures/images/logo.png")
stub_request(:get, url).to_return(status: 200, body: png) stub_request(:get, url).to_return(status: 200, body: png)
post :create, params: { url: url, type: "avatar", format: :json } post "/uploads.json", params: { url: url, type: "avatar", api_key: api_key, api_username: user.username }
json = ::JSON.parse(response.body) json = ::JSON.parse(response.body)
expect(response.status).to eq 200 expect(response.status).to eq(200)
expect(json["id"]).to be expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(1)
expect(json["id"]).to be_present
expect(json["short_url"]).to eq("upload://qUm0DGR49PAZshIi7HxMd3cAlzn.png") expect(json["short_url"]).to eq("upload://qUm0DGR49PAZshIi7HxMd3cAlzn.png")
end end
it 'correctly sets retain_hours for admins' do it 'correctly sets retain_hours for admins' do
log_in :admin sign_in(Fabricate(:admin))
Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything).never
post :create, params: { post "/uploads.json", params: {
file: logo, file: logo,
retain_hours: 100, retain_hours: 100,
type: "profile_background", type: "profile_background",
format: :json
} }
id = JSON.parse(response.body)["id"] id = JSON.parse(response.body)["id"]
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(0)
expect(Upload.find(id).retain_hours).to eq(100) expect(Upload.find(id).retain_hours).to eq(100)
end end
it 'requires a file' do it 'requires a file' do
Jobs.expects(:enqueue).never post "/uploads.json", params: { type: "composer" }
post :create, params: { type: "composer", format: :json }
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(0)
message = JSON.parse(response.body) message = JSON.parse(response.body)
expect(response.status).to eq 422 expect(response.status).to eq 422
expect(message["errors"]).to contain_exactly(I18n.t("upload.file_missing")) expect(message["errors"]).to contain_exactly(I18n.t("upload.file_missing"))
end end
it 'properly returns errors' do it 'properly returns errors' do
SiteSetting.authorized_extensions = "*"
SiteSetting.max_attachment_size_kb = 1 SiteSetting.max_attachment_size_kb = 1
Jobs.expects(:enqueue).never post "/uploads.json", params: { file: text_file, type: "avatar" }
post :create, params: { file: text_file, type: "avatar", format: :json } expect(response.status).to eq(422)
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(0)
expect(response.status).to eq 422
errors = JSON.parse(response.body)["errors"] errors = JSON.parse(response.body)["errors"]
expect(errors).to be expect(errors.first).to eq(I18n.t("upload.attachments.too_large", max_size_kb: 1))
end end
it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do
SiteSetting.allow_uploaded_avatars = false SiteSetting.allow_uploaded_avatars = false
post :create, params: { file: logo, type: "avatar", format: :json } post "/uploads.json", params: { file: logo, type: "avatar" }
expect(response).to_not be_success expect(response.status).to eq(422)
end end
it 'ensures sso_overrides_avatar is not enabled when uploading an avatar' do it 'ensures sso_overrides_avatar is not enabled when uploading an avatar' do
SiteSetting.sso_overrides_avatar = true SiteSetting.sso_overrides_avatar = true
post :create, params: { file: logo, type: "avatar", format: :json } post "/uploads.json", params: { file: logo, type: "avatar" }
expect(response).to_not be_success expect(response.status).to eq(422)
end end
it 'allows staff to upload any file in PM' do it 'allows staff to upload any file in PM' do
SiteSetting.authorized_extensions = "jpg" SiteSetting.authorized_extensions = "jpg"
SiteSetting.allow_staff_to_upload_any_file_in_pm = true SiteSetting.allow_staff_to_upload_any_file_in_pm = true
@user.update_columns(moderator: true) user.update_columns(moderator: true)
post :create, params: { post "/uploads.json", params: {
file: text_file, file: text_file,
type: "composer", type: "composer",
for_private_message: "true", for_private_message: "true",
format: :json
} }
expect(response).to be_success expect(response).to be_success
id = JSON.parse(response.body)["id"] id = JSON.parse(response.body)["id"]
expect(id).to be expect(id).to be_present
end end
it 'respects `authorized_extensions_for_staff` setting when staff upload file' do it 'respects `authorized_extensions_for_staff` setting when staff upload file' do
SiteSetting.authorized_extensions = "" SiteSetting.authorized_extensions = ""
SiteSetting.authorized_extensions_for_staff = "*" SiteSetting.authorized_extensions_for_staff = "*"
@user.update_columns(moderator: true) user.update_columns(moderator: true)
post :create, params: { post "/uploads.json", params: {
file: text_file, file: text_file,
type: "composer", type: "composer",
format: :json
} }
expect(response).to be_success expect(response).to be_success
data = JSON.parse(response.body) data = JSON.parse(response.body)
expect(data["id"]).to be expect(data["id"]).to be_present
end end
it 'ignores `authorized_extensions_for_staff` setting when non-staff upload file' do it 'ignores `authorized_extensions_for_staff` setting when non-staff upload file' do
SiteSetting.authorized_extensions = "" SiteSetting.authorized_extensions = ""
SiteSetting.authorized_extensions_for_staff = "*" SiteSetting.authorized_extensions_for_staff = "*"
post :create, params: { post "/uploads.json", params: {
file: text_file, file: text_file,
type: "composer", type: "composer",
format: :json
} }
data = JSON.parse(response.body) data = JSON.parse(response.body)
@ -178,73 +156,87 @@ describe UploadsController do
end end
it 'returns an error when it could not determine the dimensions of an image' do it 'returns an error when it could not determine the dimensions of an image' do
Jobs.expects(:enqueue).with(:create_avatar_thumbnails, anything).never post "/uploads.json", params: { file: fake_jpg, type: "composer" }
post :create, params: { file: fake_jpg, type: "composer", format: :json } expect(response.status).to eq(422)
expect(Jobs::CreateAvatarThumbnails.jobs.size).to eq(0)
expect(response.status).to eq 422
message = JSON.parse(response.body)["errors"] message = JSON.parse(response.body)["errors"]
expect(message).to contain_exactly(I18n.t("upload.images.size_not_found")) expect(message).to contain_exactly(I18n.t("upload.images.size_not_found"))
end end
end end
end end
context '.show' do describe '#show' do
let(:site) { "default" } let(:site) { "default" }
let(:sha) { Digest::SHA1.hexdigest("discourse") } let(:sha) { Digest::SHA1.hexdigest("discourse") }
let(:user) { Fabricate(:user) }
def upload_file(file)
fake_logo = Rack::Test::UploadedFile.new(file_from_fixtures(file))
SiteSetting.authorized_extensions = "*"
sign_in(user)
post "/uploads.json", params: {
file: fake_logo,
type: "composer",
}
url = JSON.parse(response.body)["url"]
upload = Upload.where(url: url).first
upload
end
it "returns 404 when using external storage" do it "returns 404 when using external storage" do
store = stub(internal?: false) SiteSetting.enable_s3_uploads = true
Discourse.stubs(:store).returns(store) SiteSetting.s3_access_key_id = "fakeid7974664"
Upload.expects(:find_by).never SiteSetting.s3_secret_access_key = "fakesecretid7974664"
get :show, params: { site: site, sha: sha, extension: "pdf" } get "/uploads/#{site}/#{sha}.pdf"
expect(response.response_code).to eq(404) expect(response.response_code).to eq(404)
end end
it "returns 404 when the upload doesn't exist" do it "returns 404 when the upload doesn't exist" do
Upload.stubs(:find_by).returns(nil) get "/uploads/#{site}/#{sha}.pdf"
expect(response.status).to eq(404)
get :show, params: { site: site, sha: sha, extension: "pdf" }
expect(response.response_code).to eq(404)
end end
it 'uses send_file' do it 'uses send_file' do
upload = build(:upload) upload = upload_file("logo.png")
Upload.expects(:find_by).with(sha1: sha).returns(upload) get "/uploads/#{site}/#{upload.sha1}.#{upload.extension}"
expect(response.status).to eq(200)
controller.stubs(:render) expect(response.headers["Content-Disposition"]).to eq("attachment; filename=\"logo.png\"")
controller.expects(:send_file)
get :show, params: { site: site, sha: sha, extension: "zip" }
end end
it "handles file without extension" do it "handles file without extension" do
SiteSetting.authorized_extensions = "*" SiteSetting.authorized_extensions = "*"
Fabricate(:upload, original_filename: "image_file", sha1: sha) upload = upload_file("image_no_extension")
controller.stubs(:render)
controller.expects(:send_file)
get :show, params: { site: site, sha: sha, format: :json } get "/uploads/#{site}/#{upload.sha1}.json"
expect(response).to be_success expect(response.status).to eq(200)
expect(response.headers["Content-Disposition"]).to eq("attachment; filename=\"image_no_extension\"")
end end
context "prevent anons from downloading files" do context "prevent anons from downloading files" do
before { SiteSetting.prevent_anons_from_downloading_files = true }
it "returns 404 when an anonymous user tries to download a file" do it "returns 404 when an anonymous user tries to download a file" do
Upload.expects(:find_by).never upload = upload_file("logo.png")
delete "/session/#{user.username}.json" # upload a file, then sign out
get :show, params: { site: site, sha: sha, extension: "pdf", format: :json } SiteSetting.prevent_anons_from_downloading_files = true
expect(response.response_code).to eq(404) get "/uploads/#{site}/#{upload.sha1}.#{upload.extension}"
expect(response.status).to eq(404)
end end
end end
end end
describe '#lookup_urls' do
it 'can look up long urls' do
sign_in(Fabricate(:user))
upload = Fabricate(:upload)
post "/uploads/lookup-urls.json", params: { short_urls: [upload.short_url] }
expect(response.status).to eq(200)
result = JSON.parse(response.body)
expect(result[0]["url"]).to eq(upload.url)
end
end
end end