Merge branch 'develop' into feat/CW-5624

This commit is contained in:
Muhsin Keloth
2025-10-08 18:04:39 +05:30
committed by GitHub
3 changed files with 85 additions and 3 deletions
+1 -1
View File
@@ -935,7 +935,7 @@ GEM
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uniform_notifier (1.17.0)
uri (1.0.3)
uri (1.0.4)
uri_template (0.7.0)
valid_email2 (5.2.6)
activemodel (>= 3.2)
@@ -34,8 +34,9 @@ class Whatsapp::PopulateTemplateParametersService
return nil if url.blank?
sanitized_url = sanitize_parameter(url)
validate_url(sanitized_url)
build_media_type_parameter(sanitized_url, media_type.downcase, media_name)
normalized_url = normalize_url(sanitized_url)
validate_url(normalized_url)
build_media_type_parameter(normalized_url, media_type.downcase, media_name)
end
def build_named_parameter(parameter_name, value)
@@ -138,9 +139,20 @@ class Whatsapp::PopulateTemplateParametersService
sanitized[0...1000] # Limit length to prevent DoS
end
def normalize_url(url)
# Use Addressable::URI for better URL normalization
# It handles spaces, special characters, and encoding automatically
Addressable::URI.parse(url).normalize.to_s
rescue Addressable::URI::InvalidURIError
# Fallback: simple space encoding if Addressable fails
url.gsub(' ', '%20')
end
def validate_url(url)
return if url.blank?
# url is already normalized by the caller
uri = URI.parse(url)
raise ArgumentError, "Invalid URL scheme: #{uri.scheme}. Only http and https are allowed" unless %w[http https].include?(uri.scheme)
raise ArgumentError, 'URL too long (max 2000 characters)' if url.length > 2000
@@ -0,0 +1,70 @@
require 'rails_helper'
describe Whatsapp::PopulateTemplateParametersService do
let(:service) { described_class.new }
describe '#normalize_url' do
it 'normalizes URLs with spaces' do
url_with_spaces = 'https://example.com/path with spaces'
normalized = service.send(:normalize_url, url_with_spaces)
expect(normalized).to eq('https://example.com/path%20with%20spaces')
end
it 'handles URLs with special characters' do
url = 'https://example.com/path?query=test value'
normalized = service.send(:normalize_url, url)
expect(normalized).to include('https://example.com/path')
expect(normalized).not_to include(' ')
end
it 'returns valid URLs unchanged' do
url = 'https://example.com/valid-path'
normalized = service.send(:normalize_url, url)
expect(normalized).to eq(url)
end
end
describe '#build_media_parameter' do
context 'when URL contains spaces' do
it 'normalizes the URL before building media parameter' do
url_with_spaces = 'https://example.com/image with spaces.jpg'
result = service.build_media_parameter(url_with_spaces, 'IMAGE')
expect(result[:type]).to eq('image')
expect(result[:image][:link]).to eq('https://example.com/image%20with%20spaces.jpg')
end
end
context 'when URL contains special characters in query string' do
it 'normalizes the URL correctly' do
url = 'https://example.com/video.mp4?title=My Video'
result = service.build_media_parameter(url, 'VIDEO', 'test_video')
expect(result[:type]).to eq('video')
expect(result[:video][:link]).not_to include(' ')
end
end
context 'when URL is already valid' do
it 'builds media parameter without changing URL' do
url = 'https://example.com/document.pdf'
result = service.build_media_parameter(url, 'DOCUMENT', 'test.pdf')
expect(result[:type]).to eq('document')
expect(result[:document][:link]).to eq(url)
expect(result[:document][:filename]).to eq('test.pdf')
end
end
context 'when URL is blank' do
it 'returns nil' do
result = service.build_media_parameter('', 'IMAGE')
expect(result).to be_nil
end
end
end
end