diff --git a/app/models/share.rb b/app/models/share.rb index b45f97e..8c1a233 100644 --- a/app/models/share.rb +++ b/app/models/share.rb @@ -3,6 +3,7 @@ class Share < ApplicationRecord UTM_SOURCES = %w[ Bing + Bluesky ConvertKit Facebook Google @@ -42,6 +43,10 @@ class Share < ApplicationRecord ].sort! validates :utm_source, :utm_campaign, :utm_medium, :utm_term, presence: true + validates :utm_source, inclusion: { in: UTM_SOURCES, allow_blank: true }, on: :create + validates :utm_medium, inclusion: { in: UTM_MEDIUMS, allow_blank: true }, on: :create + validates :utm_campaign, inclusion: { in: UTM_CAMPAIGN, allow_blank: true }, on: :create + validates :utm_content, inclusion: { in: UTM_CONTENT, allow_blank: true }, on: :create def calculated_url uri = URI(link.url) diff --git a/spec/factories/shares.rb b/spec/factories/shares.rb index eecc4c7..81fd484 100644 --- a/spec/factories/shares.rb +++ b/spec/factories/shares.rb @@ -1,10 +1,10 @@ FactoryBot.define do factory :share do utm_source { 'LinkedIn' } - utm_medium { 'community' } - utm_campaign { 'campaignOne' } + utm_medium { 'Organic' } + utm_campaign { 'Blogpromo' } utm_term { 'termOne' } - utm_content { 'campaignContent' } + utm_content { 'Photo' } link end end diff --git a/spec/models/share_spec.rb b/spec/models/share_spec.rb index 757ffbc..40639c2 100644 --- a/spec/models/share_spec.rb +++ b/spec/models/share_spec.rb @@ -1,14 +1,72 @@ require "rails_helper" RSpec.describe Share do + before do + allow_any_instance_of(Link).to receive(:fetch_social_media_snippets).and_return([]) + end + describe "#valid?" do context "when it does not have a link or the minimum requirements" do it "is not valid" do link = Share.new - + expect(link.valid?).to be_falsey expect(link.errors.full_messages).to eq ["Link must exist", "Utm source can't be blank", "Utm campaign can't be blank", "Utm medium can't be blank", "Utm term can't be blank"] end end + + context "on create with an unrecognized utm_source" do + it "is not valid" do + share = build(:share, utm_source: "NotARealSource") + + expect(share.valid?(:create)).to be_falsey + expect(share.errors[:utm_source]).to include("is not included in the list") + end + end + + context "on create with Bluesky as utm_source" do + it "is valid" do + share = build(:share, utm_source: "Bluesky") + + expect(share.valid?(:create)).to be_truthy + end + end + + context "on create with an unrecognized utm_medium" do + it "is not valid" do + share = build(:share, utm_medium: "community") + + expect(share.valid?(:create)).to be_falsey + expect(share.errors[:utm_medium]).to include("is not included in the list") + end + end + + context "on create with an unrecognized utm_campaign" do + it "is not valid" do + share = build(:share, utm_campaign: "campaignOne") + + expect(share.valid?(:create)).to be_falsey + expect(share.errors[:utm_campaign]).to include("is not included in the list") + end + end + + context "on create with an unrecognized utm_content" do + it "is not valid" do + share = build(:share, utm_content: "Custom") + + expect(share.valid?(:create)).to be_falsey + expect(share.errors[:utm_content]).to include("is not included in the list") + end + end + + context "when updating an existing record whose utm_source is no longer in the list" do + it "is allowed (validations are :create-only)" do + share = create(:share) + share.update_column(:utm_source, "LegacyValue") + + share.shortened_url = "https://example.com/abc" + expect(share.save).to be_truthy + end + end end -end \ No newline at end of file +end diff --git a/spec/requests/api_links_spec.rb b/spec/requests/api_links_spec.rb index 73c9af0..ae27ea0 100644 --- a/spec/requests/api_links_spec.rb +++ b/spec/requests/api_links_spec.rb @@ -73,8 +73,8 @@ fastruby_link.social_media_snippets.create!(content: 'Tweet 1', social_media_type: 'Twitter') fastruby_link.social_media_snippets.create!(content: 'LI 1', social_media_type: 'LinkedIn') fastruby_link.shares.create!( - utm_source: 'LinkedIn', utm_medium: 'community', - utm_campaign: 'campaignOne', utm_term: 'termOne' + utm_source: 'LinkedIn', utm_medium: 'Organic', + utm_campaign: 'Blogpromo', utm_term: 'termOne' ) end @@ -104,8 +104,8 @@ describe 'GET /links/:link_id/shares.json' do let!(:share) do fastruby_link.shares.create!( - utm_source: 'LinkedIn', utm_medium: 'community', - utm_campaign: 'campaignOne', utm_term: 'termOne' + utm_source: 'LinkedIn', utm_medium: 'Organic', + utm_campaign: 'Blogpromo', utm_term: 'termOne' ) end @@ -140,8 +140,8 @@ { share: { utm_source: 'LinkedIn', - utm_medium: 'community', - utm_campaign: 'campaignOne', + utm_medium: 'Organic', + utm_campaign: 'Blogpromo', utm_term: 'termOne', utm_content: 'Photo' }