Browse Source

Refactoring: Migrate user_out_of_office_test to RSpec

Ryan Lue 6 years ago
parent
commit
5b06840b33
2 changed files with 160 additions and 161 deletions
  1. 160 4
      spec/models/user_spec.rb
  2. 0 157
      test/unit/user_out_of_office_test.rb

+ 160 - 4
spec/models/user_spec.rb

@@ -145,6 +145,49 @@ RSpec.describe User, type: :model do
       end
     end
 
+    describe '#out_of_office?' do
+      context 'without any out_of_office_* attributes set' do
+        it 'returns false' do
+          expect(agent.out_of_office?).to be(false)
+        end
+      end
+
+      context 'with valid #out_of_office_* attributes' do
+        before do
+          agent.update(
+            out_of_office_start_at:       Time.current.yesterday,
+            out_of_office_end_at:         Time.current.tomorrow,
+            out_of_office_replacement_id: 1
+          )
+        end
+
+        context 'but #out_of_office: false' do
+          before { agent.update(out_of_office: false) }
+
+          it 'returns false' do
+            expect(agent.out_of_office?).to be(false)
+          end
+        end
+
+        context 'and #out_of_office: true' do
+          before { agent.update(out_of_office: true) }
+
+          it 'returns true' do
+            expect(agent.out_of_office?).to be(true)
+          end
+
+          context 'after the #out_of_office_end_at time has passed' do
+            before { travel 2.days  }
+
+            it 'returns false (even though #out_of_office has not changed)' do
+              expect(agent.out_of_office).to be(true)
+              expect(agent.out_of_office?).to be(false)
+            end
+          end
+        end
+      end
+    end
+
     describe '#out_of_office_agent' do
       it { is_expected.to respond_to(:out_of_office_agent) }
 
@@ -154,18 +197,72 @@ RSpec.describe User, type: :model do
         end
       end
 
-      context 'when user has designated substitute, and is out of office' do
+      context 'when user has designated substitute' do
         let(:substitute) { create(:user) }
+
         subject(:user) do
           create(:user,
-                 out_of_office:                true,
+                 out_of_office:                out_of_office,
                  out_of_office_start_at:       Time.zone.yesterday,
                  out_of_office_end_at:         Time.zone.tomorrow,
                  out_of_office_replacement_id: substitute.id,)
         end
 
-        it 'returns the designated substitute' do
-          expect(user.out_of_office_agent).to eq(substitute)
+        context 'but is not out of office' do
+          let(:out_of_office) { false }
+
+          it 'returns nil' do
+            expect(user.out_of_office_agent).to be(nil)
+          end
+        end
+
+        context 'and is out of office' do
+          let(:out_of_office) { true }
+
+          it 'returns the designated substitute' do
+            expect(user.out_of_office_agent).to eq(substitute)
+          end
+        end
+      end
+    end
+
+    describe '#out_of_office_agent_of' do
+      context 'when no other agents are out-of-office' do
+        it 'returns an empty ActiveRecord::Relation' do
+          expect(agent.out_of_office_agent_of)
+            .to be_an(ActiveRecord::Relation)
+            .and be_empty
+        end
+      end
+
+      context 'when designated as the substitute' do
+        let!(:agent_on_holiday) do
+          create(
+            :agent_user,
+            out_of_office_start_at:       Time.current.yesterday,
+            out_of_office_end_at:         Time.current.tomorrow,
+            out_of_office_replacement_id: agent.id,
+            out_of_office:                out_of_office
+          )
+        end
+
+        context 'of an in-office agent' do
+          let(:out_of_office) { false }
+
+          it 'returns an empty ActiveRecord::Relation' do
+            expect(agent.out_of_office_agent_of)
+              .to be_an(ActiveRecord::Relation)
+              .and be_empty
+          end
+        end
+
+        context 'of an out-of-office agent' do
+          let(:out_of_office) { true }
+
+          it 'returns an ActiveRecord::Relation including that agent' do
+            expect(agent.out_of_office_agent_of)
+              .to match_array([agent_on_holiday])
+          end
         end
       end
     end
