RSpec.describe YouTube::LoginPage do
  before(:each) { allow(PageObject::Platforms::WatirWebDriver).to receive(:is_for?).and_return(true) }

  let(:browser) { instance_double(Watir::Browser) }

  subject { YouTube::LoginPage.new(browser) }

  describe '#initialize' do
    it 'does not raise an error' do
      expect { subject }.to_not raise_error
    end
  end

  describe '#login' do
    it 'logs in with the correct credentials from ENV' do
      ClimateControl.modify YOUTUBE_CMS_USER: 'myuser', YOUTUBE_CMS_PASS: 'mysecret' do
        allow(browser).to receive_message_chain('text_field.wait_until_present')
        allow(browser).to receive_message_chain('text_field.set').with('myuser')
        allow(browser).to receive_message_chain('div.wait_until_present')
        allow(browser).to receive_message_chain('div.click')
        allow(browser).to receive_message_chain('div.text_field.wait_until_present')
        allow(browser).to receive_message_chain('div.text_field.set').with('mysecret')
        allow(browser).to receive_message_chain('div.wait_until_present')
        expect(browser).to receive_message_chain('div.click') # submit

        allow(subject).to receive(:logged_in?).and_return(true) # simulate seeing logged-in DOM element

        subject.login
      end
    end

    it 'raises an error when it sees a JS validation message element' do
      ClimateControl.modify YOUTUBE_CMS_USER: 'myuser', YOUTUBE_CMS_PASS: 'mysecret' do
        allow(browser).to receive_message_chain('text_field.wait_until_present')
        allow(browser).to receive_message_chain('text_field.set').with('myuser')
        allow(browser).to receive_message_chain('div.wait_until_present')
        allow(browser).to receive_message_chain('div.click')
        allow(browser).to receive_message_chain('div.text_field.wait_until_present')
        allow(browser).to receive_message_chain('div.text_field.set').with('mysecret')
        allow(browser).to receive_message_chain('div.wait_until_present')
        expect(browser).to receive_message_chain('div.click') # submit

        allow(subject).to receive(:logged_in?).and_return(false)
        allow(subject).to receive(:failure_message).and_return('BAD THINGS are happening') # simulated JS error

        expect { subject.login }.to raise_error(/BAD THINGS/)
      end
    end
  end

  describe '#failure_message' do
    it "returns nil when we don't see a client-side JS validation error" do
      allow(subject).to receive(:login_failure?).and_return(false)
      allow(subject).to receive(:logged_in?).and_return(true)
      expect(subject.failure_message).to be_nil
    end

    it 'raises an error when it fails to see a logged-in DOM element OR a JS validation DOM element' do
      ClimateControl.modify YOUTUBE_CMS_USER: 'myuser', YOUTUBE_CMS_PASS: 'mysecret' do
        allow(subject).to receive(:login_failure?).and_return(true)
        allow(subject).to receive(:login_failure_element).and_return(nil) # perhaps the site changed!

        # Cannot test the first if-conditional, it would look like this...
        # allow(browser).to receive_message_chain('span.exists?').and_return(false)
        # allow(subject).to receive_message_chain('login_failure_element.text.strip.empty?').and_return(nil)

        allow(browser).to receive(:url).and_return('not_even_a_url')

        expect(subject.failure_message).to eq('Unknown login failure! Current URL: not_even_a_url')
      end
    end
  end
end
