BigW Consortium Gitlab

routable_spec.rb 6.14 KB
Newer Older
1 2 3
require 'spec_helper'

describe Group, 'Routable' do
4
  let!(:group) { create(:group, name: 'foo') }
5

6 7 8 9
  describe 'Validations' do
    it { is_expected.to validate_presence_of(:route) }
  end

10 11
  describe 'Associations' do
    it { is_expected.to have_one(:route).dependent(:destroy) }
12
    it { is_expected.to have_many(:redirect_routes).dependent(:destroy) }
13 14 15 16 17
  end

  describe 'Callbacks' do
    it 'creates route record on create' do
      expect(group.route.path).to eq(group.path)
18
      expect(group.route.name).to eq(group.name)
19 20 21
    end

    it 'updates route record on path change' do
22
      group.update_attributes(path: 'wow', name: 'much')
23 24

      expect(group.route.path).to eq('wow')
25
      expect(group.route.name).to eq('much')
26 27 28 29 30 31 32 33 34 35 36 37 38
    end

    it 'ensure route path uniqueness across different objects' do
      create(:group, parent: group, path: 'xyz')
      duplicate = build(:project, namespace: group, path: 'xyz')

      expect { duplicate.save! }.to raise_error(ActiveRecord::RecordInvalid, 'Validation failed: Route path has already been taken, Route is invalid')
    end
  end

  describe '.find_by_full_path' do
    let!(:nested_group) { create(:group, parent: group) }

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    context 'without any redirect routes' do
      it { expect(described_class.find_by_full_path(group.to_param)).to eq(group) }
      it { expect(described_class.find_by_full_path(group.to_param.upcase)).to eq(group) }
      it { expect(described_class.find_by_full_path(nested_group.to_param)).to eq(nested_group) }
      it { expect(described_class.find_by_full_path('unknown')).to eq(nil) }
    end

    context 'with redirect routes' do
      let!(:group_redirect_route) { group.redirect_routes.create!(path: 'bar') }
      let!(:nested_group_redirect_route) { nested_group.redirect_routes.create!(path: nested_group.path.sub('foo', 'bar')) }

      context 'without follow_redirects option' do
        context 'with the given path not matching any route' do
          it { expect(described_class.find_by_full_path('unknown')).to eq(nil) }
        end

        context 'with the given path matching the canonical route' do
          it { expect(described_class.find_by_full_path(group.to_param)).to eq(group) }
          it { expect(described_class.find_by_full_path(group.to_param.upcase)).to eq(group) }
          it { expect(described_class.find_by_full_path(nested_group.to_param)).to eq(nested_group) }
        end

        context 'with the given path matching a redirect route' do
          it { expect(described_class.find_by_full_path(group_redirect_route.path)).to eq(nil) }
          it { expect(described_class.find_by_full_path(group_redirect_route.path.upcase)).to eq(nil) }
          it { expect(described_class.find_by_full_path(nested_group_redirect_route.path)).to eq(nil) }
        end
      end

      context 'with follow_redirects option set to true' do
        context 'with the given path not matching any route' do
          it { expect(described_class.find_by_full_path('unknown', follow_redirects: true)).to eq(nil) }
        end

        context 'with the given path matching the canonical route' do
          it { expect(described_class.find_by_full_path(group.to_param, follow_redirects: true)).to eq(group) }
          it { expect(described_class.find_by_full_path(group.to_param.upcase, follow_redirects: true)).to eq(group) }
          it { expect(described_class.find_by_full_path(nested_group.to_param, follow_redirects: true)).to eq(nested_group) }
        end

        context 'with the given path matching a redirect route' do
          it { expect(described_class.find_by_full_path(group_redirect_route.path, follow_redirects: true)).to eq(group) }
          it { expect(described_class.find_by_full_path(group_redirect_route.path.upcase, follow_redirects: true)).to eq(group) }
          it { expect(described_class.find_by_full_path(nested_group_redirect_route.path, follow_redirects: true)).to eq(nested_group) }
        end
      end
    end
86 87
  end

88
  describe '.where_full_path_in' do
89 90
    context 'without any paths' do
      it 'returns an empty relation' do
91
        expect(described_class.where_full_path_in([])).to eq([])
92 93 94 95 96
      end
    end

    context 'without any valid paths' do
      it 'returns an empty relation' do
97
        expect(described_class.where_full_path_in(%w[unknown])).to eq([])
98 99 100 101 102 103 104
      end
    end

    context 'with valid paths' do
      let!(:nested_group) { create(:group, parent: group) }

      it 'returns the projects matching the paths' do
105
        result = described_class.where_full_path_in([group.to_param, nested_group.to_param])
106 107 108 109 110

        expect(result).to contain_exactly(group, nested_group)
      end

      it 'returns projects regardless of the casing of paths' do
111
        result = described_class.where_full_path_in([group.to_param.upcase, nested_group.to_param.upcase])
112 113 114 115 116

        expect(result).to contain_exactly(group, nested_group)
      end
    end
  end
117

118 119 120 121 122
  describe '#full_path' do
    let(:group) { create(:group) }
    let(:nested_group) { create(:group, parent: group) }

    it { expect(group.full_path).to eq(group.path) }
123
    it { expect(nested_group.full_path).to eq("#{group.full_path}/#{nested_group.path}") }
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

    context 'with RequestStore active' do
      before do
        RequestStore.begin!
      end

      after do
        RequestStore.end!
        RequestStore.clear!
      end

      it 'does not load the route table more than once' do
        expect(group).to receive(:uncached_full_path).once.and_call_original

        3.times { group.full_path }
        expect(group.full_path).to eq(group.path)
      end
    end
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
  end

  describe '#full_name' do
    let(:group) { create(:group) }
    let(:nested_group) { create(:group, parent: group) }

    it { expect(group.full_name).to eq(group.name) }
    it { expect(nested_group.full_name).to eq("#{group.name} / #{nested_group.name}") }
  end
end

describe Project, 'Routable' do
  describe '#full_path' do
    let(:project) { build_stubbed(:empty_project) }

157
    it { expect(project.full_path).to eq "#{project.namespace.full_path}/#{project.path}" }
158 159 160 161 162 163 164
  end

  describe '#full_name' do
    let(:project) { build_stubbed(:empty_project) }

    it { expect(project.full_name).to eq "#{project.namespace.human_name} / #{project.name}" }
  end
165
end