@@ -332,6 +429,65 @@ RSpec.describe User, type: :model do
   end
 
   describe 'Attributes:' do
+    describe '#out_of_office' do
+      context 'with #out_of_office_start_at: nil' do
+        before { agent.update(out_of_office_start_at: nil, out_of_office_end_at: Time.current) }
+
+        it 'cannot be set to true' do
+          expect { agent.update(out_of_office: true) }
+            .to raise_error(Exceptions::UnprocessableEntity)
+        end
+      end
+
+      context 'with #out_of_office_end_at: nil' do
+        before { agent.update(out_of_office_start_at: Time.current, out_of_office_end_at: nil) }
+
+        it 'cannot be set to true' do
+          expect { agent.update(out_of_office: true) }
+            .to raise_error(Exceptions::UnprocessableEntity)
+        end
+      end
+
+      context 'when #out_of_office_start_at is AFTER #out_of_office_end_at' do
+        before { agent.update(out_of_office_start_at: Time.current.tomorrow, out_of_office_end_at: Time.current.next_month) }
+
+        it 'cannot be set to true' do
+          expect { agent.update(out_of_office: true) }
+            .to raise_error(Exceptions::UnprocessableEntity)
+        end
+      end
+
+      context 'when #out_of_office_start_at is AFTER Time.current' do
+        before { agent.update(out_of_office_start_at: Time.current.tomorrow, out_of_office_end_at: Time.current.yesterday) }
+
+        it 'cannot be set to true' do
+          expect { agent.update(out_of_office: true) }
+            .to raise_error(Exceptions::UnprocessableEntity)
+        end
+      end
+
+      context 'when #out_of_office_end_at is BEFORE Time.current' do
+        before { agent.update(out_of_office_start_at: Time.current.last_month, out_of_office_end_at: Time.current.yesterday) }
+
+        it 'cannot be set to true' do
+          expect { agent.update(out_of_office: true) }
+            .to raise_error(Exceptions::UnprocessableEntity)
+        end
+      end
+    end
+
+    describe '#out_of_office_replacement_id' do
+      it 'cannot be set to invalid user ID' do
+        expect { agent.update(out_of_office_replacement_id: User.pluck(:id).max.next) }
+          .to raise_error(ActiveRecord::InvalidForeignKey)
+      end
+
+      it 'can be set to a valid user ID' do
+        expect { agent.update(out_of_office_replacement_id: 1) }
+          .not_to raise_error
+      end
+    end
+
     describe '#login_failed' do
       before { user.update(login_failed: 1) }
 

+ 0 - 157
test/unit/user_out_of_office_test.rb

