require 'spec_helper'

describe Account do
  subject { Factory(:account) }

  it { should have_many(:memberships) }
  it { should have_many(:users).through(:memberships) }
  it { should have_many(:projects) }
  it { should belong_to(:plan) }

  it { should validate_uniqueness_of(:name) }
  it { should validate_uniqueness_of(:keyword) }
  it { should validate_presence_of(  :name) }
  it { should validate_presence_of(:keyword) }
  it { should validate_presence_of(:plan_id) }

  it { should_not allow_mass_assignment_of(:id) }
  it { should_not allow_mass_assignment_of(:updated_at) }
  it { should_not allow_mass_assignment_of(:created_at) }
  it { should allow_mass_assignment_of(:keyword) }

  [nil, "", "a b", "a.b", "a%b"].each do |value|
    it { should_not allow_value(value).for(:keyword).with_message(/letters/i) }
  end

  ["foo", "f00", "37signals"].each do |value|
    it { should allow_value(value).for(:keyword) }
  end

  it "should give its keyword for to_param" do
    subject.to_param.should == subject.keyword
  end

  it "finds admin users" do
    admins = [Factory(:user), Factory(:user)]
    non_admin = Factory(:user)
    non_member = Factory(:user)
    admins.each do |admin|
      Factory(:membership, :user => admin, :account => subject, :admin => true)
    end
    Factory(:membership, :user => non_admin, :account => subject, :admin => false)

    result = subject.admins

    result.to_a.should =~ admins
  end

  it "has a member with a membership" do
    membership = Factory(:membership, :account => subject)
    should have_member(membership.user)
  end

  it "doesn't have a member without a membership" do
    membership = Factory(:membership, :account => subject)
    should_not have_member(Factory(:user))
  end

  it "finds memberships by name" do
    expected = 'expected result'
    memberships = stub('memberships', :by_name => expected)
    account = Factory.stub(:account)
    account.stubs(:memberships => memberships)

    result = account.memberships_by_name

    result.should == expected
  end

  it "is expired with a trial plan after 30 days" do
    trial = Factory(:plan, :trial => true)
    Factory(:account, :created_at => 30.days.ago, :plan => trial).should be_expired
  end

  it "isn't expired with a trial plan before 30 days" do
    trial = Factory(:plan, :trial => true)
    Factory(:account, :created_at => 29.days.ago, :plan => trial).should_not be_expired
  end

  it "isn't expired with a non-trial plan after 30 days" do
    forever = Factory(:plan, :trial => false)
    Factory(:account, :created_at => 30.days.ago, :plan => forever).should_not be_expired
  end

  it "sends notifications for expiring accounts" do
    trial   = Factory(:plan, :trial => true)
    forever = Factory(:plan, :trial => false)

    expiring         = [Factory(:account, :plan => trial, :created_at => 23.days.ago),
                        Factory(:account, :plan => trial, :created_at => 24.days.ago)]
    forever          = Factory(:account, :plan => forever, :created_at => 23.days.ago)
    new_trial        = Factory(:account, :plan => trial, :created_at => 22.days.ago)
    already_notified = Factory(:account, :plan                   => trial,
                                         :created_at             => 24.days.ago,
                                         :notified_of_expiration => true)

    mail = stub('mail', :deliver => true)
    BillingMailer.stubs(:expiring_trial => mail)

    Account.deliver_expiring_trial_notifications

    expiring.each do |account|
      BillingMailer.should have_received(:expiring_trial).with(account)
    end

    mail.should have_received(:deliver).twice
  end
end