Perform the replacement in a before_create callback so that it runs in a transaction and if it fails, the transaction will rollback and the replacement record won't be created. Doing the replacement in a transaction isn't great because, for one thing, it could hold the transaction open a long time, which isn't good for the database. And two, if the transaction rolls back, the database changes will be undone, but if the replacement file has already been saved to disk, then it won't be undone, which could result in a dangling file.
226 lines
8.7 KiB
Ruby
226 lines
8.7 KiB
Ruby
require 'test_helper'
|
|
|
|
class PostReplacementsControllerTest < ActionDispatch::IntegrationTest
|
|
context "The post replacements controller" do
|
|
context "create action" do
|
|
context "replacing a post from a source url" do
|
|
should "replace the post" do
|
|
assert_difference("PostReplacement.count") do
|
|
@post = create(:post)
|
|
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_url: "https://cdn.donmai.us/original/d3/4e/d34e4cf0a437a5d65f8e82b7bcd02606.jpg",
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
end
|
|
|
|
@replacement = PostReplacement.last
|
|
assert_equal(459, @replacement.image_width)
|
|
assert_equal(650, @replacement.image_height)
|
|
assert_equal(127_238, @replacement.file_size)
|
|
assert_equal("jpg", @replacement.file_ext)
|
|
assert_equal("d34e4cf0a437a5d65f8e82b7bcd02606", @replacement.md5)
|
|
|
|
assert_equal(@post.image_width, @replacement.old_image_width)
|
|
assert_equal(@post.image_height, @replacement.old_image_height)
|
|
assert_equal(@post.file_size, @replacement.old_file_size)
|
|
assert_equal(@post.file_ext, @replacement.old_file_ext)
|
|
assert_equal(@post.md5, @replacement.old_md5)
|
|
|
|
@post.reload
|
|
assert_equal("d34e4cf0a437a5d65f8e82b7bcd02606", @post.md5)
|
|
assert_equal("d34e4cf0a437a5d65f8e82b7bcd02606", @post.media_asset.variant(:original).open_file.md5)
|
|
assert_equal("https://cdn.donmai.us/original/d3/4e/d34e4cf0a437a5d65f8e82b7bcd02606.jpg", @post.source)
|
|
assert_equal(459, @post.image_width)
|
|
assert_equal(650, @post.image_height)
|
|
assert_equal(127_238, @post.file_size)
|
|
assert_equal("jpg", @post.file_ext)
|
|
end
|
|
end
|
|
|
|
context "replacing a post with the same file" do
|
|
should "only change the source to the final source" do
|
|
@post = create(:post)
|
|
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_file: Rack::Test::UploadedFile.new("test/files/test.png"),
|
|
final_source: "blah",
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
assert_equal("blah", @post.reload.source)
|
|
end
|
|
end
|
|
|
|
context "when a post with the same MD5 already exists" do
|
|
should "return an error" do
|
|
@post1 = create(:post, md5: "ecef68c44edb8a0d6a3070b5f8e8ee76", file_size: 1234)
|
|
@post2 = create(:post, file_size: 789)
|
|
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post2.id,
|
|
post_replacement: {
|
|
replacement_file: Rack::Test::UploadedFile.new("test/files/test.jpg"),
|
|
}
|
|
}
|
|
|
|
assert_response 422
|
|
assert_equal(789, @post2.reload.file_size)
|
|
end
|
|
end
|
|
|
|
context "replacing a post with a Pixiv page URL" do
|
|
should "replace with the full size image" do
|
|
@post = create(:post)
|
|
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_url: "https://www.pixiv.net/en/artworks/62247350",
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
assert_equal(80, @post.reload.image_width)
|
|
assert_equal(82, @post.image_height)
|
|
assert_equal(16_275, @post.file_size)
|
|
assert_equal("png", @post.file_ext)
|
|
assert_equal("4ceadc314938bc27f3574053a3e1459a", @post.md5)
|
|
assert_equal("4ceadc314938bc27f3574053a3e1459a", Digest::MD5.file(@post.file).hexdigest)
|
|
assert_equal("https://i.pximg.net/img-original/img/2017/04/04/08/54/15/62247350_p0.png", @post.replacements.last.replacement_url)
|
|
assert_equal("https://i.pximg.net/img-original/img/2017/04/04/08/54/15/62247350_p0.png", @post.source)
|
|
end
|
|
end
|
|
|
|
context "replacing a post with a Pixiv ugoira" do
|
|
should "save the frame data" do
|
|
skip "Pixiv credentials not configured" unless Sources::Strategies::Pixiv.enabled?
|
|
|
|
@post = create(:post)
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_url: "https://www.pixiv.net/en/artworks/62247364",
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
assert_equal(80, @post.reload.image_width)
|
|
assert_equal(82, @post.image_height)
|
|
assert_equal(2804, @post.file_size)
|
|
assert_equal("zip", @post.file_ext)
|
|
assert_equal("cad1da177ef309bf40a117c17b8eecf5", @post.md5)
|
|
assert_equal("cad1da177ef309bf40a117c17b8eecf5", @post.media_asset.variant(:original).open_file.md5)
|
|
|
|
assert_equal("https://i.pximg.net/img-zip-ugoira/img/2017/04/04/08/57/38/62247364_ugoira1920x1080.zip", @post.source)
|
|
assert_equal([{"delay" => 125, "file" => "000000.jpg"}, {"delay" => 125, "file" => "000001.jpg"}], @post.pixiv_ugoira_frame_data.data)
|
|
end
|
|
end
|
|
|
|
context "replacing a post with notes" do
|
|
should "rescale the notes" do
|
|
skip "Pixiv credentials not configured" unless Sources::Strategies::Pixiv.enabled?
|
|
|
|
as(create(:user)) do
|
|
@post = create(:post, image_width: 160, image_height: 164)
|
|
@note = @post.notes.create!(x: 80, y: 82, width: 80, height: 82, body: "test", created_at: 1.day.ago)
|
|
end
|
|
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
format: :json,
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_url: "https://i.pximg.net/img-original/img/2017/04/04/08/54/15/62247350_p0.png",
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
@note.reload
|
|
|
|
# replacement image is 80x82, so we're downscaling by 50% (160x164 -> 80x82).
|
|
assert_equal([40, 41, 40, 41], [@note.x, @note.y, @note.width, @note.height])
|
|
end
|
|
end
|
|
|
|
context "a replacement that fails" do
|
|
should "not create a post replacement record" do
|
|
@post = create(:post)
|
|
|
|
assert_no_difference("PostReplacement.count") do
|
|
post_auth post_replacements_path, create(:moderator_user), params: {
|
|
post_id: @post.id,
|
|
post_replacement: {
|
|
replacement_file: Rack::Test::UploadedFile.new("test/files/ugoira.json"),
|
|
}
|
|
}
|
|
|
|
assert_redirected_to @post
|
|
end
|
|
end
|
|
end
|
|
|
|
should "not allow non-mods to replace posts" do
|
|
assert_difference("PostReplacement.count", 0) do
|
|
@post = create(:post)
|
|
post_auth post_replacements_path(post_id: @post.id), create(:user), params: { post_replacement: { replacement_url: "https://cdn.donmai.us/original/d3/4e/d34e4cf0a437a5d65f8e82b7bcd02606.jpg" }}
|
|
assert_response 403
|
|
end
|
|
end
|
|
end
|
|
|
|
context "update action" do
|
|
should "update the replacement" do
|
|
@post_replacement = create(:post_replacement)
|
|
|
|
put_auth post_replacement_path(@post_replacement), create(:moderator_user), params: {
|
|
format: :json,
|
|
id: @post_replacement.id,
|
|
post_replacement: {
|
|
old_file_size: 23,
|
|
file_size: 42,
|
|
}
|
|
}
|
|
|
|
assert_response :success
|
|
assert_equal(23, @post_replacement.reload.old_file_size)
|
|
assert_equal(42, @post_replacement.file_size)
|
|
end
|
|
end
|
|
|
|
context "index action" do
|
|
setup do
|
|
@admin = create(:admin_user)
|
|
@mod = create(:moderator_user, name: "yukari")
|
|
|
|
@post_replacement = create(:post_replacement, creator: @mod, post: create(:post, tag_string: "touhou"), replacement_file: Rack::Test::UploadedFile.new("test/files/test.png"))
|
|
@admin_replacement = create(:post_replacement, creator: @admin, replacement_file: Rack::Test::UploadedFile.new("test/files/test.jpg"))
|
|
end
|
|
|
|
should "render" do
|
|
get post_replacements_path
|
|
assert_response :success
|
|
end
|
|
|
|
should respond_to_search({}).with { [@admin_replacement, @post_replacement] }
|
|
|
|
context "using includes" do
|
|
should respond_to_search(post_tags_match: "touhou").with { @post_replacement }
|
|
should respond_to_search(creator: {level: User::Levels::ADMIN}).with { @admin_replacement }
|
|
should respond_to_search(creator_name: "yukari").with { @post_replacement }
|
|
end
|
|
end
|
|
end
|
|
end
|