@@ -1,157 +0,0 @@
-require 'test_helper'
-
-class UserOutOfOfficeTest < ActiveSupport::TestCase
-  setup do
-
-    UserInfo.current_user_id = 1
-
-    groups = Group.all
-    roles = Role.where(name: 'Agent')
-    @agent1 = User.create!(
-      login:         'user-out_of_office-agent1@example.com',
-      firstname:     'UserOutOfOffice',
-      lastname:      'Agent1',
-      email:         'user-out_of_office-agent1@example.com',
-      password:      'agentpw',
-      active:        true,
-      out_of_office: false,
-      roles:         roles,
-      groups:        groups,
-    )
-    @agent2 = User.create!(
-      login:         'user-out_of_office-agent2@example.com',
-      firstname:     'UserOutOfOffice',
-      lastname:      'Agent2',
-      email:         'user-out_of_office-agent2@example.com',
-      password:      'agentpw',
-      active:        true,
-      out_of_office: false,
-      roles:         roles,
-      groups:        groups,
-    )
-    @agent3 = User.create!(
-      login:         'user-out_of_office-agent3@example.com',
-      firstname:     'UserOutOfOffice',
-      lastname:      'Agent3',
-      email:         'user-out_of_office-agent3@example.com',
-      password:      'agentpw',
-      active:        true,
-      out_of_office: false,
-      roles:         roles,
-      groups:        groups,
-    )
-  end
-
-  test 'check out_of_office?' do
-
-    # check
-    assert_not(@agent1.out_of_office?)
-    assert_not(@agent2.out_of_office?)
-    assert_not(@agent3.out_of_office?)
-
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office = true
-      @agent1.out_of_office_start_at = Time.zone.now + 2.days
-      @agent1.out_of_office_end_at = Time.zone.now
-      @agent1.save!
-    end
-
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office = true
-      @agent1.out_of_office_start_at = Time.zone.now
-      @agent1.out_of_office_end_at = Time.zone.now - 2.days
-      @agent1.save!
-    end
-
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office = true
-      @agent1.out_of_office_start_at = nil
-      @agent1.out_of_office_end_at = Time.zone.now
-      @agent1.save!
-    end
-
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office = true
-      @agent1.out_of_office_start_at = Time.zone.now
-      @agent1.out_of_office_end_at = nil
-      @agent1.save!
-    end
-
-    @agent1.out_of_office = false
-    @agent1.out_of_office_start_at = Time.zone.now + 2.days
-    @agent1.out_of_office_end_at = Time.zone.now
-    @agent1.save!
-
-    assert_not(@agent1.out_of_office?)
-
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office = true
-      @agent1.out_of_office_start_at = Time.zone.now + 2.days
-      @agent1.out_of_office_end_at = Time.zone.now + 4.days
-      @agent1.save!
-    end
-    assert_raises(Exceptions::UnprocessableEntity) do
-      @agent1.out_of_office_replacement_id = 999_999_999_999 # not existing
-      @agent1.save!
-    end
-    @agent1.out_of_office_replacement_id = @agent2.id
-    @agent1.save!
-
-    assert_not(@agent1.out_of_office?)
-
-    travel 2.days
-
-    assert(@agent1.out_of_office?)
-    assert(@agent1.out_of_office_agent_of.blank?)
-    assert_equal(1, @agent2.out_of_office_agent_of.count)
-    assert_equal(@agent1.id, @agent2.out_of_office_agent_of[0].id)
-
-    travel 1.day
-
-    assert(@agent1.out_of_office?)
-
-    travel 1.day
-
-    assert(@agent1.out_of_office?)
-
-    travel 1.day
-
-    assert_not(@agent1.out_of_office?)
-
-    assert_not(@agent1.out_of_office_agent)
-
-    assert_not(@agent2.out_of_office_agent)
-
-    assert_equal(0, @agent1.out_of_office_agent_of.count)
-    assert_equal(0, @agent2.out_of_office_agent_of.count)
-
-    @agent2.out_of_office = true
-    @agent2.out_of_office_start_at = Time.zone.now
-    @agent2.out_of_office_end_at = Time.zone.now + 4.days
-    @agent2.out_of_office_replacement_id = @agent3.id
-    @agent2.save!
-
-    assert(@agent2.out_of_office?)
-
-    assert_equal(@agent2.out_of_office_agent.id, @agent3.id)
-
-    assert_equal(0, @agent1.out_of_office_agent_of.count)
-    assert_equal(0, @agent2.out_of_office_agent_of.count)
-    assert_equal(1, @agent3.out_of_office_agent_of.count)
-    assert_equal(@agent2.id, @agent3.out_of_office_agent_of[0].id)
-
-    travel 4.days
-
-    assert_equal(0, @agent1.out_of_office_agent_of.count)
-    assert_equal(0, @agent2.out_of_office_agent_of.count)
-    assert_equal(1, @agent3.out_of_office_agent_of.count)
-    assert_equal(@agent2.id, @agent3.out_of_office_agent_of[0].id)
-
-    travel 1.day
-
-    assert_equal(0, @agent1.out_of_office_agent_of.count)
-    assert_equal(0, @agent2.out_of_office_agent_of.count)
-    assert_equal(0, @agent3.out_of_office_agent_of.count)
-  end
-
-end