Files
redux-scraper/spec/lib/domain/fa/parser/redux_page_spec.rb
2025-09-07 18:27:22 +00:00

972 lines
34 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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