require 'spec_helper'

describe ApiTeachersController, type: :controller do
  render_views
  BIO = "Once a man learned a guitar."

  let(:user)        { FactoryGirl.create(:user) }
  let(:genre1)      { FactoryGirl.create(:genre, :description => "g1") }
  let(:genre2)      { FactoryGirl.create(:genre, :description => "g2") }
  let(:subject1)    { FactoryGirl.create(:subject, :description => "s1") }
  let(:subject2)    { FactoryGirl.create(:subject, :description => "s2") }
  let(:language1)   { FactoryGirl.create(:language, :description => "l1") }
  let(:language2)   { FactoryGirl.create(:language, :description => "l2") }
  let(:instrument1) { FactoryGirl.create(:instrument, :description => 'a great instrument')}
  let(:instrument2) { FactoryGirl.create(:instrument, :description => 'an ok instrument')}

  before(:each) do
    controller.current_user = user
  end

  after(:all) do
    User.destroy_all
    Teacher.destroy_all
  end

  describe "index" do
    it "simple" do
      @teacher = Teacher.save_teacher(
          user,
          years_teaching: 21,
          biography: BIO,
          genres: [genre1, genre2],
          instruments: [instrument1, instrument2],
          languages: [language1, language2],
          subjects: [subject1, subject2]
      )

      get :index
    end
  end
  describe "creates" do
    it "simple" do
      post :create, biography: BIO, format: 'json'
      response.should be_success
      user.reload
      user.teacher.should_not be_nil

      user.teacher.biography.should == BIO
    end


    it "with instruments" do
      post :create, biography: BIO, instruments: [instrument1, instrument2], format: 'json'
      response.should be_success
      user.reload
      user.teacher.should_not be_nil
      t = user.teacher
      t.biography.should == BIO
      t.instruments.should have(2).items
    end

    it "with child records" do
      params = {
        subjects: [subject1.id, subject2.id],
        genres: [genre1.id, genre2.id],
        languages: [language1.id, language2.id],
        teaches_age_lower: 10,
        teaches_age_upper: 20,
        teaches_beginner: true,
        teaches_intermediate: false,
        teaches_advanced: true,
        format: 'json'
      }

      post :create, params

      response.should be_success
      user.reload
      user.teacher.should_not be_nil
      t = user.teacher

      # Genres
      t.genres.should have(2).items

      # Subjects
      t.subjects.should have(2).items

      # Languages
      t.languages.should have(2).items

      t.teaches_age_lower.should == 10
      t.teaches_age_upper.should == 20
      t.teaches_beginner.should be true
      t.teaches_intermediate.should be false
      t.teaches_advanced.should be true
    end
  end

  describe "gets details" do
    before :each do
      @teacher = Teacher.save_teacher(
        user,
        years_teaching: 21,
        biography: BIO,
        genres: [genre1, genre2],
        instruments: [instrument1, instrument2],
        languages: [language1, language2],
        subjects: [subject1, subject2]
      )

      @teacher.should_not be_nil
      @teacher.id.should_not be_nil
    end

    it "by teacher id" do
      get :detail, {:format => 'json', teacher_id: @teacher.id}
      response.should be_success
      json = JSON.parse(response.body)
      json["biography"].should==BIO
    end

    it "by current user" do
      get :detail, {:format => 'json'}
      response.should be_success

      json = JSON.parse(response.body)
      json["biography"].should==BIO
    end

    it "no teacher" do
      user2 = FactoryGirl.create(:user)
      controller.current_user = user2
      get :detail, {:format => 'json'}
      response.status.should eq(404)
    end


    it "and retrieves sub-records" do
      get :detail, {:format => 'json', teacher_id: @teacher.id}
      response.should be_success
      json = JSON.parse(response.body)
      json["genres"].should have(2).items
      json["instruments"].should have(2).items
      json["subjects"].should have(2).items
      json["languages"].should have(2).items

      json["genres"].first.should eq(genre1.id)
      json["instruments"].last.should eq(instrument2.id)
      json["subjects"].first.should eq(subject1.id)
      json["languages"].last.should eq(language2.id)
    end
  end

  describe "to existing" do
    before :each do
      @teacher = Teacher.save_teacher(
        user,
        years_teaching: 21,
        biography: BIO
      )
      @teacher.should_not be_nil
      @teacher.id.should_not be_nil
    end

    it "deletes" do
      delete :delete, {:format => 'json', id: @teacher.id}
      response.should be_success
      user.reload
      user.teacher.should be_nil
    end

    it "with child records" do
      params = {
        id: @teacher.id,
        subjects: [subject1, subject2],
        genres: [genre1, genre2],
        languages: [language1, language2],
        teaches_age_lower: 10,
        teaches_age_upper: 20,
        teaches_beginner: true,
        teaches_intermediate: false,
        teaches_advanced: true,
        format: 'json'
      }

      post :update, params

      response.should be_success
      user.reload
      user.teacher.should_not be_nil
      t = user.teacher

      # Genres
      t.genres.should have(2).items

      # Subjects
      t.subjects.should have(2).items

      # Languages
      t.languages.should have(2).items

      t.teaches_age_lower.should == 10
      t.teaches_age_upper.should == 20
      t.teaches_beginner.should be true
      t.teaches_intermediate.should be false
      t.teaches_advanced.should be true
    end
  end

  describe "validates" do
    it "introduction" do
      post :create, validate_introduction: true, format: 'json'
      response.should_not be_success
      response.status.should eq(422)
      json = JSON.parse(response.body)
      json['errors'].should have_key('biography')

    end

    it "basics" do
      post :create, validate_basics: true, format: 'json'
      response.should_not be_success
      response.status.should eq(422)
      json = JSON.parse(response.body)
      json['errors'].should have_key('instruments')
      json['errors'].should have_key('subjects')
      json['errors'].should have_key('genres')
      json['errors'].should have_key('languages')

      post :create, instruments: [instrument1, instrument2], validate_basics: true, format: 'json'
      response.should_not be_success
      response.status.should eq(422)
      json = JSON.parse(response.body)
      json['errors'].should_not have_key('subjects')
      json['errors'].should_not have_key('instruments')
      json['errors'].should have_key('genres')
      json['errors'].should have_key('languages')
    end

    it "pricing" do
      params = {
        prices_per_lesson: false,
        prices_per_month: false,
        lesson_duration_30: false,
        lesson_duration_45: false,
        lesson_duration_60: false,
        lesson_duration_90: false,
        lesson_duration_120: false,
        price_per_lesson_45_cents: 3000,
        price_per_lesson_120_cents: 3000,
        price_per_month_30_cents: 5000,
        validate_pricing: true,
        format: 'json'
      }
      post :create, params
      response.should_not be_success
      response.status.should eq(422)
      json = JSON.parse(response.body)
      json['errors'].should have_key('offer_pricing')
      json['errors'].should have_key('offer_duration')

      # Add lesson duration and resubmit.  We should only get one error now:
      params[:lesson_duration_45] = true
      post :create, params
      response.should_not be_success
      response.status.should eq(422)
      json = JSON.parse(response.body)
      json['errors'].should have_key('offer_pricing')
      json['errors'].should_not have_key('offer_duration')
      #puts "JSON.pretty_generate(json): #{JSON.pretty_generate(json)}"
    end
  end
end
