require "spec_helper"

describe Schleuder::Subscription do
  BOOLEAN_SUBSCRIPTION_ATTRIBUTES =
    [
      :delivery_enabled,
      :admin
  ].freeze

  it "has a valid factory" do
    subscription = create(:subscription)

    expect(subscription).to be_valid
  end

  it { is_expected.to respond_to :list_id }
  it { is_expected.to respond_to :email }
  it { is_expected.to respond_to :fingerprint }
  it { is_expected.to respond_to :admin }
  it { is_expected.to respond_to :delivery_enabled }

  it "is invalid when list_id is blank" do
    subscription = build(:subscription, list_id: "")

    expect(subscription).not_to be_valid
    expect(subscription.errors.messages[:list_id]).to be_present
  end

  it "is invalid when email is nil" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, email: nil)

    expect(subscription).not_to be_valid
    expect(subscription.errors.messages[:email]).to include("can't be blank")
  end

   it "is invalid when email is blank" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, email: "")

    expect(subscription).not_to be_valid
    expect(subscription.errors.messages[:email]).to include("can't be blank")
  end

  it "is invalid when email does not contain an @" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, email: "fooatbar.org")

    expect(subscription).not_to be_valid
    expect(subscription.errors.messages[:email]).to include("is not a valid email address")
  end

  it "formats email address when email begins with a space" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, email: " foo@bar.org")

    expect(subscription).to be_valid
    expect(subscription.email).to be_eql('foo@bar.org')
    expect(subscription.errors.messages[:email]).to be_blank
  end

  it "is valid when fingerprint is empty" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, fingerprint: "")

    expect(subscription).to be_valid
    expect(subscription.errors.messages[:fingerprint]).to be_blank
  end

  it "is valid when fingerprint is nil" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, fingerprint: nil)

    expect(subscription).to be_valid
    expect(subscription.errors.messages[:fingerprint]).to be_blank
  end

  it "is invalid when fingerprint contains invalid characters" do
    list = create(:list)
    subscription = build(:subscription, list_id: list.id, fingerprint: "&$$$$123AAA")

    expect(subscription).not_to be_valid
    expect(subscription.errors.messages[:fingerprint]).to include("is not a valid OpenPGP-fingerprint")
  end

  BOOLEAN_SUBSCRIPTION_ATTRIBUTES.each do |subscription_attribute|
    it "is invalid if #{subscription_attribute} is nil" do
      list = create(:list)
      subscription = build(:subscription, list_id: list.id)
      subscription[subscription_attribute] = nil

      expect(subscription).not_to be_valid
      expect(subscription.errors.messages[subscription_attribute]).to include("must be true or false")
    end

    it "is invalid if #{subscription_attribute} is blank" do
      list = create(:list)
      subscription = build(:subscription, list_id: list.id)
      subscription[subscription_attribute] = ""

      expect(subscription).not_to be_valid
      expect(subscription.errors.messages[subscription_attribute]).to include("must be true or false")
    end
  end

  it "is invalid if the given email is already subscribed for the list" do
    list1 = create(:list)
    list2 = create(:list)
    subscription1 = create(:subscription, list_id: list1.id)
    subscription2 = create(:subscription, list_id: list2.id, email: subscription1.email)
    subscription3 = build(:subscription, email: subscription1.email, list_id: subscription1.list_id)

    expect(subscription1).to be_valid
    expect(subscription2).to be_valid
    expect(subscription3).not_to be_valid
    expect(subscription3.errors[:email]).to eql(["is already subscribed"])
  end

  describe "#fingerprint" do
    it "transforms the fingerprint to upper case" do
      subscription = Schleuder::Subscription.new(email: "example@example.org", fingerprint: "c4d60f8833789c7caa44496fd3ffa6613ab10ece")

      expect(subscription.fingerprint).to eq("C4D60F8833789C7CAA44496FD3FFA6613AB10ECE")
    end
  end

  it "removes whitespaces and 0x from the fingerprint" do
    fingerprint = "0x 99 991 1000 10"
    subscription = build(:subscription, fingerprint: fingerprint)

    expect(subscription.fingerprint).to eq "99991100010"
  end
end

