diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index e7f7845098..20f0aba26d 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -15,6 +15,7 @@ class Enterprise < ApplicationRecord medium: { resize_to_fill: [720, 156] }, large: { resize_to_fill: [1200, 260] }, }.freeze + VALID_INSTAGRAM_REGEX = %r{\A[a-zA-Z0-9._]{1,30}([^/-]*)\z} searchable_attributes :sells, :is_primary_producer searchable_associations :properties @@ -99,6 +100,7 @@ class Enterprise < ApplicationRecord validate :shopfront_taxons validate :shopfront_producers validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? } + validates :instagram, format: { with: VALID_INSTAGRAM_REGEX, message: Spree.t('errors.messages.invalid_instagram_url') }, allow_blank: true before_validation :initialize_permalink, if: lambda { permalink.nil? } before_validation :set_unused_address_fields @@ -456,7 +458,7 @@ class Enterprise < ApplicationRecord end def correct_instagram_url(url) - url && strip_url(url).sub(%r{www.instagram.com/}, '').delete("@") + url && strip_url(url.downcase).sub(%r{www.instagram.com/}, '').sub(%r{instagram.com/}, '').delete("@") end def correct_twitter_url(url) diff --git a/config/locales/en.yml b/config/locales/en.yml index 9c38d6b867..9bc77724d9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3780,6 +3780,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using messages: included_price_validation: "cannot be selected unless you have set a Default Tax Zone" blank: "can't be blank" + invalid_instagram_url: "Must be user name only eg. the_prof" layouts: admin: login_nav: diff --git a/db/migrate/20221208150521_update_enterprise_instagram_links.rb b/db/migrate/20221208150521_update_enterprise_instagram_links.rb new file mode 100644 index 0000000000..8bcd7d9b10 --- /dev/null +++ b/db/migrate/20221208150521_update_enterprise_instagram_links.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class UpdateEnterpriseInstagramLinks < ActiveRecord::Migration[6.1] + class Enterprise < ActiveRecord::Base + def strip_url(url) + url&.sub(%r{(https?://)?}, '') + end + + def correct_instagram_url(url) + url && strip_url(url.downcase).sub(%r{www.instagram.com/}, '').sub(%r{instagram.com/}, + '').delete("@") + end + + def instagram + correct_instagram_url self[:instagram] + end + end + + def up + Enterprise.where.not(instagram: nil).find_each do |enterprise| + enterprise.update!(instagram: enterprise.instagram) + enterprise.save! + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/schema.rb b/db/schema.rb index b38959a8aa..bf1adb58c3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_11_16_095826) do +ActiveRecord::Schema.define(version: 2022_12_08_150521) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/migrations/update_enterprise_instagram_links_spec.rb b/spec/migrations/update_enterprise_instagram_links_spec.rb new file mode 100644 index 0000000000..99a2a770f0 --- /dev/null +++ b/spec/migrations/update_enterprise_instagram_links_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require Rails.root.join('db/migrate/20221208150521_update_enterprise_instagram_links.rb') + +describe UpdateEnterpriseInstagramLinks do + let!(:enterprise1) { create(:enterprise, instagram: "https://www.instagram.com/happyfarm") } + + let!(:enterprise2) { create(:enterprise, instagram: "@happyfarm") } + + let!(:enterprise3) { create(:enterprise, instagram: "happyfarm") } + + # rubocop:disable Style/NumericLiterals + + let(:current_version) { 20221208150521 } + + # rubocop:enable Style/NumericLiterals + + subject { ActiveRecord::Migrator.new(:up, migrations, current_version).migrate } + + context "when link includes https://www.instagram.com/" do + it "removes https://www.instagram.com/" do + expect(enterprise1.instagram).to eq("happyfarm") + end + end + + context "when link includes @" do + it "removes @" do + expect(enterprise2.instagram).to eq("happyfarm") + end + end + + context "when link includes only the username" do + it "does nothing" do + expect(enterprise3.instagram).to eq("happyfarm") + end + end +end diff --git a/spec/models/enterprise_spec.rb b/spec/models/enterprise_spec.rb index 7a0df9afda..cbc26efa41 100644 --- a/spec/models/enterprise_spec.rb +++ b/spec/models/enterprise_spec.rb @@ -155,6 +155,94 @@ describe Enterprise do end end + describe "prevent a wrong instagram link pattern" do + it "invalidates the instagram attribute https://facebook.com/user" do + e = build(:enterprise, instagram: 'https://facebook.com/user') + expect(e).to_not be_valid + end + + it "invalidates the instagram attribute tagram.com/user" do + e = build(:enterprise, instagram: 'tagram.com/user') + expect(e).to_not be_valid + end + + it "invalidates the instagram attribute https://instagram.com/user/preferences" do + e = build(:enterprise, instagram: 'https://instagram.com/user/preferences') + expect(e).to_not be_valid + end + + it "invalidates the instagram attribute https://instagram.com/user/" do + e = build(:enterprise, instagram: 'https://instagram.com/user/') + expect(e).to_not be_valid + end + + it "invalidates the instagram attribute https://instagram.com/user-user" do + e = build(:enterprise, instagram: 'https://instagram.com/user-user') + expect(e).to_not be_valid + end + end + + describe "Verify accepted instagram url pattern" do + it "validates empty instagram attribute" do + e = build(:enterprise, instagram: '') + expect(e).to be_valid + expect(e.instagram).to eq "" + end + + it "validates the instagram attribute @my_user" do + e = build(:enterprise, instagram: '@my_user') + expect(e).to be_valid + expect(e.instagram).to eq "my_user" + end + + it "validates the instagram attribute user" do + e = build(:enterprise, instagram: 'user') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "validates the instagram attribute my_www5.example" do + e = build(:enterprise, instagram: 'my_www5.example') + expect(e).to be_valid + expect(e.instagram).to eq "my_www5.example" + end + + it "validates the instagram attribute http://instagram.com/user" do + e = build(:enterprise, instagram: 'http://instagram.com/user') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "validates the instagram attribute https://www.instagram.com/user" do + e = build(:enterprise, instagram: 'https://www.instagram.com/user') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "validates the instagram attribute instagram.com/@user" do + e = build(:enterprise, instagram: 'instagram.com/@user') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "validates the instagram attribute Https://www.Instagram.com/@User" do + e = build(:enterprise, instagram: 'Https://www.Instagram.com/@User') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "validates the instagram attribute instagram.com/user" do + e = build(:enterprise, instagram: 'instagram.com/user') + expect(e).to be_valid + expect(e.instagram).to eq "user" + end + + it "renders the expected pattern" do + e = build(:enterprise, instagram: 'instagram.com/user') + expect(e.instagram).to eq "user" + end + end + describe "preferred_shopfront_taxon_order" do it "empty strings are valid" do enterprise = build(:enterprise, preferred_shopfront_taxon_order: "") diff --git a/spec/system/consumer/registration_spec.rb b/spec/system/consumer/registration_spec.rb index 1ccb014ce2..17329c3169 100644 --- a/spec/system/consumer/registration_spec.rb +++ b/spec/system/consumer/registration_spec.rb @@ -136,7 +136,7 @@ describe "Registration", js: true do expect(e.facebook).to eq "FaCeBoOk" expect(e.linkedin).to eq "LiNkEdIn" expect(e.twitter).to eq "TwItTeR" - expect(e.instagram).to eq "InStAgRaM" + expect(e.instagram).to eq "instagram" click_link "Go to Enterprise Dashboard" expect(page).to have_content "CHOOSE YOUR PACKAGE"