diff --git a/.babelrc b/.babelrc index 1ec4a04b8474a..4f0581df5a433 100644 --- a/.babelrc +++ b/.babelrc @@ -1,37 +1,21 @@ { "presets": [ - ["env", { - "modules": false, - "targets": { - "browsers": "> 1%", - "uglify": true - }, - "useBuiltIns": true - }], - "preact" + ["env", { "modules": false, "targets": { "browsers": "> 1%", "uglify": true }, "useBuiltIns": true }], + "preact", ], + "env": { "test": { "plugins": [ "transform-es2015-modules-commonjs", - ["transform-react-jsx", { "pragma":"h" }], - "transform-class-properties" ] } }, + "plugins": [ "syntax-dynamic-import", "transform-object-rest-spread", - ["transform-class-properties", - { - "spec": true - } - ], - [ - "transform-react-jsx", - { - "pragma": "h" - } - ] + ["transform-class-properties", { "spec": true }], + [ "transform-react-jsx", { "pragma": "h" }] ] } diff --git a/.gitdocs.js b/.gitdocs.js new file mode 100644 index 0000000000000..093f6d2ace571 --- /dev/null +++ b/.gitdocs.js @@ -0,0 +1,11 @@ +/* + * This file is created so that it's possible to + * Run `gitdocs serve` from root + */ + +var config = require('./docs/.gitdocs.json'); + +module.exports = new Promise((resolve, reject) => { + config.root = 'docs/'; + resolve(config); +}); diff --git a/.github/weekly-digest.yml b/.github/weekly-digest.yml deleted file mode 100644 index 08cced6393094..0000000000000 --- a/.github/weekly-digest.yml +++ /dev/null @@ -1,7 +0,0 @@ -# Configuration for weekly-digest - https://github.com/apps/weekly-digest -publishDay: mon -canPublishIssues: true -canPublishPullRequests: true -canPublishContributors: true -canPublishStargazers: true -canPublishCommits: true diff --git a/Gemfile.lock b/Gemfile.lock index a2af8fedbd679..2c59718192937 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -123,7 +123,7 @@ GEM algorithmia (1.0.1) httparty (~> 0.13) json (~> 1.8) - ancestry (3.0.2) + ancestry (3.0.3) activerecord (>= 3.2.0) approvals (0.0.24) nokogiri (~> 1.6) diff --git a/app/decorators/podcast_episode_decorator.rb b/app/decorators/podcast_episode_decorator.rb new file mode 100644 index 0000000000000..beae9647b9e13 --- /dev/null +++ b/app/decorators/podcast_episode_decorator.rb @@ -0,0 +1,11 @@ +class PodcastEpisodeDecorator < ApplicationDecorator + delegate_all + + def comments_to_show_count + cached_tag_list_array.include?("discuss") ? 75 : 25 + end + + def cached_tag_list_array + (tag_list || "").split(", ") + end +end diff --git a/app/labor/rate_limit_checker.rb b/app/labor/rate_limit_checker.rb index c5e61a61038e1..c00bb5f3bb992 100644 --- a/app/labor/rate_limit_checker.rb +++ b/app/labor/rate_limit_checker.rb @@ -26,7 +26,7 @@ def limit_by_email_recipient_address(address) end def ping_admins - return unless user + return unless user && Rails.env.production? SlackBot.ping( "Rate limit exceeded. https://dev.to#{user.path}", channel: "abuse-reports", diff --git a/app/labor/rss_reader.rb b/app/labor/rss_reader.rb index 0bd3448792cc8..56258155b8fce 100644 --- a/app/labor/rss_reader.rb +++ b/app/labor/rss_reader.rb @@ -72,9 +72,10 @@ def make_from_rss_item(item, user, feed) organization_id: user.organization_id.present? ? user.organization_id : nil } article = Article.create!(article_params) + return unless Rails.env.production? SlackBot.delay.ping( "New Article Retrieved via RSS: #{article.title}\nhttps://dev.to#{article.path}", - channel: "activity", + channel: Rails.env.production? ? "activity" : "test", username: "article_bot", icon_emoji: ":robot_face:", ) diff --git a/app/liquid_tags/parler_tag.rb b/app/liquid_tags/parler_tag.rb index 4707efb720040..cebc8a009a94f 100755 --- a/app/liquid_tags/parler_tag.rb +++ b/app/liquid_tags/parler_tag.rb @@ -27,7 +27,6 @@ def parse_id(input) end def valid_id?(id) - puts id id =~ /\A(https:\/\/www.parler.io\/audio\/\d{1,11}\/[a-zA-Z0-9]{11,40}.[0-9a-zA-Z-]{11,36}.mp3)\Z/ end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 8a61d5bc032fb..a411007ea8657 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -228,7 +228,7 @@ def sharemeow_link def self.comment_async_bust(commentable, username) commentable.touch - commentable.touch(:last_comment_at) + commentable.touch(:last_comment_at) if commentable.respond_to?(:last_comment_at) CacheBuster.new.bust_comment(commentable, username) commentable.index! end diff --git a/app/models/reaction.rb b/app/models/reaction.rb index 24c4274d6862e..d68f2c2904054 100644 --- a/app/models/reaction.rb +++ b/app/models/reaction.rb @@ -135,7 +135,7 @@ def permissions errors.add(:category, "is not valid.") end - if reactable_type == "Article" && !reactable.published + if reactable_type == "Article" && !reactable&.published errors.add(:reactable_id, "is not valid.") end end diff --git a/config/initializers/cloudinary.rb b/config/initializers/cloudinary.rb index e80740594ed0d..1ac97196e5cbe 100644 --- a/config/initializers/cloudinary.rb +++ b/config/initializers/cloudinary.rb @@ -1,5 +1,5 @@ Cloudinary.config do |config| - config.cloud_name = ApplicationConfig["CLOUDINARY_CLOUD_NAME"] + config.cloud_name = Rails.env.test? ? "TEST-CLOUD" : ApplicationConfig["CLOUDINARY_CLOUD_NAME"] config.api_key = ApplicationConfig["CLOUDINARY_API_KEY"] config.api_secret = ApplicationConfig["CLOUDINARY_API_SECRET"] config.secure = ApplicationConfig["CLOUDINARY_SECURE"] diff --git a/config/initializers/delayed_job.rb b/config/initializers/delayed_job.rb new file mode 100644 index 0000000000000..fd323b3102a98 --- /dev/null +++ b/config/initializers/delayed_job.rb @@ -0,0 +1,6 @@ +Delayed::Worker.destroy_failed_jobs = true +Delayed::Worker.sleep_delay = 60 +Delayed::Worker.max_attempts = 10 +Delayed::Worker.max_run_time = 30.minutes +Delayed::Worker.read_ahead = 5 +Delayed::Worker.delay_jobs = !Rails.env.test? diff --git a/docs/helpful-hints.md b/docs/helpful-hints.md index bfdf085855dde..ac87348a89bc9 100644 --- a/docs/helpful-hints.md +++ b/docs/helpful-hints.md @@ -7,4 +7,7 @@ You can view the previews at (for example) `http://localhost:3000/rails/mailers/ ## Previewing these docs in development -Run `yarn run serve-docs` and visit `http://localhost:8000` in your browser. +0. Make sure you are at the base of the repository +1. Install gitdocs `npm install -g gitdocs@next` +1. Serve it `gitdocs serve` +1. Visit `http://localhost:8000` diff --git a/package.json b/package.json index 850d06fbe98fd..23617ab552a2d 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,7 @@ "test:watch": "jest app/javascript/ --watch", "storybook": "start-storybook -p 6006 -c app/javascript/.storybook -s app/javascript/.storybook/assets", "build-storybook": "build-storybook -c app/javascript/.storybook -s app/javascript/.storybook/assets", - "precommit": "lint-staged", - "serve-docs": "cd docs && gitdocs serve" + "precommit": "lint-staged" }, "lint-staged": { "*.{js,jsx}": [ diff --git a/spec/factories/podcasts.rb b/spec/factories/podcasts.rb index 9ccf6c08da451..9ede69abb5179 100644 --- a/spec/factories/podcasts.rb +++ b/spec/factories/podcasts.rb @@ -8,6 +8,8 @@ image { image } description { Faker::Hipster.paragraph(1) } slug { "slug-#{rand(10_000)}" } - feed_url { "slug-#{rand(10_000)}" } + feed_url { Faker::Internet.url } + after(:build) { |pod| pod.define_singleton_method(:pull_all_episodes) {} } + end end diff --git a/spec/factories/reactions.rb b/spec/factories/reactions.rb index 5991a3f33b4ff..e758a27f88b83 100644 --- a/spec/factories/reactions.rb +++ b/spec/factories/reactions.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :reaction do reactable_id { rand(10000) } - user_id { rand(10000) } + user reactable_type { "Article" } category { "like" } end diff --git a/spec/features/user_edits_a_comment_spec.rb b/spec/features/user_edits_a_comment_spec.rb index ec74c905150c8..117f93cad0743 100644 --- a/spec/features/user_edits_a_comment_spec.rb +++ b/spec/features/user_edits_a_comment_spec.rb @@ -27,6 +27,7 @@ def assert_updated context "when user edits via permalinks" do it "updates" do + user.reload visit user.comments.last.path.to_s click_link("EDIT") assert_updated diff --git a/spec/features/user_selects_looking_for_work.rb b/spec/features/user_selects_looking_for_work.rb index 06bd21867eebe..232eba7073e4f 100644 --- a/spec/features/user_selects_looking_for_work.rb +++ b/spec/features/user_selects_looking_for_work.rb @@ -13,7 +13,6 @@ visit "/settings" page.check "Looking for work" click_button("submit") - Delayed::Worker.new.work_off expect(user.follows.count).to eq(1) end end diff --git a/spec/labor/email_digest_spec.rb b/spec/labor/email_digest_spec.rb index 7a3c2888ad7aa..9fd3522878c31 100644 --- a/spec/labor/email_digest_spec.rb +++ b/spec/labor/email_digest_spec.rb @@ -13,14 +13,9 @@ def deliver(*args); super end before do allow(DigestMailer).to receive(:digest_email) { mock_delegator } allow(mock_delegator).to receive(:deliver).and_return(true) - Delayed::Worker.delay_jobs = false user end - after do - Delayed::Worker.delay_jobs = true - end - describe "::send_digest_email" do context "when there's article to be sent" do before { user.follow(author) } diff --git a/spec/liquid_tags/parler_tag_spec.rb b/spec/liquid_tags/parler_tag_spec.rb index bc587bc2782a3..17391a339d10d 100644 --- a/spec/liquid_tags/parler_tag_spec.rb +++ b/spec/liquid_tags/parler_tag_spec.rb @@ -21,7 +21,6 @@ def generate_iframe(_id) it "accepts a valid Parler URL" do liquid = generate_new_liquid(valid_id) - puts liquid expect(liquid.render).to eq(generate_iframe(valid_id)) end diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb index 374067840f7b0..5407331f76389 100644 --- a/spec/models/article_spec.rb +++ b/spec/models/article_spec.rb @@ -414,15 +414,13 @@ def build_and_validate_article(*args) end it "updates main_image_background_hex_color" do + article = build(:article) + allow(article).to receive(:update_main_image_background_hex).and_call_original article.save - expect(article.update_main_image_background_hex_without_delay).to eq(true) + expect(article).to have_received(:update_main_image_background_hex) end describe "#async_score_calc" do - before { Delayed::Worker.delay_jobs = false } - - after { Delayed::Worker.delay_jobs = true } - context "when published" do let(:article) { create(:article) } diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb index aac059b8a0259..e46ee4a568d03 100644 --- a/spec/models/mention_spec.rb +++ b/spec/models/mention_spec.rb @@ -14,11 +14,6 @@ ) end - before do - # Run workers synchronously - # Delayed::Worker.delay_jobs = false - end - it "creates mention if there is a user mentioned" do comment.body_markdown = "Hello @#{user.username}, you are cool." comment.save diff --git a/spec/models/mentor_relationship_spec.rb b/spec/models/mentor_relationship_spec.rb index c8baa9626807a..c7962d9292f4d 100644 --- a/spec/models/mentor_relationship_spec.rb +++ b/spec/models/mentor_relationship_spec.rb @@ -29,7 +29,9 @@ it "sends an email to both users" do relationship.save! - expect(EmailMessage.all.size).to eq(2) + ["mentor_email", "mentee_email"].each do |campaign| + expect(EmailMessage.where(utm_campaign: campaign).count).to eq(1) + end end it "finds unmatched mentors" do diff --git a/spec/models/reaction_spec.rb b/spec/models/reaction_spec.rb index 71c4542bf0034..fb74b3db06e35 100644 --- a/spec/models/reaction_spec.rb +++ b/spec/models/reaction_spec.rb @@ -9,7 +9,20 @@ create(:comment, user_id: user.id, commentable_id: article.id, commentable_type: "Article") end let(:reaction) do - build(:reaction, user_id: user.id, reactable_id: comment.id, reactable_type: "Comment") + build(:reaction, reactable: comment, reactable_type: "Comment") + end + + describe "actual validation" do + subject { Reaction.new(reactable: article, reactable_type: "Article", user: user) } + + before { user.add_role(:trusted) } + + it { is_expected.to belong_to(:user) } + it { is_expected.to validate_inclusion_of(:category).in_array(%w(like thinking hands unicorn thumbsdown vomit readinglist)) } + it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(%i[reactable_id reactable_type category]) } + + # Thumbsdown and Vomits test needed + # it { is_expected.to validate_inclusion_of(:reactable_type).in_array(%w(Comment Article)) } end describe "validations" do @@ -46,7 +59,7 @@ end context "when user is trusted" do - before { user.add_role(:trusted) } + before { reaction.user.add_role(:trusted) } it "allows vomit reactions for users with trusted role" do reaction.category = "vomit" @@ -64,10 +77,8 @@ it "runs async jobs effectively" do u2 = create(:user) c2 = create(:comment, commentable_id: article.id) - Delayed::Worker.delay_jobs = false create(:reaction, user_id: u2.id, reactable_id: c2.id, reactable_type: "Comment") create(:reaction, user_id: u2.id, reactable_id: article.id, reactable_type: "Article") - Delayed::Worker.delay_jobs = true expect(reaction).to be_valid end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5758376f63545..e49fe8eeb10d3 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -422,6 +422,7 @@ def user_from_authorization_service(service_name, signed_in_resource, cta_varian it "returns onboarding checklist leave_your_first_comment if has left comment" do create(:comment, user_id: user.id, commentable_id: article.id, commentable_type: "Article") + user.reload checklist = UserStates.new(user).cached_onboarding_checklist[:leave_your_first_comment] expect(checklist).to eq(true) end diff --git a/spec/support/fixtures/approvals/user_preview_article_body.approved.html b/spec/support/fixtures/approvals/user_preview_article_body.approved.html index 36ba5a73962f6..2df64a40283cb 100644 --- a/spec/support/fixtures/approvals/user_preview_article_body.approved.html +++ b/spec/support/fixtures/approvals/user_preview_article_body.approved.html @@ -24,8 +24,8 @@
Line break in ul/ol spacing test