From dc47ac5719caee1bdbe131fbd1e24f2db771c7ca Mon Sep 17 00:00:00 2001 From: Robert Fletcher Date: Thu, 5 Mar 2026 17:29:10 -0800 Subject: [PATCH] more system specs --- .tool-versions | 1 - spec/fixtures/invalid.opml | 1 + spec/system/account_setup_spec.rb | 10 ++++++++ spec/system/authentication_spec.rb | 11 ++++++++ spec/system/debug_spec.rb | 35 ++++++++++++++++++++++++++ spec/system/feed_edit_spec.rb | 23 +++++++++++++++-- spec/system/feed_show_spec.rb | 10 ++++++++ spec/system/feed_status_spec.rb | 31 +++++++++++++++++++++++ spec/system/feeds_index_spec.rb | 11 ++++++++ spec/system/import_spec.rb | 10 ++++++++ spec/system/keyboard_shortcuts_spec.rb | 20 +++++++++++++++ spec/system/stories_index_spec.rb | 23 +++++++++++++++++ 12 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/invalid.opml create mode 100644 spec/system/authentication_spec.rb create mode 100644 spec/system/debug_spec.rb create mode 100644 spec/system/feed_status_spec.rb diff --git a/.tool-versions b/.tool-versions index 9248d4ff4..837e271ce 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,2 @@ ruby 4.0.1 -bundler 2.6.2 postgres 14.6 diff --git a/spec/fixtures/invalid.opml b/spec/fixtures/invalid.opml new file mode 100644 index 000000000..dcb338f60 --- /dev/null +++ b/spec/fixtures/invalid.opml @@ -0,0 +1 @@ +this is not valid opml content diff --git a/spec/system/account_setup_spec.rb b/spec/system/account_setup_spec.rb index b3da84c87..766e0cdfb 100644 --- a/spec/system/account_setup_spec.rb +++ b/spec/system/account_setup_spec.rb @@ -33,6 +33,16 @@ def fill_in_fields(username:, confirm: "my-password") expect(page).to have_link("sign up") end + it "completes sign up for a second user" do + Setting::UserSignup.create!(enabled: true) + create(:user) + visit(setup_password_path) + + fill_in_fields(username: "second-user") + + expect(page).to have_text("Logged in as second-user") + end + it "does not allow a second user to signup when not enabled" do create(:user) diff --git a/spec/system/authentication_spec.rb b/spec/system/authentication_spec.rb new file mode 100644 index 000000000..686b61744 --- /dev/null +++ b/spec/system/authentication_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +RSpec.describe "authentication" do + it "redirects to login when accessing a protected page while logged out" do + create(:user) + + visit(news_path) + + expect(page).to have_current_path(login_path) + end +end diff --git a/spec/system/debug_spec.rb b/spec/system/debug_spec.rb new file mode 100644 index 000000000..2e38a4da3 --- /dev/null +++ b/spec/system/debug_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +RSpec.describe "admin/debug" do + it "displays debug information" do + login_as(create(:user, admin: true)) + + visit("/admin/debug") + + expect(page).to have_content(RUBY_VERSION) + end + + it "shows None when there are no pending migrations" do + login_as(create(:user, admin: true)) + + visit("/admin/debug") + + expect(page).to have_content("None") + end + + it "shows the queued jobs count" do + login_as(create(:user, admin: true)) + + visit("/admin/debug") + + expect(page).to have_content("Queued Jobs") + end + + it "blocks non-admin users" do + login_as(default_user) + + visit("/admin/debug") + + expect(page).to have_content("No route matches") + end +end diff --git a/spec/system/feed_edit_spec.rb b/spec/system/feed_edit_spec.rb index 3fcf5a913..02d13e345 100644 --- a/spec/system/feed_edit_spec.rb +++ b/spec/system/feed_edit_spec.rb @@ -26,7 +26,27 @@ def visit_edit_feed expect(page).to have_content("Updated the feed") end - it "allows assigning a feed to a group", :aggregate_failures do + it "allows removing a group from a feed" do + login_as(default_user) + feed = create(:feed, :with_group) + 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("", from: "group-id") + click_on("Save") + + expect(feed.reload.group).to be_nil + end + + it "allows assigning a feed to a group" do login_as(default_user) group = create(:group) feed = create(:feed) @@ -44,7 +64,6 @@ def visit_edit_feed 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 d78fdc97b..c60103967 100644 --- a/spec/system/feed_show_spec.rb +++ b/spec/system/feed_show_spec.rb @@ -71,6 +71,16 @@ def create_and_visit_feed(story_title: nil) expect(page).to have_current_path(feeds_new_path) end + it "displays read stories for the feed" do + login_as(default_user) + feed = create(:feed) + create(:story, :read, feed:, title: "Read Story") + + visit("/feed/#{feed.id}") + + expect(page).to have_content("Read Story") + end + it "only marks stories from the current feed as read" do login_as(default_user) other_feed = create(:feed) diff --git a/spec/system/feed_status_spec.rb b/spec/system/feed_status_spec.rb new file mode 100644 index 000000000..9ad3efb85 --- /dev/null +++ b/spec/system/feed_status_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +RSpec.describe "feed status bubbles" do + it "shows a green status for a healthy feed" do + login_as(default_user) + create(:feed, status: :green) + + visit("/feeds") + + expect(page).to have_css(".status.green") + end + + it "shows a red status for a feed that has never successfully fetched" do + login_as(default_user) + create(:feed, status: :red) + + visit("/feeds") + + expect(page).to have_css(".status.red") + end + + it "shows a yellow status for a red feed that has stories" do + login_as(default_user) + feed = create(:feed, status: :red) + create(:story, feed:) + + visit("/feeds") + + expect(page).to have_css(".status.yellow") + end +end diff --git a/spec/system/feeds_index_spec.rb b/spec/system/feeds_index_spec.rb index ace5f788c..bd0af1610 100644 --- a/spec/system/feeds_index_spec.rb +++ b/spec/system/feeds_index_spec.rb @@ -86,4 +86,15 @@ expect(page).to have_link(href: feed.url) end + + it "displays feeds in alphabetical order" do + login_as(default_user) + create(:feed, name: "Zebra Feed") + create(:feed, name: "Alpha Feed") + + visit "/feeds" + + names = all(".feed-title a").map(&:text).map(&:strip) + expect(names).to eq(["Alpha Feed", "Zebra Feed"]) + end end diff --git a/spec/system/import_spec.rb b/spec/system/import_spec.rb index 3d7f01d59..8c7c19fe5 100644 --- a/spec/system/import_spec.rb +++ b/spec/system/import_spec.rb @@ -19,4 +19,14 @@ expect(page).to have_content("We're getting you some stories to read") end + + it "gracefully handles an invalid OPML file" do + login_as(default_user) + visit(feeds_import_path) + file_path = Rails.root.join("spec/fixtures/invalid.opml") + + attach_file("opml_file", file_path, visible: false) + + expect(page).to have_content("We're getting you some stories to read") + end end diff --git a/spec/system/keyboard_shortcuts_spec.rb b/spec/system/keyboard_shortcuts_spec.rb index 59430ab1d..56be775f7 100644 --- a/spec/system/keyboard_shortcuts_spec.rb +++ b/spec/system/keyboard_shortcuts_spec.rb @@ -133,6 +133,26 @@ def open_story_and_send(key) expect(page).to have_current_path(feeds_new_path) end + it "opens story in new tab with b" do + login_as(default_user) + create_story_and_visit(title: "My Story") + send_keys("j") + + send_keys("b") + + expect(page.windows.size).to eq(2) + end + + it "opens story in new tab with v" do + login_as(default_user) + create_story_and_visit(title: "My Story") + send_keys("j") + + send_keys("v") + + expect(page.windows.size).to eq(2) + end + it "opens the shortcuts modal with ?" do login_as(default_user) create_story_and_visit(title: "My Story") diff --git a/spec/system/stories_index_spec.rb b/spec/system/stories_index_spec.rb index 7c0ff039d..4b84a4895 100644 --- a/spec/system/stories_index_spec.rb +++ b/spec/system/stories_index_spec.rb @@ -160,6 +160,29 @@ def open_story_and_find_unread_icon(story_title) expect(page).to have_css(".story.read") end + it "displays stories in newest-first order by default" do + create(:story, title: "Older Story", published: 2.days.ago) + create(:story, title: "Newer Story", published: 1.day.ago) + login_as(default_user) + + visit news_path + + titles = all(".story-title").map(&:text) + expect(titles).to eq(["Newer Story", "Older Story"]) + end + + it "displays stories in oldest-first order when configured" do + default_user.update!(stories_order: "asc") + create(:story, title: "Older Story", published: 2.days.ago) + create(:story, title: "Newer Story", published: 1.day.ago) + login_as(default_user) + + visit news_path + + titles = all(".story-title").map(&:text) + expect(titles).to eq(["Older Story", "Newer Story"]) + end + it "allows viewing a story with hot keys" do create(:story, title: "My Story", body: "My Body") login_as(default_user)