972 lines
34 KiB
Ruby
972 lines
34 KiB
Ruby
# 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
|