# typed: false require "rails_helper" require_relative "page_spec_helper" describe Domain::Fa::Parser::Page do include Domain::Fa::Parser::PageSpecHelper it "sees_not_logged_in" do parser = get_parser("login_page.html", require_logged_in: false) refute parser.logged_in? assert_nil parser.logged_in_user end it "throws_if_not_logged_in_by_default" do assert_raises(Domain::Fa::Parser::NotLoggedInError) do get_parser("login_page.html") end end it "submission_not_found_does_not_throw" do parser = get_parser("submission_not_found_in_db.html") refute parser.logged_in? assert parser.submission_not_found? end it "sees_logged_in_correctly" do parser = get_parser("index_logged_in_zzreg.html") assert parser.logged_in? assert_equal parser.logged_in_user, "zzreg" refute parser.submission_not_found? end it "user_page_is_correct" do parser = get_parser("user_page_miles_df.html") assert parser.logged_in? assert_page_type parser, :probably_user_page? assert parser.probably_user_page? assert_equal "-08:00", parser.logged_in_user_tz.formatted_offset up = parser.user_page assert_equal "Miles-DF", up.name assert up.profile_html, /COMMISSIONS: CLOSED/ assert_equal 592, up.num_submissions assert_equal 2_005_424, up.num_pageviews assert_equal 40_192, up.num_comments_recieved assert_equal 7_227, up.num_comments_given assert_equal 6, up.num_journals assert_equal 1_236_200, up.num_favorites assert_equal Time.parse("Jan 12th, 2006 07:52 -08:00"), up.registered_since assert_equal "//a.furaffinity.net/1556545516/miles-df.gif", up.profile_thumb_url end it "can parse admin user page" do parser = get_parser "user_page_dragoneer.html" assert parser.logged_in? assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal "Dragoneer", up.name assert_equal 1_460_919, up.num_pageviews assert_match /Site Owner/, up.profile_html end it "correctly parses a user when there's an admin elsewhere on the page" do parser = get_parser "user_page_childofpeace.html" assert parser.logged_in? assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal "Childofpeace2004", up.name assert_equal 419, up.num_pageviews assert_match /Not Available/, up.profile_html end it "parses special accounts with spaces in the name" do parser = get_parser "user_page_fa_staff.html" assert parser.logged_in? assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal "Fur Affinity Staff", up.name assert_equal 15_962, up.num_pageviews assert_match /placeholder for sending system notices/, up.profile_html end it "gallery_is_correct" do parser = get_parser "gallery_page_miles_df.html" assert parser.logged_in? assert_page_type parser, :probably_listings_page? listings = parser.submissions_parsed assert_equal 48, listings.length assert_equal 51_039_083, listings.first.id first_listing = listings.first assert_equal "Miles-DF", first_listing.artist assert_equal "/user/miles-df/", first_listing.artist_user_page_path assert_equal "booty", first_listing.title assert_equal "/view/51039083/", first_listing.view_path assert_equal "//t.furaffinity.net/51039083@300-1676577120.jpg", first_listing.thumb_path assert_equal 2, parser.submission_folders.length parser_empty = get_parser "gallery_page_empty_miles_df.html" assert parser_empty.probably_listings_page? assert_equal 0, parser_empty.submissions_parsed.length end it "gallery_is_correct_with_folders" do parser = get_parser "gallery_page_with_folders_feretta.html" assert_page_type parser, :probably_listings_page? listings = parser.submissions_parsed assert_equal 48, listings.length first_listing = listings.first assert_equal 51_066_954, first_listing.id assert_equal "Feretta", first_listing.artist assert_equal "/user/feretta/", first_listing.artist_user_page_path assert_equal "[Comm] Size and property - 2/3", first_listing.title assert_equal "/view/51066954/", first_listing.view_path assert_equal "//t.furaffinity.net/51066954@200-1676761927.jpg", first_listing.thumb_path last_listing = listings.last assert_equal 50_320_568, last_listing.id assert_equal "Feretta", last_listing.artist assert_equal "/user/feretta/", last_listing.artist_user_page_path assert_equal "[Comm] Sizable date - 1/3", last_listing.title assert_equal "/view/50320568/", last_listing.view_path assert_equal "//t.furaffinity.net/50320568@200-1671750577.jpg", last_listing.thumb_path folders = parser.submission_folders assert_equal({ href: "/scraps/feretta/", title: "Scraps" }, folders[0]) assert_equal( { href: "/gallery/feretta/folder/60236/Tale-of-Tails", title: "Tale of Tails", }, folders[1], ) assert_equal( { href: "/gallery/feretta/folder/60234/Illustrations", title: "Illustrations", }, folders[2], ) assert_equal( { href: "/gallery/feretta/folder/229520/Marketing", title: "Marketing" }, folders[9], ) assert_equal( { href: "/gallery/feretta/folder/820310/3D", title: "3D" }, folders[13], ) end it "browse_page" do # https://www.furaffinity.net/browse/ parser = get_parser "browse_page.html" assert_page_type parser, :probably_listings_page? listings = parser.submissions_parsed # FA appears to respond with only 47? assert_equal 47, listings.length first = listings.first assert_equal 51_067_352, first.id assert_equal "CleverDerpy", first.artist assert_equal "/user/cleverderpy/", first.artist_user_page_path assert_equal "The Second Kind of Tarpit", first.title assert_equal "/view/51067352/", first.view_path assert_equal "//t.furaffinity.net/51067352@400-1676764142.jpg", first.thumb_path end it "adult_submission" do parser = get_parser("submission_51067352_adult.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 51_067_352, sub.id assert_equal "CleverDerpy", sub.artist assert_equal "/user/cleverderpy/", sub.artist_user_page_path assert_equal "The Second Kind of Tarpit", sub.title assert_equal :adult, sub.rating assert_equal "//d.furaffinity.net/art/cleverderpy/1676764142/1676764142.cleverderpy_tarryn_and_rosie_shaymin_tar_cv_00001.png", sub.full_res_img assert_equal Time.parse("Feb 18, 2023 06:49 PM -08:00"), sub.posted_date assert_equal "Artwork (Digital)", sub.category assert_equal "Vore", sub.theme assert_equal "Unspecified / Any", sub.species assert_equal "Multiple characters", sub.gender assert_equal 201, sub.num_views assert_equal 0, sub.num_comments assert_equal 15, sub.num_favorites assert_equal "1920x1080", sub.resolution_str assert sub.description_html =~ /belongs to Nintendo/ end it "submission_is_correct" do parser = get_parser("submission_51067333_blauhaher.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 51_067_333, sub.id assert_equal "BlauHaher", sub.artist assert_equal "/user/blauhaher/", sub.artist_user_page_path assert_equal "//a.furaffinity.net/1676066883/blauhaher.gif", sub.artist_avatar_url assert_equal '"CUTIE!"', sub.title assert_equal :general, sub.rating assert_equal "//d.furaffinity.net/art/blauhaher/1676764049/1676764049.blauhaher_хорнь.png", sub.small_img assert_equal "//d.furaffinity.net/art/blauhaher/1676764049/1676764049.blauhaher_хорнь.png", sub.full_res_img assert_equal Time.parse("Feb 18, 2023 06:47 PM -08:00"), sub.posted_date assert_equal "Artwork (Digital)", sub.category assert_equal "Doodle", sub.theme assert_equal "Unspecified / Any", sub.species assert_equal "Any", sub.gender assert_equal 1, sub.num_favorites assert_equal 0, sub.num_comments assert_equal 17, sub.num_views assert_equal "1024x1024", sub.resolution_str assert_equal [], sub.keywords_array assert sub.description_html =~ /really adore at the way this/ end it "submission_with_tags" do parser = get_parser("submission_19190013_korichi.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 19_190_013, sub.id assert_equal "Korichi", sub.artist assert_equal "General Furry Art", sub.theme assert_equal "Artwork (Digital)", sub.category assert_equal :general, sub.rating assert_equal "1280x914", sub.resolution_str assert_equal 6272, sub.num_views assert_equal "Male", sub.gender assert_equal "Dragon (Other)", sub.species assert_equal Time.parse("Feb 24, 2016 12:51 AM -08:00"), sub.posted_date assert_equal %w[kobold frog hunting male frog mighty hunter], sub.keywords_array end it "text_only_submission" do parser = get_parser("submission_10327196_icyfoxy_text_only.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 10_327_196, sub.id assert_equal "icyfoxy", sub.artist assert_equal "/user/icyfoxy/", sub.artist_user_page_path assert_equal "Ancient Awakening- Wereyena herm TF (By Wyraachur)", sub.title assert_equal "//d.furaffinity.net/download/art/icyfoxy/stories/1488278723/1365480658.icyfoxy_sonya_the_wereyena.txt", sub.full_res_img assert_equal :adult, sub.rating assert_equal 819, sub.num_views assert_equal 0, sub.num_comments assert_equal 12, sub.num_favorites assert_equal "Hyena", sub.species assert_equal "Story", sub.category assert_equal "General Furry Art", sub.theme assert_equal "50x50", sub.resolution_str assert_equal %w[ Transformation TF Change Male Herm TFTG Transgender Growth Fang Breasts Ass Cock Balls Icyfoxy Wyraachur wereyena Sonya ], sub.keywords_array assert_equal "Other / Not Specified", sub.gender expect(Time.parse("Apr 9, 2013 12:10 AM -07:00")).to be_within(1.second).of( sub.posted_date, ) end it "submission_id_is_correct_20340491" do parser = get_parser("submission_20340491.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 20_340_491, sub.id assert_equal "Skye", sub.title assert_equal :general, sub.rating end it "flash_submission" do parser = get_parser("submission_21956745_flash.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 21_956_745, sub.id assert_equal "Drake Test: Take One", sub.title assert_equal :mature, sub.rating assert_equal "Tasuric", sub.artist assert_equal "Flash", sub.category assert_equal "Animal related (non-anthro)", sub.theme assert (/A closeup of the drake g/) =~ sub.description_html assert_equal "//d.furaffinity.net/download/art/tasuric/1481384060/1481384060.tasuric_tasflash_camnom.swf", sub.full_res_img end it "submission_id_16750893_category" do parser = get_parser("submission_16750893.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 16_750_893, sub.id assert_equal "Day at the range with kagura", sub.title assert_equal :mature, sub.rating assert_equal "Soulhunt3r", sub.artist # this post in particular is special - it has no category nor theme (??) assert_nil sub.category assert_nil sub.theme assert_equal "Western Dragon", sub.species assert (/Today was a good day kagura/) =~ sub.description_html assert_equal "//d.furaffinity.net/art/soulhunt3r/1433541729/1433541729.soulhunt3r_image.jpg", sub.full_res_img end it "watchlist_zzreg" do parser = get_parser("watchlist_zzreg.html", require_logged_in: false) user_list = parser.user_list assert_equal 10, user_list.length assert_equal "-creeps", user_list[0].url_name assert_equal "-creeps", user_list[0].name assert_equal "~nicky~", user_list.last.url_name assert_equal "~Nicky~", user_list.last.name end it "parses home page correctly" do parser = get_parser("home.html", require_logged_in: true) assert_page_type parser, :probably_listings_page? listings = parser.submissions_parsed assert_equal 112, listings.length assert_equal 52_807_274, listings.first.id first_listing = listings.first assert_equal "LemontasticTobster", first_listing.artist assert_equal "/user/lemontastictobster/", first_listing.artist_user_page_path assert_equal "FREE OC Animatronic Raffle! (READ DESC)", first_listing.title assert_equal "/view/52807274/", first_listing.view_path assert_equal "//t.furaffinity.net/52807274@200-1688750295.jpg", first_listing.thumb_path end it "has the right recent favorites and users" do parser = get_parser("user_page_tenzing.html") assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal up.recent_fav_fa_ids.length, 20 assert_equal up.recent_fav_fa_ids, [ 53_255_068, 53_140_782, 31_417_552, 53_050_580, 53_050_352, 52_961_865, 52_916_591, 34_833_220, 49_050_098, 52_875_656, 52_826_012, 52_807_234, 35_678_896, 52_773_671, 52_750_513, 38_721_736, 28_430_551, 50_976_208, 51_785_387, 52_449_028, ] assert_equal up.recent_watchers.map(&:to_a), [ %w[Boxstuff boxstuff], %w[Shuffl3 shuffl3], %w[Fervidus fervidus], %w[SargentTNT sargenttnt], %w[asitanneko asitanneko], %w[overfuck overfuck], %w[LuciaTheCelestialVixen luciathecelestialvixen], %w[goodcabinet goodcabinet], %w[Lethal_Dose1 lethaldose1], %w[Kingtiger2101 kingtiger2101], %w[Nilla_Arts nillaarts], %w[Riku_Anita rikuanita], ] assert_equal up.recent_watching.map(&:to_a), [ %w[Seyorrol seyorrol], %w[Glopossum glopossum], %w[Jeniak jeniak], %w[rajii rajii], %w[Kenjomik kenjomik], %w[fluff-kevlar fluff-kevlar], %w[Fisk fisk], %w[Crinz crinz], %w[Tabuley tabuley], %w[Braeburned braeburned], %w[knifeDragon knifedragon], %w[LotusGarden lotusgarden], ] end it "works with FA+ users" do parser = get_parser("marzimoo_user_page.html") assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal up.name, "MarziMoo" assert_equal up.registered_since, Time.parse("Sep 7, 2018 06:19 -0700") end it "handles pages with no favorites" do parser = get_parser("azurathefox_user_page.html") assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal up.name, "AzuraTheFox" assert_equal up.recent_fav_fa_ids, [] assert_equal up.recent_watchers.first.to_a, %w[SN214549 sn214549] assert_equal up.recent_watchers.last.to_a, %w[Duckyou7464 duckyou7464] assert_equal up.recent_watching, [] end it "parses older format for favs pages" do parser = get_parser("favs_zzreg_page_0_first.html") assert_page_type parser, :probably_listings_page? assert_equal parser.submissions_parsed.length, 2 assert_equal parser.favorites_next_button_id, "1074627373" end it "parses 2024 format for favs pages with a next button" do parser = get_parser("favs_zzreg_page_1_2024_format.html") assert_page_type parser, :probably_listings_page? assert_equal parser.submissions_parsed.length, 48 assert_equal parser.favorites_next_button_id, "1436907409" end it "parses 2024 format for favs pages with no next button" do parser = get_parser("favs_zzreg_page_last_2024_format.html") assert_page_type parser, :probably_listings_page? assert_equal parser.submissions_parsed.length, 37 assert_nil parser.favorites_next_button_id end it "parses 2025 format" do parser = get_parser("submission_59584979_2025_style_keywords.html") assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 59_584_979, sub.id assert_equal "Felureii", sub.artist assert_equal "/user/felureii/", sub.artist_user_page_path assert_equal "//a.furaffinity.net/1733967392/felureii.gif", sub.artist_avatar_url assert_equal "Practice", sub.title assert_equal :general, sub.rating assert_equal "//d.furaffinity.net/art/felureii/1737390216/1737390216.felureii_0f3gn7ifbl8.jpg", sub.small_img assert_equal "//d.furaffinity.net/art/felureii/1737390216/1737390216.felureii_0f3gn7ifbl8.jpg", sub.full_res_img assert_equal Time.parse("Jan 20, 2025 11:23 AM -08:00"), sub.posted_date assert_equal "Artwork (Digital)", sub.category assert_equal "All", sub.theme assert_equal "Unspecified / Any", sub.species assert_equal "Any", sub.gender assert_equal 0, sub.num_favorites assert_equal 0, sub.num_comments assert_equal 16, sub.num_views assert_equal "677x672", sub.resolution_str assert_equal %w[art troll fantasy], sub.keywords_array assert_equal "Nothing special, just practice.", sub.description_html.strip end it "parses num_watched_by and num_watching" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_koul_over_threshold_watchers.html", ), ) assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal 25, up.num_watched_by assert_equal 14, up.num_watching end context "pages after the September 2025 update" do it "works when posted_at is in the AM" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/submission/submission_page_62203391_2025-09-07.html", ), ) assert_page_type parser, :probably_submission? sub = parser.submission assert_equal 62_203_391, sub.id assert_equal "alice_yagami", sub.artist assert_equal "aliceyagami", sub.artist_url_name assert_equal "/user/aliceyagami/", sub.artist_user_page_path assert_equal "//d.furaffinity.net/art/aliceyagami/1757267333/1757267333.aliceyagami_silksong.jpg", sub.small_img assert_equal "//d.furaffinity.net/art/aliceyagami/1757267333/1757267333.aliceyagami_silksong.jpg", sub.full_res_img assert_equal Time.parse("Sep 7, 2025 10:48:53 -07:00"), sub.posted_date end it "works when posted_at is in the PM" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/submission/submission_page_62198493_2025-09-07.html", ), ) assert_page_type parser, :probably_submission? sub = parser.submission assert_equal Time.parse("Sep 6, 2025 9:07:01 PM -07:00"), sub.posted_date end end context "recent gallery submission parsing" do it "works when the user has recent gallery submissions" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_kutua_one_recent_one_total_gallery.html", ), ) assert_page_type parser, :probably_user_page? up = parser.user_page expect(up.recent_gallery_fa_ids).to eq([60_073_062]) end it "works when the user has no submissions" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_angelpawqt.html", ), ) assert_page_type parser, :probably_user_page? up = parser.user_page expect(up.recent_gallery_fa_ids).to eq([]) end end context "march 2025 user page layout updates" do it "gets the right page fields" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_gnilica_03_2025_update.html", ), ) assert_page_type parser, :probably_user_page? assert_equal "-05:00", parser.logged_in_user_tz.formatted_offset up = parser.user_page assert_equal 89, up.num_pageviews assert_equal 1, up.num_watched_by assert_equal 2, up.num_watching assert_equal 3, up.num_favorites assert_equal 1, up.num_comments_recieved assert_equal 0, up.num_comments_given assert_equal 1, up.num_submissions assert_equal "gnilica", up.name assert_equal :active, up.account_status assert_equal ["WildSteppe"], up.recent_watchers.map(&:name) assert_equal %w[WildSteppe just_dosha], up.recent_watching.map(&:name) assert_equal ["wildsteppe"], up.recent_watchers.map(&:url_name) assert_equal %w[wildsteppe justdosha], up.recent_watching.map(&:url_name) assert_equal Time.parse("Nov 8, 2023 12:16 PM -0500"), up.registered_since assert_equal [55_315_013], up.recent_gallery_fa_ids assert_equal [], up.recent_fav_fa_ids end it "works with deceased account" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_dragoneer_03_2025_update.html", ), ) assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal "Dragoneer", up.name assert_equal :deceased, up.account_status assert_equal [ 57_640_158, 57_631_759, 57_574_876, 57_573_028, 57_557_857, 57_550_264, 57_536_644, 57_414_032, 57_268_996, 57_253_476, 57_058_401, 56_515_114, 57_056_700, 56_527_550, 56_984_570, 56_891_225, 56_975_323, 56_943_559, 56_912_979, 56_912_982, ], up.recent_fav_fa_ids assert_equal [ 52_163_102, 52_151_943, 52_141_347, 52_138_550, 52_130_147, 52_082_293, 52_082_271, 51_908_294, 51_894_361, 51_881_908, 51_857_730, 51_799_409, 51_785_417, 51_783_907, 51_746_087, 51_746_065, 51_362_239, 51_301_232, 51_277_956, 51_264_723, ], up.recent_gallery_fa_ids assert_equal %w[ kingexcalibur drembonaarkrah chakat-jaggerfrost neo-kitsune wolfiezwolf idididid uddebo86 wyq eternalkrush sabredragon honeycumb anthroperson18 ], up.recent_watchers.map(&:url_name) assert_equal %w[ augurynite inkchubs larru-larru zekeobsidian appleofmyshampoo vaspi dissimulated omeome mazaku lamor grasseater98 videlthewusky ], up.recent_watching.map(&:url_name) end it "works with a staff account" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/user_page/user_page_ash_staff_03_2025_update.html", ), ) assert_page_type parser, :probably_user_page? up = parser.user_page assert_equal "Ash", up.name assert_equal :admin, up.account_status end end it "works with new submission page format without gender field" do parser = get_parser_at( Rails.root.join( "test/fixtures/files/domain/fa/parser/redux/submission_48178881_no_gender_fields.html", ), ) assert_page_type parser, :probably_submission? sub = parser.submission assert_equal "Artwork (Digital)", sub.category assert_equal "Unspecified / Any", sub.species assert_equal "Animal related (non-anthro)", sub.theme assert_equal 128, sub.num_favorites assert_equal 3, sub.num_comments assert_equal 1706, sub.num_views assert_equal Time.parse("Jul 20, 2022 01:34 PM -07:00"), sub.posted_date assert_nil sub.gender assert_equal :adult, sub.rating end describe "an old old user page" do let(:parser) do get_fa_parser( "user_page/user_page_koraksinatra_old_old.html", version: Domain::Fa::Parser::Page::VERSION_0, ) end it "has the right submission_json_data" do up = parser.user_page expect(up.submissions_json_data.length).to eq(28) sub_21828172 = up.submissions_json_data.find { |f| f.fa_id == 21_828_172 } expect(sub_21828172).to be_present expect(sub_21828172.title).to eq("Turkey Lady") expect(sub_21828172.user_full_name).to eq("Korak_Sinatra") expect(sub_21828172.url_name).to eq("koraksinatra") expect(sub_21828172.date_full).to eq("Nov 26th, 2016 05:04 PM") expect(sub_21828172.faved_at).to eq( Time.parse("Nov 26th, 2016 05:04 PM -08:00"), ) sub_21822027 = up.submissions_json_data.find { |f| f.fa_id == 21_822_027 } expect(sub_21822027).to be_present expect(sub_21822027.title).to eq("Qhala - Commission") expect(sub_21822027.user_full_name).to eq("discoverychannelofficial") expect(sub_21822027.url_name).to eq("discoverychannelofficial") expect(sub_21822027.date_full).to eq("Nov 25th, 2016 09:03 PM") end it "has the right recent_fav_fa_ids" do up = parser.user_page expect(up.recent_fav_fa_ids).to eq( [ 20_027_473, 20_027_473, 21_828_538, 21_828_379, 21_827_826, 21_822_027, 21_821_169, 21_820_661, 21_815_021, 21_810_631, 21_803_422, 21_803_299, 21_803_014, 21_802_133, 21_796_639, ], ) end end describe "an old old admin user page" do let(:parser) do get_fa_parser( "user_page/user_page_chase_old_old.html", version: Domain::Fa::Parser::Page::VERSION_0, ) end it "is detected as a user page" do expect(parser.probably_user_page?).to eq(true) end it "has the right recent_fav_fa_ids" do up = parser.user_page expect(up.recent_fav_fa_ids).to eq([]) end end describe "a favs page with duplicate favs on it" do let(:parser) do get_fa_parser( "favorites/favs_narse_2023_duplicate_ids.html", version: Domain::Fa::Parser::Page::VERSION_2, ) end it "has the right recent_fav_fa_ids" do up = parser.user_page expect(up.recent_fav_fa_ids).to eq([]) expect(up.recent_gallery_fa_ids).to eq([]) end end describe "parsing a user page" do describe "#submissions_json_data" do it "works with a user page with old embedded json format" do parser = get_fa_parser("user_page/user_page_zzreg_one_scrap_submission.html") up = parser.user_page expect(up.submissions_json_data.length).to eq(20) fav0 = up.submissions_json_data.find { |f| f.fa_id == 59_785_748 } expect(fav0).to be_present expect(fav0.fa_id).to eq(59_785_748) expect(fav0.user_full_name).to eq("-creeps") expect(fav0.url_name).to eq("-creeps") expect(fav0.title).to eq("Monty") date_full = "Feb 7, 2025 01:32 AM" expect(fav0.date_full).to eq(date_full) faved_at = Time.parse(date_full + " -08:00") expect(fav0.faved_at).to eq(faved_at) end it "works with a user page with new json in its own tag" do parser = get_fa_parser( "user_page/user_page_zzreg_new_submission_data_elem.html", ) up = parser.user_page expect(up.submissions_json_data.length).to eq(20) fav0 = up.submissions_json_data.find { |f| f.fa_id == 60_272_845 } expect(fav0).to be_present expect(fav0.fa_id).to eq(60_272_845) expect(fav0.user_full_name).to eq("MuskyDusky") expect(fav0.url_name).to eq("muskydusky") expect(fav0.title).to eq("Breeding Season in the Mountains") date_full = "Jul 8, 2025 01:04 PM" expect(fav0.date_full).to eq(date_full) faved_at = Time.parse(date_full + " -07:00") expect(fav0.faved_at).to eq(faved_at) fav19 = up.submissions_json_data.find { |f| f.fa_id == 59_860_095 } expect(fav19.title).to eq("🔞Outdoor Cookie") expect(fav19.user_full_name).to eq("KeaveMind") expect(fav19.url_name).to eq("keavemind") date_full = "Mar 11, 2025 08:32 PM" expect(fav19.date_full).to eq(date_full) faved_at = Time.parse(date_full + " -07:00") expect(fav19.faved_at).to eq(faved_at) end end end describe "parsing a favorites page" do describe "#most_recent_faved_at_time" do it "works with a favorites page with old embedded json format" do parser = get_fa_parser("favorites/favs_zzreg_page_0_first.html") expect(parser.most_recent_faved_at_time).to eq( Time.parse("May 11, 2023 10:54 AM -07:00"), ) end it "works with a favorites page with new json format" do parser = get_fa_parser("favorites/favs_zzreg_page_0_new_data_format.html") expect(parser.most_recent_faved_at_time).to eq( Time.parse("Jul 8, 2025 01:04 PM -07:00"), ) end end end describe "#server_local_time" do it "works with a user page from 2016" do parser = get_fa_parser( "user_page/user_page_fenford_11_2016.html", version: Domain::Fa::Parser::Page::VERSION_0, ) expect(parser.server_local_time_string).to eq("Nov 26th, 2016 01:34 PM") expect(parser.logged_in_user_tz.formatted_offset).to eq("-08:00") expect(parser.server_local_time).to eq( Time.parse("Nov 26th, 2016 01:34 PM -0800"), ) end it "works with a user page from 2025" do parser = get_fa_parser( "user_page/user_page_fenford_07_2025.html", version: Domain::Fa::Parser::Page::VERSION_2, ) expect(parser.server_local_time_string).to eq("Jul 8, 2025 03:34 PM") expect(parser.logged_in_user_tz.formatted_offset).to eq("-08:00") expect(parser.server_local_time).to eq( Time.parse("Jul 8th, 2025 3:34 PM -0700"), ) end end describe "#compute_server_time_zone_offset" do it "works with a user page from 2016" do # HttpLogEntry id=19 parser = get_fa_parser( "user_page/user_page_fenford_11_2016.html", version: Domain::Fa::Parser::Page::VERSION_0, ) expect(parser.logged_in_user_tz.formatted_offset).to eq("-08:00") end it "works with a user page from 2025" do parser = get_fa_parser( "user_page/user_page_fenford_07_2025.html", version: Domain::Fa::Parser::Page::VERSION_2, ) expect(parser.logged_in_user_tz.formatted_offset).to eq("-08:00") end end def get_fa_parser( file, require_logged_in: true, version: Domain::Fa::Parser::Page::VERSION_2 ) path = File.join("domain/fa", file) get_parser_at(path, require_logged_in:, version:) end def get_parser(file, require_logged_in: true) path = File.join("domain/fa/parser/redux", file) get_parser_at(path, require_logged_in:) end def get_parser_at( path, require_logged_in: true, version: Domain::Fa::Parser::Page::VERSION_2 ) path = path.to_s contents = SpecUtil.read_fixture_file(path) || raise("Couldn't open #{path}") parser = Domain::Fa::Parser::Page.new( contents, require_logged_in: require_logged_in, ) assert_equal version, parser.page_version, "parser version mismatch for file #{path}" parser end end