class ReviseElixirRadarEntry def call(entry) result = Validation() do check { check_url_points_to_an_existing_page(entry[:url]) } check { check_domain_matches_url_host(entry[:domain], entry[:url]) } check { check_entry_title_matches_page_title(entry[:url], entry[:title]) } check { check_utm_campaign_is_valid(entry[:url]) } end review_result = { title: entry[:title] } case result when Success review_result[:status] = 'valid' when Failure review_result[:status] = 'invalid' review_result[:errors] = result end review_result end private def check_url_points_to_an_existing_page(url) if CheckUrlPointsToAnExistingPage.new.call(url) Success(url) else Failure('page_not_found') end end def check_domain_matches_url_host(domain, url) # case CheckDomainMatchesUrlHost.new.call(domain, url) # when true then Success(url) # when false then Failure('domain_does_not_match') # end if CheckDomainMatchesUrlHost.new.call(domain, url) Success(url) else Failure('domain_does_not_match') end end def check_entry_title_matches_page_title(url, entry_title) if CheckEntryTitleMatchesPageTitle.new.call(url, entry_title) Success(url) else Failure('page_title_does_not_match') end end def check_utm_campaign_is_valid(url) if CheckUtmCampaignIsValid.new.call(url) Success(url) else Failure('wrong_utm_campaign') end end end class CheckEntryTitleMatchesPageTitle def initialize(get_page_title: nil) @get_page_title = get_page_title end def call(url, entry_title) page_title = get_page_title.call(url) normalized_page_title = normalize_page_title(page_title) entry_title_matches_page_title = entry_title_matches_page_title?(normalized_page_title, entry_title) [entry_title_matches_page_title, normalized_page_title] end private def normalize_page_title(page_title) page_title .gsub(/\s+/, ' ') .strip end def get_page_title(url) @get_page_title ||= begin lambda do |url| GetPageTitle .new(with: :mechanize) .call(url) end end end def entry_title_matches_page_title?(normalized_page_title, entry_title) (normalized_page_title =~ Regexp.new(entry_title.strip)) end end class GetPageTitle STRATEGIES = { mechanize: lambda do |url| Mechanize.new.get(url).title end } def initialize(with: strategy) @strategy = strategy end def call(url) STRATEGIES.fetch[@strategy].call(url) end end CheckEntryTitleMatchesPageTitle .new( get_page_title: lambda do |url| 'Elixir/Erlang Clustering in Kubernetes' end ) .call( url: 'http://bitwalker.org/posts/2016-08-04-clustering-in-kubernetes', entry_title: 'Elixir/Erlang Clustering in Kubernetes' ) # => [true, 'Elixir/Erlang Clustering in Kubernetes'] class CheckUtmCampaignIsValid def initialize(current_issue_number: nil) @current_issue_number = current_issue_number end def call(url) [ is_utm_campaign_valid?(extract_utm_campaign_value_from(url)), given_utm_campaign_value ] end private def is_utm_campaign_valid?(given_utm_campaign_value) (given_utm_campaign_value == current_issue_number.call) end def extract_utm_campaign_value_from(url) parse_query_strings(url) .fetch('utm_campaign', []) .first end def parse_query_strings(url) CGI.parse(URI.parse(url).query) end def current_issue_number @current_issue_number ||= lambda { $current_issue_number } end end