require 'rails_helper' RSpec.describe Post, type: :model do before do PostUrlSanitisationRule.unscoped.delete_all end describe 'URL normalisation' do it 'normalises the HTTP URL before applying sanitisation rules' do PostUrlSanitisationRule.create!( priority: 10, source_pattern: '\\Ahttps://example\\.com/videos/([^/]+)\\z', replacement: 'https://example.com/watch/\\1' ) post = described_class.create!( title: 'normalised URL', url: ' https://EXAMPLE.com/videos/123/ ' ) expect(post.url).to eq('https://example.com/watch/123') end it 'does not normalise an unchanged URL when another attribute changes' do post = create(:post) post.update_column(:url, 'https://EXAMPLE.com/unchanged/') post.update!(title: 'updated title') expect(post.reload.url).to eq('https://EXAMPLE.com/unchanged/') end it 'validates the sanitised URL length' do path = 'a' * 375 PostUrlSanitisationRule.create!( priority: 10, source_pattern: '\\Ahttps://example\\.com/(a+)\\z', replacement: 'https://example.com/\\1\\1' ) post = described_class.new( title: 'long URL', url: "https://example.com/#{ path }" ) expect(post).to be_invalid expect(post.errors.details.fetch(:url)).to include( error: :too_long, count: 768 ) end it 'validates uniqueness after sanitisation' do PostUrlSanitisationRule.create!( priority: 10, source_pattern: '\\Ahttps://example\\.com/alias\\z', replacement: 'https://example.com/canonical' ) create(:post, url: 'https://example.com/canonical') post = described_class.new(title: 'duplicate URL', url: 'https://example.com/alias') expect(post).to be_invalid expect(post.errors.details.fetch(:url)).to include(error: :taken, value: post.url) end end end