✂️ Remove the approvals gem ✂️ (#12978)

* Remove approvals fixtures

* Remove approvals initializer

* Remove approvals gem

* Remove approvals step from travis.yml

* Remove approvals from dockerignore and gitignore

* Remove references to approvals gem in docs

* Un-approvals spec/liquid_tags/codepen_tag_spec.rb

* Un-approvals spec/liquid_tags/dotnet_fiddle_tag_spec.rb

* Temporarily skip other approvals tests

We will still need to delete files in /spec/fixtures/approvals after this.

* Revert changes to dotnet_fiddle_tag_spec and codepen_tag_spec, skip those tests instead

* Temporarily skip more approvals based tests

* Attempt at moving html doc inline

* Comment out one more approvals spec

* Update dotnet fiddle and codepen liquid tag specs to not use Approvals

* Update liquid tag specs + system specs to not use Approvals

* Un-approval feed import, github issue, and tweet tag specs

* Re-add .approvals to gitignore and dockerignore

* Use Rspec compound expectations
This commit is contained in:
Vaidehi Joshi 2021-03-19 13:28:06 -07:00 committed by GitHub
parent d6fde3ab89
commit 3f6600541e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 131 additions and 411 deletions

View file

@ -60,7 +60,6 @@ install:
script: script:
- bundle exec rails db:create db:schema:load webpacker:compile - bundle exec rails db:create db:schema:load webpacker:compile
- bin/knapsack_pro_rspec - bin/knapsack_pro_rspec
- '[ ! -f .approvals ] || bundle exec approvals verify --ask false'
notifications: notifications:
slack: slack:
if: branch = master if: branch = master

View file

@ -159,7 +159,6 @@ group :development, :test do
end end
group :test do group :test do
gem "approvals", "~> 0.0" # A library to make it easier to do golden-master style testing in Ruby
gem "exifr", ">= 1.3.6" # EXIF Reader is a module to read EXIF from JPEG and TIFF images gem "exifr", ">= 1.3.6" # EXIF Reader is a module to read EXIF from JPEG and TIFF images
gem "factory_bot_rails", "~> 6.1" # factory_bot is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies gem "factory_bot_rails", "~> 6.1" # factory_bot is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies
gem "launchy", "~> 2.5" # Launchy is helper class for launching cross-platform applications in a fire and forget manner. gem "launchy", "~> 2.5" # Launchy is helper class for launching cross-platform applications in a fire and forget manner.

View file

@ -111,9 +111,6 @@ GEM
activerecord (>= 4.2.0) activerecord (>= 4.2.0)
anyway_config (2.1.0) anyway_config (2.1.0)
ruby-next-core (>= 0.11.0) ruby-next-core (>= 0.11.0)
approvals (0.0.24)
nokogiri (~> 1.6)
thor (~> 0.18)
ast (2.4.2) ast (2.4.2)
aws-eventstream (1.1.1) aws-eventstream (1.1.1)
aws-sigv4 (1.2.3) aws-sigv4 (1.2.3)
@ -886,7 +883,6 @@ DEPENDENCIES
ahoy_matey (~> 3.2) ahoy_matey (~> 3.2)
amazing_print (~> 1.3) amazing_print (~> 1.3)
ancestry (~> 3.2) ancestry (~> 3.2)
approvals (~> 0.0)
better_errors (~> 2.9) better_errors (~> 2.9)
binding_of_caller (~> 0.8) binding_of_caller (~> 0.8)
blazer (~> 2.4.2) blazer (~> 2.4.2)

View file

@ -1,43 +0,0 @@
---
title: Approvals Tests
---
# Approvals Tests
Approvals test is a form of unit test. It works by taking a snapshot of the
results and confirming that they have not changed. A good use-case for the
Approvals tests is to compare the rendered HTML to the test specified HTML.
## Usage
Simply create your test similar to the following:
```ruby
it "renders the correct HTML on the home page" do
page = '<html><head></head><body><h1>ZOMG</h1></body></html>'
verify(format: :html) { page } # format can also be :json
end
```
You may then run the said test and a new `*.received.*` file will be created.
Thereafter, run the following command to verify the newly created file and
approve the created change.
```shell
approvals verify
```
Please be sure to include the Approvals file in your commit.
## Edge cases
Approvals tests are difficult to utilise for testing variables that change. This
includes variables like:
- Time
- URL slug
- uploaded image slug
Please avoid generating large approvals files as it will be stored in the
codebase. If your approvals file gets too large, Approvals test may not be the
right tool for the job.

View file

@ -2,7 +2,6 @@
title: Testing/QA Guide title: Testing/QA Guide
items: items:
- acceptance-tests.md - acceptance-tests.md
- approvals-tests.md
- integration-tests.md - integration-tests.md
- unit-functional-tests.md - unit-functional-tests.md
- frontend-tests.md - frontend-tests.md

View file

@ -1,12 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" media="screen" href="/assets/katex-fingerprint.css" />
</head>
<body>
<div class="katex-element">
<span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>c</mi><mo>=</mo><mo>±</mo><msqrt><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup></mrow></msqrt></mrow><annotation encoding="application/x-tex">c = \pm\sqrt{a^2 + b^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathdefault">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.2399999999999998em;vertical-align:-0.177736em;"></span><span class="mord">±</span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.0622639999999999em;"><span class="svg-align" style="top:-3.2em;"><span class="pstrut" style="height:3.2em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mord mathdefault">a</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathdefault">b</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.0222640000000003em;"><span class="pstrut" style="height:3.2em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.28em;"><svg width="400em" height="1.28em" viewbox="0 0 400000 1296" preserveaspectratio="xMinYMin slice"><path d="M263,681c0.7,0,18,39.7,52,119&#10;c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120&#10;c340,-704.7,510.7,-1060.3,512,-1067&#10;l0 -0&#10;c4.7,-7.3,11,-11,19,-11&#10;H40000v40H1012.3&#10;s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232&#10;c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1&#10;s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26&#10;c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z&#10;M1001 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height:0.177736em;"><span></span></span></span></span></span></span></span></span></span>
</div>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe width="710" height="120" src="https://api.parler.io/ss/player?url=https://www.parler.io/audio/73240183203/d53cff009eac2ab1bc9dd8821a638823c39cbcea.7dd28611-b7fc-4cf8-9977-b6e3aaf644a1.mp3" loading="lazy">
</iframe>
</body>
</html>

View file

@ -19,8 +19,11 @@ RSpec.describe CodepenTag, type: :liquid_tag do
it "accepts codepen link" do it "accepts codepen link" do
liquid = generate_new_liquid(codepen_link) liquid = generate_new_liquid(codepen_link)
rendered_codepen_iframe = liquid.render
Approvals.verify(rendered_codepen_iframe, name: "codepen_liquid_tag", format: :html) expect(liquid.render).to include("<iframe")
.and include(
'src="https://codepen.io/twhite96/embed/XKqrJX?height=600&default-tab=result&embed-version=2"',
)
end end
it "accepts codepen link with a / at the end" do it "accepts codepen link with a / at the end" do

View file

@ -18,7 +18,7 @@ RSpec.describe CommentTag, type: :liquid_tag do
liquid = generate_comment_tag(comment.id_code_generated) liquid = generate_comment_tag(comment.id_code_generated)
expect(liquid.render).to include(comment.body_markdown) expect(liquid.render).to include(comment.body_markdown)
expect(liquid.render).to include(user.name) .and include(user.name)
end end
it "renders 'Comment Not Found' message if comment ID does not exist" do it "renders 'Comment Not Found' message if comment ID does not exist" do

View file

@ -12,7 +12,9 @@ RSpec.describe DetailsTag, type: :liquid_tag do
it "generates proper details div with summary" do it "generates proper details div with summary" do
rendered = generate_details_liquid(summary, content).render rendered = generate_details_liquid(summary, content).render
Approvals.verify(rendered, name: "details_liquid_tag_spec", format: :html)
expect(rendered).to include("<details")
expect(rendered).to include('<summary>Click to see the answer!') # rubocop:disable Style/StringLiterals
end end
end end
end end

View file

@ -17,8 +17,9 @@ RSpec.describe DotnetFiddleTag, type: :liquid_tag do
it "accepts dotnet link" do it "accepts dotnet link" do
liquid = generate_new_liquid(dotnetfiddle_link) liquid = generate_new_liquid(dotnetfiddle_link)
rendered_dotnet_iframe = liquid.render
Approvals.verify(rendered_dotnet_iframe, name: "dotnetfiddle_liquid_tag", format: :html) expect(liquid.render).to include("<iframe")
.and include('src="https://dotnetfiddle.net/Widget/v2kx9jcd"')
end end
it "accepts dotnet link with a / at the end" do it "accepts dotnet link with a / at the end" do

View file

@ -13,8 +13,14 @@ RSpec.describe InstagramTag, type: :liquid_tag do
it "checks that the tag is properly parsed" do it "checks that the tag is properly parsed" do
valid_id = "BXgGcAUjM39" valid_id = "BXgGcAUjM39"
liquid = generate_instagram_tag(valid_id) liquid = generate_instagram_tag(valid_id)
rendered_instagram = liquid.render
Approvals.verify(rendered_instagram, name: "instagram_liquid_tag", format: :html) # rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include('id="instagram-liquid-tag"')
.and include("https://www.instagram.com/p/#{valid_id}/embed/captioned")
.and include('src="https://platform.instagram.com/en_US/embeds.js"')
.and include('<div class="instagram-position">')
# rubocop:enable Style/StringLiterals
end end
it "rejects invalid ids" do it "rejects invalid ids" do

View file

@ -18,8 +18,11 @@ RSpec.describe JsFiddleTag, type: :liquid_tag do
it "accepts jsfiddle link" do it "accepts jsfiddle link" do
liquid = generate_new_liquid(jsfiddle_link) liquid = generate_new_liquid(jsfiddle_link)
rendered_jsfiddle_iframe = liquid.render
Approvals.verify(rendered_jsfiddle_iframe, name: "jsfiddle_liquid_tag", format: :html) # rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include('src="http://jsfiddle.net/link2twenty/v2kx9jcd/embedded//dark"')
# rubocop:enable Style/StringLiterals
end end
it "accepts jsfiddle link with a / at the end" do it "accepts jsfiddle link with a / at the end" do

View file

@ -19,53 +19,62 @@ RSpec.describe JsitorTag, type: :liquid_tag do
Liquid::Template.parse("{% jsitor #{link} %}") Liquid::Template.parse("{% jsitor #{link} %}")
end end
# rubocop:disable Style/StringLiterals
it "renders jsitor liquid tag" do it "renders jsitor liquid tag" do
liquid = create_jsitor_liquid_tag(jsitor_link) liquid = create_jsitor_liquid_tag(jsitor_link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag", format: :html) expect(liquid.render).to include('<iframe')
.and include('src="https://jsitor.com/embed/B7FQ5tHbY"')
end end
it "parses the link with spaces before and after" do it "parses the link with spaces before and after" do
link = " https://jsitor.com/embed/B7FQ5tHbY " link = " https://jsitor.com/embed/B7FQ5tHbY "
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag", format: :html) expect(liquid.render).to include('<iframe')
.and include('src="https://jsitor.com/embed/B7FQ5tHbY"')
end end
it "accepts jsitor link with query params" do it "accepts jsitor link with query params" do
link = "https://jsitor.com/embed/B7FQ5tHbY?html&css" link = "https://jsitor.com/embed/B7FQ5tHbY?html&css"
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag_with_params", format: :html) expect(liquid.render).to include('<iframe')
.and include('src="https://jsitor.com/embed/B7FQ5tHbY?html&amp;css"')
end end
it "accepts jsitor id" do it "accepts jsitor id" do
link = "B7FQ5tHbY" link = "B7FQ5tHbY"
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag", format: :html) expect(liquid.render).to include('<iframe')
.and include("https://jsitor.com/embed/#{link}")
end end
it "accepts jsitor id with parameters" do it "accepts jsitor id with parameters" do
link = "B7FQ5tHbY?html&css" link = "B7FQ5tHbY&amp;html&amp;css"
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag_with_params", format: :html) expect(liquid.render).to include('<iframe')
.and include("https://jsitor.com/embed/#{link}")
end end
it "accepts jsitor link with hyphen id" do it "accepts jsitor link with hyphen id" do
link = "https://jsitor.com/embed/2o-syYxmi" link = "https://jsitor.com/embed/2o-syYxmi"
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag_with_hyphen", format: :html) expect(liquid.render).to include('<iframe')
.and include(link)
end end
it "accepts jsitor id with hyphen" do it "accepts jsitor id with hyphen" do
link = "2o-syYxmi" link = "2o-syYxmi"
liquid = create_jsitor_liquid_tag(link) liquid = create_jsitor_liquid_tag(link)
render_jsitor_iframe = liquid.render
Approvals.verify(render_jsitor_iframe, name: "jsitor_liquid_tag_with_hyphen", format: :html) expect(liquid.render).to include('<iframe')
.and include("https://jsitor.com/embed/#{link}")
end end
# rubocop:enable Style/StringLiterals
it "doesnt accepts jsitor link with a / at the end" do it "doesnt accepts jsitor link with a / at the end" do
link = "https://jsitor.com/embed/1QgJVmCam/" link = "https://jsitor.com/embed/1QgJVmCam/"

View file

@ -9,8 +9,8 @@ RSpec.describe KatexTag, type: :liquid_tag do
it "generates Katex output" do it "generates Katex output" do
content = "c = \\pm\\sqrt{a^2 + b^2}" content = "c = \\pm\\sqrt{a^2 + b^2}"
rendered = generate_katex_liquid(content).render rendered = generate_katex_liquid(content).render.gsub(/katex-.{64}\.css/, "katex-fingerprint.css")
verify(format: :html) { rendered.gsub(/katex-.{64}\.css/, "katex-fingerprint.css") } expect(rendered).to include("/assets/katex-fingerprint.css")
end end
it "includes the css style tag only once when rendering multiple" do it "includes the css style tag only once when rendering multiple" do

View file

@ -51,8 +51,13 @@ RSpec.describe KotlinTag, type: :liquid_tag do
it "renders correctly a Kotlin Playground link" do it "renders correctly a Kotlin Playground link" do
liquid = generate_new_liquid(valid_link) liquid = generate_new_liquid(valid_link)
rendered_kotlin_iframe = liquid.render
Approvals.verify(rendered_kotlin_iframe, name: "kotlin_liquid_tag", format: :html) # rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include(
"https://play.kotlinlang.org/embed?short=owreUFFUG&amp;from&amp;to&amp;theme=darcula&amp;readOnly",
)
# rubocop:enable Style/StringLiterals
end end
end end
end end

View file

@ -11,8 +11,14 @@ RSpec.describe NextTechTag, type: :liquid_template do
it "accepts nexttech link" do it "accepts nexttech link" do
liquid = generate_new_liquid(nexttech_link) liquid = generate_new_liquid(nexttech_link)
rendered_nexttech_iframe = liquid.render
Approvals.verify(rendered_nexttech_iframe, name: "nexttech_liquid_tag", format: :html) # rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include('src="https://next.tech/projects/6ba1fffbd09e/embed"')
.and include(
'style="width:100%; height:calc(350px + 8vw); border:0; border-radius: 4px; overflow:hidden;"',
)
# rubocop:enable Style/StringLiterals
end end
it "accepts nexttech link with a / at the end" do it "accepts nexttech link with a / at the end" do

View file

@ -15,7 +15,11 @@ RSpec.describe ParlerTag, type: :liquid_tag do
it "accepts a valid Parler URL" do it "accepts a valid Parler URL" do
liquid = generate_new_liquid(valid_id) liquid = generate_new_liquid(valid_id)
verify(format: :html) { liquid.render }
# rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include("https://api.parler.io/ss/player?url=#{valid_id}")
# rubocop:enable Style/StringLiterals
end end
it "raises an error for invalid IDs" do it "raises an error for invalid IDs" do

View file

@ -24,7 +24,12 @@ RSpec.describe RunkitTag, type: :liquid_tag do
it "generates proper div with content" do it "generates proper div with content" do
rendered = generate_runkit_liquid(preamble, content).render rendered = generate_runkit_liquid(preamble, content).render
Approvals.verify(rendered, name: "runkit_liquid_tag_spec", format: :html)
# rubocop:disable Style/StringLiterals
expect(rendered).to include('<code')
expect(rendered).to include('style="display: none"')
expect(rendered).to include('await getJSON(&quot;https://storage.googleapis.com/maps-devrel/google.json&quot;);')
# rubocop:enable Style/StringLiterals
end end
end end
end end

View file

@ -19,8 +19,11 @@ RSpec.describe SoundcloudTag, type: :liquid_tag do
it "accepts soundcloud link" do it "accepts soundcloud link" do
liquid = generate_new_liquid(soundcloud_link) liquid = generate_new_liquid(soundcloud_link)
rendered_soundcloud_iframe = liquid.render
Approvals.verify(rendered_soundcloud_iframe, name: "soundcloud_liquid_tag", format: :html) # rubocop:disable Style/StringLiterals
expect(liquid.render).to include('<iframe')
.and include("#{url_segment}=#{soundcloud_link}&auto_play=false")
# rubocop:enable Style/StringLiterals
end end
it "rejects invalid soundcloud link" do it "rejects invalid soundcloud link" do

View file

@ -23,11 +23,14 @@ RSpec.describe TweetTag, type: :liquid_tag do
end end
end end
xit "render properly", :vcr do it "render properly", :vcr do
VCR.use_cassette("twitter_client_status_extended") do VCR.use_cassette("twitter_client_status_extended") do
Time.use_zone("Asia/Tokyo") do Time.use_zone("Asia/Tokyo") do
rendered = generate_tweet_liquid_tag(twitter_id).render rendered = generate_tweet_liquid_tag(twitter_id).render
Approvals.verify(rendered, name: "liquid_tweet_tag_spec", format: :html)
expect(rendered).to include('<blockquote class="ltag__twitter-tweet"')
expect(rendered).to include('<div class="ltag__twitter-tweet__main"')
expect(rendered).to include('<div class="ltag__twitter-tweet__actions">')
end end
end end
end end

View file

@ -25,7 +25,7 @@ RSpec.describe UserTag, type: :liquid_tag do
it "renders a missing username and name", aggregate_failures: true do it "renders a missing username and name", aggregate_failures: true do
liquid = generate_user_tag("nonexistent user") liquid = generate_user_tag("nonexistent user")
expect(liquid.render).to include("[deleted user]") expect(liquid.render).to include("[deleted user]")
expect(liquid.render).to include("[Deleted User]") .and include("[Deleted User]")
end end
end end
end end

View file

@ -15,7 +15,7 @@ RSpec.describe WikipediaTag, type: :liquid_tag, vcr: true do
VCR.use_cassette("wikipedia_tag") do VCR.use_cassette("wikipedia_tag") do
liquid = generate_new_liquid(valid_url) liquid = generate_new_liquid(valid_url)
expect(liquid.render).to include("ltag__wikipedia") expect(liquid.render).to include("ltag__wikipedia")
expect(liquid.render).to include("<b>Wikipedia</b> is a multilingual online encyclopedia") .and include("<b>Wikipedia</b> is a multilingual online encyclopedia")
end end
end end
@ -23,7 +23,7 @@ RSpec.describe WikipediaTag, type: :liquid_tag, vcr: true do
VCR.use_cassette("wikipedia_section_tag") do VCR.use_cassette("wikipedia_section_tag") do
liquid = generate_new_liquid(valid_section_url) liquid = generate_new_liquid(valid_section_url)
expect(liquid.render).to include("ltag__wikipedia") expect(liquid.render).to include("ltag__wikipedia")
expect(liquid.render).to include("Several studies have shown that most of the Wikipedia contributors are male.") .and include("Several studies have shown that most of the Wikipedia contributors are male.")
end end
end end

View file

@ -24,25 +24,35 @@ RSpec.describe YoutubeTag, type: :liquid_tag do
Liquid::Template.parse("{% youtube #{id} %}") Liquid::Template.parse("{% youtube #{id} %}")
end end
# rubocop:disable Style/StringLiterals
it "accepts a valid YouTube ID with no starting time" do it "accepts a valid YouTube ID with no starting time" do
liquid = generate_new_liquid(valid_id_no_time).render liquid = generate_new_liquid(valid_id_no_time).render
Approvals.verify(liquid, name: "youtube_liquid_tag_no_time", format: :html)
expect(liquid).to include('<iframe')
expect(liquid).to include('src="https://www.youtube.com/embed/dQw4w9WgXcQ"')
end end
it "accepts valid YouTube ID with starting times" do it "accepts valid YouTube ID with starting times" do
liquid = generate_new_liquid(valid_ids_with_time).render liquid = generate_new_liquid(valid_ids_with_time).render
Approvals.verify(liquid, name: "youtube_liquid_tag_with_time", format: :html)
expect(liquid).to include('<iframe')
expect(liquid).to include('src="https://www.youtube.com/embed/QASbw8_0meM?start=29546"')
end end
it "accepts YouTube ID with no start time and an empty space" do it "accepts YouTube ID with no start time and an empty space" do
liquid = generate_new_liquid("#{valid_id_no_time} ").render liquid = generate_new_liquid("#{valid_id_no_time} ").render
Approvals.verify(liquid, name: "youtube_liquid_tag_no_time_trailing_space", format: :html)
expect(liquid).to include('<iframe')
expect(liquid).to include('src="https://www.youtube.com/embed/dQw4w9WgXcQ"')
end end
it "accepts YouTube ID with start times and one empty space" do it "accepts YouTube ID with start times and one empty space" do
liquid = generate_new_liquid("#{valid_ids_with_time} ").render liquid = generate_new_liquid("#{valid_ids_with_time} ").render
Approvals.verify(liquid, name: "youtube_liquid_tag_with_time", format: :html)
expect(liquid).to include('<iframe')
expect(liquid).to include('src="https://www.youtube.com/embed/QASbw8_0meM?start=29546"')
end end
# rubocop:enable Style/StringLiterals
it "raises an error for invalid IDs" do it "raises an error for invalid IDs" do
expect { generate_new_liquid(invalid_id).render }.to raise_error("Invalid YouTube ID") expect { generate_new_liquid(invalid_id).render }.to raise_error("Invalid YouTube ID")

View file

@ -88,10 +88,12 @@ RSpec.describe GithubIssue, type: :model, vcr: true do
end end
end end
xit "saves HTML in .processed_html" do it "saves HTML in .processed_html" do
VCR.use_cassette("github_client_issue") do VCR.use_cassette("github_client_issue") do
issue = described_class.find_or_fetch(url_issue) issue = described_class.find_or_fetch(url_issue)
Approvals.verify(issue.processed_html, name: "github_client_issue", format: :html)
expect(issue.processed_html).to include("<p><strong>Describe the bug</strong></p>")
expect(issue.processed_html).to include("<p><strong>To Reproduce</strong></p>")
end end
end end

View file

@ -12,10 +12,11 @@ RSpec.describe Feeds::Import, type: :service, vcr: true do
end end
end end
# TODO: We could probably improve these tests by parsing against the items in the feed rather than hardcoding
it "fetch only articles from a feed_url", vcr: { cassette_name: "feeds_import" } do it "fetch only articles from a feed_url", vcr: { cassette_name: "feeds_import" } do
num_articles = described_class.call num_articles = described_class.call
verify(format: :txt) { num_articles } expect(num_articles).to eq(21)
end end
it "does not recreate articles if they already exist", vcr: { cassette_name: "feeds_import_twice" } do it "does not recreate articles if they already exist", vcr: { cassette_name: "feeds_import_twice" } do
@ -25,11 +26,9 @@ RSpec.describe Feeds::Import, type: :service, vcr: true do
end end
it "parses correctly", vcr: { cassette_name: "feeds_import" } do it "parses correctly", vcr: { cassette_name: "feeds_import" } do
described_class.call expect do
described_class.call
verify format: :txt do end.to change(User.find_by(feed_url: nonpermanent_link).articles, :count).by(1)
User.find_by(feed_url: nonpermanent_link).articles.first.body_markdown
end
end end
it "sets feed_fetched_at to the current time", vcr: { cassette_name: "feeds_import" } do it "sets feed_fetched_at to the current time", vcr: { cassette_name: "feeds_import" } do
@ -87,17 +86,17 @@ RSpec.describe Feeds::Import, type: :service, vcr: true do
end end
context "with an explicit set of users", vcr: { cassette_name: "feeds_import" } do context "with an explicit set of users", vcr: { cassette_name: "feeds_import" } do
# TODO: We could probably improve these tests by parsing against the items in the feed rather than hardcoding
it "accepts a subset of users" do it "accepts a subset of users" do
num_articles = described_class.call(users: User.with_feed.limit(1)) num_articles = described_class.call(users: User.with_feed.limit(1))
verify(format: :txt) { num_articles } expect(num_articles).to eq(10)
end end
it "imports no articles if given users are without feed" do it "imports no articles if given users are without feed" do
create(:user, feed_url: nil) create(:user, feed_url: nil)
described_class.call(users: User.where(feed_url: nil)) expect(described_class.call(users: User.where(feed_url: nil))).to eq(0)
verify(format: :txt) { 0 }
end end
end end
end end

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe height="600" src="https://codepen.io/twhite96/embed/XKqrJX?height=600&amp;default-tab=result&amp;embed-version=2" scrolling="no" frameborder="no" allowtransparency="true" loading="lazy" style="width: 100%;">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<details><summary>Click to see the answer!</summary><p>The answer is Forem! </p>
</details>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe src="https://dotnetfiddle.net/Widget/v2kx9jcd" width="100%" height="600" frameborder="0">
</iframe>
</body>
</html>

View file

@ -1,18 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="robots" content="noindex" />
</head>
<body>
<div class="unsubscribed">
<div class="unsubscribed__title">
You have been unsubscribed from DEV(local) digest emails. 😔
</div>
<br /><div class="unsubscribed__message">
You will no longer receive emails like this. If you'd like to re-subscribe or manage your full email preferences, please
<a href="http://localhost:3000/settings/notifications">click here</a>.
</div>
</div>
</body>
</html>

View file

@ -1,9 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<div class="instagram-position">
<iframe id="instagram-liquid-tag" src="https://www.instagram.com/p/BXgGcAUjM39/embed/captioned" allowtransparency="true" frameborder="0" data-instgrm-payload-id="instagram-media-payload-0" scrolling="no" loading="lazy">
</iframe>
<script async="" defer="defer" src="https://platform.instagram.com/en_US/embeds.js"></script></div>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe src="http://jsfiddle.net/link2twenty/v2kx9jcd/embedded//dark" width="100%" height="600" scrolling="no" frameborder="no" allowfullscreen="" allowtransparency="true" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe height="400" src="https://jsitor.com/embed/B7FQ5tHbY" scrolling="no" frameborder="no" loading="lazy" allowtransparency="true" style="width: 100%;">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe height="400" src="https://jsitor.com/embed/2o-syYxmi" scrolling="no" frameborder="no" loading="lazy" allowtransparency="true" style="width: 100%;">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe height="400" src="https://jsitor.com/embed/B7FQ5tHbY?html&amp;css" scrolling="no" frameborder="no" loading="lazy" allowtransparency="true" style="width: 100%;">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe src="https://play.kotlinlang.org/embed?short=owreUFFUG&amp;from&amp;to&amp;theme=darcula&amp;readOnly" allowtransparency="true" scrolling="no" frameborder="0" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe src="https://next.tech/projects/6ba1fffbd09e/embed" style="width:100%; height:calc(350px + 8vw); border:0; border-radius: 4px; overflow:hidden;">
</iframe>
</body>
</html>

View file

@ -1,18 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<div class="runkit-element">
<code style="display: none">
const myVar = 9001
</code>
<code style="display: none;">
// GeoJSON!
var getJSON = require("async-get-json");
await getJSON("https://storage.googleapis.com/maps-devrel/google.json");
</code>
</div>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https://soundcloud.com/user-261265215/dev-to-review-episode-2&amp;auto_play=false&amp;color=%23000000&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;show_teaser=true" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,142 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body><h1>
<a name="h1" href="#h1" class="anchor" id="h1">
</a>
h1
</h1>
<h2>
<a name="h2" href="#h2" class="anchor" id="h2">
</a>
h2
</h2>
<h3>
<a name="h3" href="#h3" class="anchor" id="h3">
</a>
h3
</h3>
<h4>
<a name="h4" href="#h4" class="anchor" id="h4">
</a>
h4
</h4>
<h5>
<a name="h5" href="#h5" class="anchor" id="h5">
</a>
h5
</h5>
<h6>
<a name="h6" href="#h6" class="anchor" id="h6">
</a>
h6
</h6>
<h1>
<a name="multiword-heading" href="#multiword-heading" class="anchor" id="multiword-heading">
</a>
multiword heading
</h1>
<h1>
<a name="multiword-heading-with-weird-punctuampation" href="#multiword-heading-with-weird-punctuampation" class="anchor" id="multiword-heading-with-weird-punctuampation">
</a>
multiword heading with ( weird ? punctu&amp;^ation
</h1>
<h1>
<a name="emoji-heading" href="#emoji-heading" class="anchor" id="emoji-heading">
</a>
😎 emoji heading
</h1>
<p><em>italic</em> <em>italic</em><br /><strong>bold</strong> <strong>bold</strong><br /><em>You <strong>can</strong> combine them</em><br /><strong>asterisks and <em>underscores</em></strong></p>
<ul><li>Item 1</li>
<li>Item 2
<ul><li>Item 2a</li>
</ul></li>
</ul><ol><li>Item 1</li>
<li>Item 2
<ol><li>Item 2a</li>
</ol></li>
</ol><p><a href="cloudinary_link"></a><br />
Format: <a href="cloudinary_link"></a></p>
<ol><li>
<p><strong>Line break in ul/ol spacing test</strong></p>
<ul><li>TEST1
<ul><li>TEST1.1
<ul><li>TEST1.1.1</li>
<li>TESET1.1.3</li>
</ul></li>
</ul></li>
</ul></li>
<li>
<p><strong>Line break in ul/ol spacing test 2</strong></p>
<ul><li>ITEM 1</li>
<li>ITEM 2</li>
<li>ITEM 3</li>
</ul></li>
</ol><p><a href="http://github.com">http://github.com</a><br /><a href="http://github.com">GitHub</a></p>
<p>As Kanye West said:</p>
<blockquote>
<p>We're living the future so<br />
the present is our past.</p>
</blockquote>
<p>I think you should use an <code>&lt;addr&gt;</code> element here instead.<br /></p>
<div class="highlight js-code-highlight">
<pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">fancyAlert</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">.</span><span class="nx">facebox</span><span class="p">({</span><span class="na">div</span><span class="p">:</span><span class="dl">'</span><span class="s1">#foo</span><span class="dl">'</span><span class="p">})</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">
<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title><path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title><path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path></svg></div>
</div>
</div>
<div class="highlight js-code-highlight">
<pre class="highlight plaintext"><code>// indented codeblock should work
function hello() {
console.log("hello");
}
</code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">
<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode</title><path d="M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-off"><title>Exit fullscreen mode</title><path d="M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"></path></svg></div>
</div>
</div>
<ul><li>[x] @mentions, #refs, <a href="">links</a>, <strong>formatting</strong>, and <del>tags</del> supported</li>
<li>[x] list syntax required (any unordered or ordered list supported)</li>
<li>[x] this is a complete item</li>
<li>[ ] this is an incomplete item</li>
</ul><div class="table-wrapper-paragraph"><table><thead><tr><th>First Header</th>
<th>Second Header</th>
</tr></thead><tbody><tr><td>Content from cell 1</td>
<td>Content from cell 2</td>
</tr><tr><td>Content in the first column</td>
<td>Content in the second column</td>
</tr></tbody></table></div>
<p><del>this</del></p></body>
</html>

View file

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe width="710" height="399" src="https://www.youtube.com/embed/dQw4w9WgXcQ" allowfullscreen="" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe width="710" height="399" src="https://www.youtube.com/embed/dQw4w9WgXcQ" allowfullscreen="" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,7 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe width="710" height="399" src="https://www.youtube.com/embed/QASbw8_0meM?start=29546" allowfullscreen="" loading="lazy">
</iframe>
</body>
</html>

View file

@ -1,5 +0,0 @@
require "approvals/rspec"
Approvals.configure do |approvals_config|
approvals_config.approvals_path = "#{::Rails.root}/spec/support/fixtures/approvals/"
end

View file

@ -47,7 +47,13 @@ RSpec.describe "Using the editor", type: :system do
article_body = find("div.crayons-article__body")["innerHTML"] article_body = find("div.crayons-article__body")["innerHTML"]
article_body.gsub!(%r{"https://res\.cloudinary\.com/.{1,}"}, "cloudinary_link") article_body.gsub!(%r{"https://res\.cloudinary\.com/.{1,}"}, "cloudinary_link")
Approvals.verify(article_body, name: "user_preview_article_body", format: :html) # TODO: Convert this to an E2E test?
# rubocop:disable Style/StringLiterals
expect(article_body).to include('<a name="multiword-heading-with-weird-punctuampation"')
.and include('<a name="emoji-heading"')
.and include('<blockquote>')
.and include('Format: <a href=cloudinary_link></a>')
# rubocop:enable Style/StringLiterals
end end
end end
@ -58,7 +64,13 @@ RSpec.describe "Using the editor", type: :system do
article_body = find(:xpath, "//div[@id='article-body']")["innerHTML"] article_body = find(:xpath, "//div[@id='article-body']")["innerHTML"]
article_body.gsub!(%r{"https://res\.cloudinary\.com/.{1,}"}, "cloudinary_link") article_body.gsub!(%r{"https://res\.cloudinary\.com/.{1,}"}, "cloudinary_link")
Approvals.verify(article_body, name: "user_preview_article_body", format: :html) # TODO: Convert this to an E2E test?
# rubocop:disable Style/StringLiterals
expect(article_body).to include('<a name="multiword-heading-with-weird-punctuampation"')
.and include('<a name="emoji-heading"')
.and include('<blockquote>')
.and include('Format: <a href=cloudinary_link></a>')
# rubocop:enable Style/StringLiterals
end end
it "user write and publish an article" do it "user write and publish an article" do

View file

@ -4,6 +4,6 @@ RSpec.describe "email_subscriptions/unsubscribe.html.erb", type: :view do
it "works" do it "works" do
assign(:email_type, "#{SiteConfig.community_name} digest emails") assign(:email_type, "#{SiteConfig.community_name} digest emails")
render render
Approvals.verify(rendered, name: "email_subscriptions/unsubscribe", format: :html) expect(rendered).to include("You have been unsubscribed from #{SiteConfig.community_name} digest emails. 😔")
end end
end end

Binary file not shown.