# frozen_string_literal: true

#
#  Copyright (c) 2012-2020, CVP Schweiz. This file is part of
#  hitobito_cvp and licensed under the Affero General Public License version 3
#  or later. See the COPYING file at the top-level directory or at
#  https://github.com/hitobito/hitobito_cvp.

require "spec_helper"

describe Contactable::EmailValidator do
  let(:validator) { described_class.new }
  let(:top_leader) { people(:top_leader) }
  let(:bottom_member) { people(:bottom_member) }

  before { allow(Truemail).to receive(:valid?).and_call_original }

  it "ignores person with blank email" do
    top_leader.email = nil
    top_leader.save!(validate: false)
    validator.validate_people
    expect(taggings_for(top_leader).count).to eq(0)
  end

  it "tags people with invalid primary e-mail" do
    top_leader.update_columns(email: "not-an-email")

    validator.validate_people

    expect(taggings_for(top_leader).count).to eq(1)
    leader_tagging = taggings_for(top_leader).first
    expect(leader_tagging.tag.name).to eq("category_validation:email_primary_invalid")
    expect(leader_tagging.context).to eq("tags")
    expect(leader_tagging.hitobito_tooltip).to eq("not-an-email")
  end

  it "keeps existing invalid e-mail tag" do
    top_leader.update_columns(email: "not-an-email")
    create_invalid_additional_email(top_leader, "not-an-email")

    validator.validate_people

    expect(taggings_for(top_leader).count).to eq(2)

    validator.validate_people

    leader_tagging_primary = taggings_for(top_leader).first
    expect(leader_tagging_primary.tag.name).to eq("category_validation:email_primary_invalid")

    leader_tagging_additional = taggings_for(top_leader).second
    expect(leader_tagging_additional.tag.name).to eq("category_validation:email_additional_invalid")
  end

  it "tags people with invalid additional e-mail" do
    create_invalid_additional_email(bottom_member, "not-an-email")
    create_invalid_additional_email(bottom_member, "mail@nodomain")

    validator.validate_people

    expect(taggings_for(bottom_member).count).to eq(1)
    member_tagging = taggings_for(bottom_member).first
    expect(member_tagging.tag.name).to eq("category_validation:email_additional_invalid")
    expect(member_tagging.context).to eq("tags")
    expect(member_tagging.hitobito_tooltip).to eq("not-an-email mail@nodomain")
  end

  it "tags people with invalid primary and additional e-mail" do
    top_leader.update_columns(email: "not-an-email")
    create_invalid_additional_email(top_leader, "not-an-email")

    validator.validate_people

    expect(taggings_for(top_leader).count).to eq(2)

    leader_tagging_primary = taggings_for(top_leader).first
    expect(leader_tagging_primary.tag.name).to eq("category_validation:email_primary_invalid")
    expect(leader_tagging_primary.context).to eq("tags")
    expect(leader_tagging_primary.hitobito_tooltip).to eq("not-an-email")

    leader_tagging_additional = taggings_for(top_leader).second
    expect(leader_tagging_additional.tag.name).to eq("category_validation:email_additional_invalid")
    expect(leader_tagging_additional.context).to eq("tags")
    expect(leader_tagging_additional.hitobito_tooltip).to eq("not-an-email")
  end

  private

  def taggings_for(person)
    ActsAsTaggableOn::Tagging
      .where(taggable: person)
  end

  def create_invalid_additional_email(person, email)
    AdditionalEmail
      .new(contactable: person,
        email: email)
      .save!(validate: false)
  end
end
