require "rails_helper" RSpec.describe Profile do let(:user) { create(:user) } let(:profile) { user.profile } describe "validations" do subject { profile } it { is_expected.to validate_uniqueness_of(:user_id) } describe "conditionally validating summary" do let(:invalid_summary) { "x" * ProfileValidator::MAX_SUMMARY_LENGTH.next } it "is valid if users previously had long summaries and are grandfathered" do profile.summary = invalid_summary profile.save(validate: false) profile.summary = "x" * 999 expect(profile).to be_valid end it "is not valid if the summary is too long and the user is not grandfathered" do profile.summary = invalid_summary expect(profile).not_to be_valid expect(profile.errors_as_sentence).to eq "Bio is too long" end it "is valid if the summary is less than the limit" do profile.summary = "Hello 👋" expect(profile).to be_valid end it "counts line ending as a single character when summary is multi line" do profile.summary = "#{'x' * ProfileValidator::MAX_SUMMARY_LENGTH.pred}\r\n" expect(profile).to be_valid end end describe "validating text areas" do let(:text_area_get) { ProfileField.find_by(label: "Test Text Area")&.attribute_name } let(:text_area_set) { "#{text_area_get}=" } before do create(:profile_field, label: "Test Text Area", input_type: :text_area) end it "is valid if the text is short enough" do profile.public_send(text_area_set, "Ruby") expect(profile).to be_valid end it "is invalid if the text is too long" do profile.public_send(text_area_set, "x" * ProfileValidator::MAX_TEXT_AREA_LENGTH.next) expect(profile).not_to be_valid expect(profile.errors_as_sentence) .to include("is too long (maximum is 200 characters)") end it "is valid if text contains new-lines within 200 characters" do profile.public_send( text_area_set, "Lorem Ipsum is simply dummy text of the printing and typesetting industry\r\nLorem Ipsum is simply dummy text of the printing and typesetting industry\r\nLorem Ipsum is simply dummy text of the printing and", ) expect(profile).to be_valid end end describe "validating text fields" do it "is valid if the text is short enough" do profile.location = "Somewhere" expect(profile).to be_valid end it "is invalid if the text is too long" do profile.location = "x" * ProfileValidator::MAX_TEXT_FIELD_LENGTH.next expect(profile).not_to be_valid expect(profile.errors_as_sentence).to eq "Location is too long (maximum is 100 characters)" end end describe "validating website_url" do it "is valid if blank" do profile.website_url = nil expect(profile).to be_valid end it "is valid with a complete url" do profile.website_url = "https://dev.to" expect(profile).to be_valid end it "is invalid with an incomplete url" do profile.website_url = "dev.to" expect(profile).not_to be_valid expect(profile.errors_as_sentence).to eq "Website url is not a valid URL" end end end context "when accessing profile fields" do before do create(:profile_field, label: "Test 1") create(:profile_field, label: "Test 2", input_type: :text_area) end let(:profile) { described_class.new } let(:test1) { ProfileField.find_by(label: "Test 1").attribute_name } let(:test2) { ProfileField.find_by(label: "Test 2").attribute_name } it "defines accessors for active profile fields", :aggregate_failures do expect(profile).to respond_to(test1) expect(profile).to respond_to(test2) end end end