require 'rails_helper'

module Twitch
  RSpec.describe RolesController do
    let(:user) { User.new(email: 'fake@email.unreal') }
    let(:permission) { 'staff_admins_global_mods' }
    include_context 'mocked permissions'

    before do
      allow(User).to receive(:find).with('1234').and_return(user)
    end

    describe '#edit' do
      include_context 'an authorized user acting on a twitch user'

      it 'sets the user' do
        get :edit, params: { user_id: '1234' }
        expect(@controller.view_assigns['user']).to eq(user)
      end
    end

    describe '#update' do
      include_context 'an authorized user acting on a twitch user'

      before do
        allow(Roles).to receive(:update).and_return(nil)
        expect(History::AddAudit).to receive(:add)
          .with({
          action: 'update_role',
          user_type: 'ldap_user',
          user_id: admin_account.ldap_login,
          resource_type: 'twitch_user',
          resource_id: '1234',
          description: 'Elevated user role',
          changes: [
            History::ChangeSet.new(
              attribute: 'authorized_domain',
              new_value: user.email.split('@').last.to_s
            )
          ]
          })
          .once

        patch :update, params: {
          user_id: '1234',
          twitch_user: {
            admin: '1',
            subadmin: '0',
            global_mod: '1'
          }
        }
      end

      it 'sets the roles using the user roles service' do
        expect(Roles).to have_received(:update).with(
          '1234', admin: true, subadmin: false, global_mod: true
        )
      end

      it 'redirects to the user show page' do
        expect(response).to redirect_to '/twitch/users/1234'
      end

      it 'shows a flash success message' do
        expect(flash[:success]).to eq 'Successfully updated user roles.'
      end

    end

    describe '#update' do
      include_context 'an authorized user acting on a twitch user'

      def init_params(params = {})
        {
          user_id: '1234',
          twitch_user: {
            admin: '0',
            subadmin: '0',
            global_mod: '0'
          }.merge(params)
        }
      end

      context 'when the update fails' do
        it "shows an error message if the mod user's email does not have an accepted domain" do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: false,
            subadmin: true,
            global_mod: false
          ).and_raise(UpdateRoles::InvalidEmailError)
          patch :update, params: init_params(subadmin: '1')
          expect(flash[:error]).to eq('Elevated roles must use an email with one of these domains: @mods.twitch.tv, @mods.justin.tv, @amazon.com, @twitch.tv, or @justin.tv')
        end

        it "shows an error message if setting admin role and the user's email does not have an accepted admin domain" do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: true,
            subadmin: false,
            global_mod: false
          ).and_raise(UpdateRoles::InvalidAdminEmailError)
          patch :update, params: init_params(admin: '1')
          expect(flash[:error]).to eq 'Admins must use an email with one of these domains: @twitch.tv or @justin.tv'
        end

        it "shows an error message if setting subadmin role and the user's email does not have an accepted subadmin domain" do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: false,
            subadmin: true,
            global_mod: false
          ).and_raise(UpdateRoles::InvalidSubAdminEmailError)
          patch :update, params: init_params(subadmin: '1')
          expect(flash[:error]).to eq 'Sub-Admins must use an email with one of these domains: @twitch.tv, @justin.tv, @mods.twitch.tv, or @mods.justin.tv'
        end

        it "shows an error message if setting global_mod role and the user's email does not have an accepted global_mod domain" do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: false,
            subadmin: false,
            global_mod: true
          ).and_raise(UpdateRoles::InvalidGlobalModEmailError)
          patch :update, params: init_params(global_mod: '1')
          expect(flash[:error]).to eq 'Mods must use an email with one of these domains: @twitch.tv, @justin.tv, @mods.twitch.tv, @mods.justin.tv, or @amazon.com'
        end

        it "shows an error message if the user's email is not verified" do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: true,
            subadmin: false,
            global_mod: false
          ).and_raise(UpdateRoles::UnverifiedEmailError)
          patch :update, params: init_params(admin: '1')
          expect(flash[:error]).to eq 'User must have a verified email'
        end

        it 'shows an error message if the user does not two factor auth enabled' do
          allow(Roles).to receive(:update).with(
            '1234',
            admin: true,
            subadmin: false,
            global_mod: false
          ).and_raise(UpdateRoles::TwoFactorRequiredError)
          patch :update, params: init_params(admin: '1')
          expect(flash[:error]).to eq 'User must have two-factor authentication enabled'
        end

      end
    end
  end
end
