Replace images in story description with text links

Fix #645
This commit is contained in:
Brian Kung 2019-03-20 08:03:31 -05:00 committed by Peter Bhat Harkins
parent 41cb46a97e
commit efe3505811
4 changed files with 131 additions and 5 deletions

View File

@ -14,8 +14,8 @@ class StoriesController < ApplicationController
@title = "Submit Story"
@cur_url = "/stories/new"
@story = Story.new(story_params)
@story.user_id = @user.id
@story = Story.new(user: @user)
@story.attributes = story_params
if @story.valid? && !(@story.already_posted_recently? && !@story.seen_previous)
if @story.save

View File

@ -18,9 +18,8 @@ class Markdowner
h.name = "strong"
end
if !opts[:allow_images]
ng.css("img").remove
end
# This should happen before adding rel=nofollow to all links
convert_images_to_links(ng) unless opts[:allow_images]
# make links have rel=nofollow
ng.css("a").each do |h|
@ -75,4 +74,18 @@ class Markdowner
end
end
end
def self.convert_images_to_links(node)
node.css("img").each do |img|
link = node.create_element('a')
link['href'], title, alt = img.attributes
.values_at('src', 'title', 'alt')
.map(&:to_s)
link.content = [title, alt, link['href']].find(&:present?)
img.replace link
end
end
end

View File

@ -16,6 +16,40 @@ RSpec.feature "Submitting Stories", type: :feature do
}.to(change { Story.count })
end
context "submitting an inline image" do
context "as a user who is not a moderator" do
scenario "results in a link, not an image" do
expect {
visit "/stories/new"
fill_in "Text", with: "![](https://lbst.rs/fake.jpg)"
fill_in "Title", with: "Image Test"
select :tag1, from: 'Tags'
click_button "Submit"
expect(page).to have_css 'a[href="https://lbst.rs/fake.jpg"]'
expect(page).not_to have_css 'img[src="https://lbst.rs/fake.jpg"]'
}.to(change { Story.count })
end
end
context "as a user who is a moderator" do
before { user.update(is_moderator: true) }
scenario "results in an image, not a link" do
expect {
visit "/stories/new"
fill_in "Text", with: "![](https://lbst.rs/fake.jpg)"
fill_in "Title", with: "Image Test"
select :tag1, from: 'Tags'
click_button "Submit"
expect(page).not_to have_css 'a[href="https://lbst.rs/fake.jpg"]'
expect(page).to have_css 'img[src="https://lbst.rs/fake.jpg"]'
}.to(change { Story.count })
end
end
end
scenario "resubmitting a recent link" do
s = create(:story, created_at: 1.day.ago)
expect {

View File

@ -49,4 +49,83 @@ describe Markdowner do
expect(Markdowner.to_html("[ex](/u/abc)"))
.to eq("<p><a href=\"/u/abc\">ex</a></p>\n")
end
context "when images are not allowed" do
subject { Markdowner.to_html(description, allow_images: false) }
let(:fake_img_url) { 'https://lbst.rs/fake.jpg' }
context "when single inline image in description" do
let(:description) { "![#{alt_text}](#{fake_img_url} \"#{title_text}\")" }
let(:alt_text) { nil }
let(:title_text) { nil }
def target_html inner_text = nil
"<p><a href=\"#{fake_img_url}\" rel=\"nofollow\">#{inner_text}</a></p>\n"
end
context "with no alt text, title text" do
it "turns inline image into links with the url as the default text" do
expect(subject).to eq(target_html(fake_img_url))
end
end
context "with title text" do
let(:title_text) { 'title text' }
it "turns inline image into links with title text" do
expect(subject).to eq(target_html(title_text))
end
end
context "with alt text" do
let(:alt_text) { 'alt text' }
it "turns inline image into links with alt text" do
expect(subject).to eq(target_html(alt_text))
end
end
context "with title text" do
let(:title_text) { 'title text' }
it "turns inline image into links with title text" do
expect(subject).to eq(target_html(title_text))
end
end
context "with title text and alt text" do
let(:title_text) { 'title text' }
it "turns inline image into links, preferring title text" do
expect(subject).to eq(target_html(title_text))
end
end
end
context "with multiple inline images in description" do
let(:description) do
"![](#{fake_img_url})" \
"![](#{fake_img_url})" \
"![alt text](#{fake_img_url})" \
"![](#{fake_img_url} \"title text\")" \
"![alt text](#{fake_img_url} \"title text 2\")"
end
it 'turns all inline images into links' do
expect(subject).to eq(
"<p>" \
"<a href=\"#{fake_img_url}\" rel=\"nofollow\">#{fake_img_url}</a>" \
"<a href=\"#{fake_img_url}\" rel=\"nofollow\">#{fake_img_url}</a>" \
"<a href=\"#{fake_img_url}\" rel=\"nofollow\">alt text</a>" \
"<a href=\"#{fake_img_url}\" rel=\"nofollow\">title text</a>" \
"<a href=\"#{fake_img_url}\" rel=\"nofollow\">title text 2</a>" \
"</p>\n"
)
end
end
end
context "when images are allowed" do
subject { Markdowner.to_html("![](https://lbst.rs/fake.jpg)", allow_images: true) }
it 'allows image tags' do
expect(subject).to include '<img'
end
end
end