|
| 1 | +require "rails_helper" |
| 2 | + |
| 3 | +RSpec.describe "StoriesPerformanceFix", type: :request do |
| 4 | + let(:user) { create(:user) } |
| 5 | + |
| 6 | + describe "GET /:username/:slug (article show with collection)" do |
| 7 | + let(:collection) { create(:collection, user: user) } |
| 8 | + let(:article) do |
| 9 | + create(:article, user: user, published: true, collection: collection, |
| 10 | + cached_tag_list: "ruby, rails", main_image: "https://example.com/image.png") |
| 11 | + end |
| 12 | + let!(:other_collection_articles) do |
| 13 | + create_list(:article, 3, user: user, published: true, collection: collection, |
| 14 | + cached_tag_list: "ruby", main_image: "https://example.com/other.png") |
| 15 | + end |
| 16 | + |
| 17 | + before do |
| 18 | + # Create articles to trigger sticky nav suggestions |
| 19 | + create_list(:article, 3, user: user, published: true, cached_tag_list: "ruby") |
| 20 | + career_articles = create_list(:article, 3, published: true, cached_tag_list: "career", |
| 21 | + public_reactions_count: 50) |
| 22 | + career_articles.each { |a| a.update_columns(published_at: 1.day.ago) } |
| 23 | + end |
| 24 | + |
| 25 | + it "renders the article show page with collection without MissingAttributeError" do |
| 26 | + # The collection partial uses: id, path, title, slug, published_at, crossposted_at, |
| 27 | + # user_id, organization_id, cached_tag_list, subforem_id, main_image |
| 28 | + get article.path |
| 29 | + follow_redirect! if response.status == 301 |
| 30 | + expect(response).to have_http_status(:ok) |
| 31 | + end |
| 32 | + |
| 33 | + it "renders sticky nav with user stickies (GetUserStickies)" do |
| 34 | + # GetUserStickies uses: id, path, title, cached_tag_list, organization_id, user_id, subforem_id |
| 35 | + get article.path |
| 36 | + follow_redirect! if response.status == 301 |
| 37 | + expect(response).to have_http_status(:ok) |
| 38 | + end |
| 39 | + |
| 40 | + it "renders sticky nav with trending articles (SuggestStickies) when no user stickies" do |
| 41 | + # Remove all same-author articles so GetUserStickies returns empty |
| 42 | + user.articles.where.not(id: article.id).destroy_all |
| 43 | + # SuggestStickies uses: id, path, title, cached_tag_list, cached_user, organization_id, user_id |
| 44 | + get article.path |
| 45 | + follow_redirect! if response.status == 301 |
| 46 | + expect(response).to have_http_status(:ok) |
| 47 | + end |
| 48 | + end |
| 49 | + |
| 50 | + describe "GET /:username (user profile with articles)" do |
| 51 | + let!(:articles) do |
| 52 | + create_list(:article, 3, user: user, published: true, cached_tag_list: "ruby", |
| 53 | + main_image: "https://example.com/image.png") |
| 54 | + end |
| 55 | + |
| 56 | + it "renders user profile page without MissingAttributeError" do |
| 57 | + # limited_column_select provides: path, title, id, published, comments_count, |
| 58 | + # public_reactions_count, cached_tag_list, main_image, main_image_background_hex_color, |
| 59 | + # updated_at, slug, video, user_id, organization_id, video_source_url, video_code, |
| 60 | + # video_thumbnail_url, video_closed_caption_track_url, cached_user, cached_organization, |
| 61 | + # published_at, crossposted_at, description, reading_time, video_duration_in_seconds, |
| 62 | + # score, last_comment_at, main_image_height, type_of, edited_at, processed_html, subforem_id |
| 63 | + get "/#{user.username}" |
| 64 | + expect(response).to have_http_status(:ok) |
| 65 | + end |
| 66 | + |
| 67 | + it "renders all article titles on the profile page" do |
| 68 | + get "/#{user.username}" |
| 69 | + expect(response).to have_http_status(:ok) |
| 70 | + articles.each do |a| |
| 71 | + expect(response.body).to include(a.title) |
| 72 | + end |
| 73 | + end |
| 74 | + |
| 75 | + it "renders article reading time without MissingAttributeError" do |
| 76 | + get "/#{user.username}" |
| 77 | + expect(response).to have_http_status(:ok) |
| 78 | + expect(response.body).to include("min read") |
| 79 | + end |
| 80 | + |
| 81 | + context "with pinned articles" do |
| 82 | + let!(:pin) { create(:profile_pin, profile: user, pinnable: articles.first) } |
| 83 | + |
| 84 | + it "renders pinned articles without MissingAttributeError" do |
| 85 | + get "/#{user.username}" |
| 86 | + expect(response).to have_http_status(:ok) |
| 87 | + expect(response.body).to include("Pinned") |
| 88 | + expect(response.body).to include(articles.first.title) |
| 89 | + end |
| 90 | + end |
| 91 | + end |
| 92 | + |
| 93 | + describe "GET /:org_slug (organization profile with articles)" do |
| 94 | + let(:org) { create(:organization) } |
| 95 | + let!(:org_membership) { create(:organization_membership, user: user, organization: org) } |
| 96 | + let!(:org_articles) do |
| 97 | + create_list(:article, 3, organization: org, user: user, published: true, |
| 98 | + cached_tag_list: "devops", main_image: "https://example.com/org.png") |
| 99 | + end |
| 100 | + |
| 101 | + it "renders organization profile page without MissingAttributeError" do |
| 102 | + get "/#{org.slug}" |
| 103 | + expect(response).to have_http_status(:ok) |
| 104 | + end |
| 105 | + |
| 106 | + it "renders org article cards with all required columns" do |
| 107 | + get "/#{org.slug}" |
| 108 | + expect(response).to have_http_status(:ok) |
| 109 | + org_articles.each do |a| |
| 110 | + expect(response.body).to include(a.title) |
| 111 | + end |
| 112 | + end |
| 113 | + end |
| 114 | +end |
0 commit comments