From cee060ee5af9d32a83abb9f6b5a007c24fd89179 Mon Sep 17 00:00:00 2001 From: Robert Fletcher Date: Tue, 3 Mar 2026 15:52:46 -0800 Subject: [PATCH] add even more system test coverage --- .rubocop_todo.yml | 8 +++- spec/system/application_settings_spec.rb | 18 +++++++ spec/system/archive_spec.rb | 24 ++++++++++ spec/system/feed_edit_spec.rb | 22 +++++++++ spec/system/feed_show_spec.rb | 22 +++++++++ spec/system/feeds_index_spec.rb | 12 +++++ spec/system/keyboard_shortcuts_spec.rb | 27 +++++++++++ spec/system/profile_spec.rb | 14 ++++++ spec/system/starred_spec.rb | 61 ++++++++++++++++++++++++ spec/system/stories_index_spec.rb | 45 +++++++++++++++++ 10 files changed, 252 insertions(+), 1 deletion(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e9ccb8b0d..be0ed7f30 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -110,7 +110,7 @@ RSpec/DescribeClass: Exclude: - 'spec/integration/feed_importing_spec.rb' -# Offense count: 35 +# Offense count: 42 # Configuration parameters: Max, CountAsOne. RSpec/ExampleLength: Exclude: @@ -127,7 +127,13 @@ RSpec/ExampleLength: - 'spec/repositories/group_repository_spec.rb' - 'spec/repositories/story_repository_spec.rb' - 'spec/system/add_feed_spec.rb' + - 'spec/system/archive_spec.rb' + - 'spec/system/feed_edit_spec.rb' + - 'spec/system/feed_show_spec.rb' + - 'spec/system/feeds_index_spec.rb' - 'spec/system/good_job_spec.rb' + - 'spec/system/starred_spec.rb' + - 'spec/system/stories_index_spec.rb' - 'spec/tasks/remove_old_stories_spec.rb' - 'spec/utils/feed_discovery_spec.rb' - 'spec/utils/opml_parser_spec.rb' diff --git a/spec/system/application_settings_spec.rb b/spec/system/application_settings_spec.rb index 03019028c..c8ef8d096 100644 --- a/spec/system/application_settings_spec.rb +++ b/spec/system/application_settings_spec.rb @@ -9,4 +9,22 @@ expect(page).to have_content("User signups are enabled") end + + it "allows disabling account creation" do + Setting::UserSignup.first.update!(enabled: true) + login_as(create(:user, admin: true)) + visit(settings_path) + + within("form", text: "User signups are enabled") { click_on("Disable") } + + expect(page).to have_content("User signups are disabled") + end + + it "prevents signup when signups are disabled" do + create(:user, admin: true) + + visit(setup_password_path) + + expect(page).to have_current_path(login_path) + end end diff --git a/spec/system/archive_spec.rb b/spec/system/archive_spec.rb index 163199800..188d3aa2d 100644 --- a/spec/system/archive_spec.rb +++ b/spec/system/archive_spec.rb @@ -30,4 +30,28 @@ def create_read_stories(count) expect(page).to have_link("Next") end + + it "navigates to the next page", :aggregate_failures do + login_as(default_user) + create_read_stories(21) + visit(archive_path) + + click_on("Next") + + expect(page).to have_content("2 of 2") + expect(page).to have_link("Previous") + end + + it "navigates pages with arrow keys", :aggregate_failures do + login_as(default_user) + create_read_stories(21) + visit(archive_path) + + send_keys(:arrow_right) + expect(page).to have_link("Previous") + + send_keys(:arrow_left) + expect(page).to have_link("Next") + expect(page).to have_no_link("Previous") + end end diff --git a/spec/system/feed_edit_spec.rb b/spec/system/feed_edit_spec.rb index f66a20749..3fcf5a913 100644 --- a/spec/system/feed_edit_spec.rb +++ b/spec/system/feed_edit_spec.rb @@ -25,4 +25,26 @@ def visit_edit_feed expect(page).to have_content("Updated the feed") end + + it "allows assigning a feed to a group", :aggregate_failures do + login_as(default_user) + group = create(:group) + feed = create(:feed) + a11y_skip = [ + "aria-required-children", + "color-contrast", + "label", + "landmark-one-main", + "page-has-heading-one", + "region", + "select-name" + ] + visit("/feeds/#{feed.id}/edit", a11y_skip:) + + select(group.name, from: "group-id") + click_on("Save") + + expect(page).to have_content("Updated the feed") + expect(feed.reload.group).to eq(group) + end end diff --git a/spec/system/feed_show_spec.rb b/spec/system/feed_show_spec.rb index 0118e61ee..97bf31768 100644 --- a/spec/system/feed_show_spec.rb +++ b/spec/system/feed_show_spec.rb @@ -32,4 +32,26 @@ def create_and_visit_feed(story_title: nil) expect(page).to have_content("You've reached RSS Zero") end + + it "refreshes the feed" do + login_as(default_user) + feed = create_and_visit_feed + create(:story, feed:, title: "New Story") + + find_by_id("refresh").click + + expect(page).to have_content("New Story") + end + + it "only marks stories from the current feed as read" do + login_as(default_user) + other_feed = create(:feed) + create(:story, feed: other_feed, title: "Other Story") + create_and_visit_feed(story_title: "Feed Story") + + find_by_id("mark-all").click + visit(news_path) + + expect(page).to have_content("Other Story") + end end diff --git a/spec/system/feeds_index_spec.rb b/spec/system/feeds_index_spec.rb index be664bd03..908ebe505 100644 --- a/spec/system/feeds_index_spec.rb +++ b/spec/system/feeds_index_spec.rb @@ -28,6 +28,18 @@ expect(page).to have_content("Feed deleted") end + it "removes stories from news when a feed is deleted" do + login_as(default_user) + feed = create(:feed) + create(:story, feed: feed, title: "Gone Story") + visit("/feeds") + + click_on "Delete" + visit(news_path) + + expect(page).to have_content("You've reached RSS Zero") + end + it "allows the user to edit a feed" do login_as(default_user) feed = create(:feed) diff --git a/spec/system/keyboard_shortcuts_spec.rb b/spec/system/keyboard_shortcuts_spec.rb index b25de46a2..fe606589f 100644 --- a/spec/system/keyboard_shortcuts_spec.rb +++ b/spec/system/keyboard_shortcuts_spec.rb @@ -70,4 +70,31 @@ def create_story_and_visit(title:) expect(page).to have_content("My Story") end + + it "marks all as read with A" do + login_as(default_user) + create_story_and_visit(title: "My Story") + + send_keys("A") + + expect(page).to have_content("You've reached RSS Zero") + end + + it "navigates to feeds with f" do + login_as(default_user) + create_story_and_visit(title: "My Story") + + send_keys("f") + + expect(page).to have_current_path(feeds_path) + end + + it "navigates to add feed with a" do + login_as(default_user) + create_story_and_visit(title: "My Story") + + send_keys("a") + + expect(page).to have_current_path(feeds_new_path) + end end diff --git a/spec/system/profile_spec.rb b/spec/system/profile_spec.rb index 07e74c1ca..8f1ee59fe 100644 --- a/spec/system/profile_spec.rb +++ b/spec/system/profile_spec.rb @@ -41,4 +41,18 @@ def fill_in_password_fields(existing_password, new_password) expect(default_user.reload).to be_stories_order_asc end + + it "rejects username change with wrong password" do + fill_in_username_fields("wrong_password") + click_on("Update username") + + expect(page).to have_text("Unable to update profile") + end + + it "rejects password change with wrong existing password" do + fill_in_password_fields("wrong_password", "new_password") + click_on("Update password") + + expect(page).to have_text("Unable to update password") + end end diff --git a/spec/system/starred_spec.rb b/spec/system/starred_spec.rb index 2d05d745f..3c2b1d8c7 100644 --- a/spec/system/starred_spec.rb +++ b/spec/system/starred_spec.rb @@ -17,4 +17,65 @@ expect(page).to have_content("you haven't starred any stories") end + + def unstar_story(story_title) + find(".story-preview", text: story_title).click + find(".story-actions .story-starred").click + end + + it "unstars a story from the starred view" do + login_as(default_user) + create(:story, :starred, title: "Starred Story") + visit(starred_path) + + unstar_story("Starred Story") + visit(starred_path) + + expect(page).to have_content("you haven't starred any stories") + end + + def open_story_and_find_star_icon(story_title) + find(".story-preview", text: story_title).click + find(".story-actions .story-starred i") + end + + it "changes the star icon on toggle", :aggregate_failures do + login_as(default_user) + create(:story, title: "My Story") + visit(news_path) + + icon = open_story_and_find_star_icon("My Story") + expect(icon[:class]).to include("fa-star-o") + + find(".story-actions .story-starred").click + expect(icon[:class]).to include("fa-star") + expect(icon[:class]).not_to include("fa-star-o") + + find(".story-actions .story-starred").click + expect(icon[:class]).to include("fa-star-o") + end + + it "stars from the preview row" do + login_as(default_user) + create(:story, title: "Preview Star Story") + visit(news_path) + + find(".story-preview .story-starred", text: "").click + visit(starred_path) + + expect(page).to have_content("Preview Star Story") + end + + def create_starred_stories(count) + count.times { create(:story, :starred) } + end + + it "paginates starred stories" do + login_as(default_user) + create_starred_stories(21) + + visit(starred_path) + + expect(page).to have_link("Next") + end end diff --git a/spec/system/stories_index_spec.rb b/spec/system/stories_index_spec.rb index 6156df6ce..9611768be 100644 --- a/spec/system/stories_index_spec.rb +++ b/spec/system/stories_index_spec.rb @@ -93,6 +93,51 @@ def mark_story_unread(story_title) expect(page).to have_content("My Story") end + def open_story_and_find_unread_icon(story_title) + find(".story-preview", text: story_title).click + find(".story-actions .story-keep-unread i") + end + + it "changes the keep unread icon on toggle", :aggregate_failures do + create(:story, title: "My Story") + login_as(default_user) + visit(news_path) + + icon = open_story_and_find_unread_icon("My Story") + expect(icon[:class]).to include("fa-square-o") + + find(".story-actions .story-keep-unread").click + expect(icon[:class]).to include("fa-check") + expect(icon[:class]).not_to include("fa-square-o") + + find(".story-actions .story-keep-unread").click + expect(icon[:class]).to include("fa-square-o") + end + + it "displays a download link for stories with enclosures" do + create( + :story, + title: "Podcast Episode", + enclosure_url: "http://example.com/episode.mp3" + ) + login_as(default_user) + visit(news_path) + + find(".story-preview", text: "Podcast Episode").click + + expect(page).to have_link(href: "http://example.com/episode.mp3") + end + + it "does not display a download link for stories without enclosures" do + create(:story, title: "Regular Story") + login_as(default_user) + visit(news_path) + + find(".story-preview", text: "Regular Story").click + + expect(page).to have_no_css("a.story-enclosure") + end + it "allows viewing a story with hot keys" do create(:story, title: "My Story", body: "My Body") login_as(default_user)