groups_controller_spec.rb 11.6 KB
Newer Older
1 2 3
require 'rails_helper'

describe GroupsController do
4
  let(:user) { create(:user) }
5
  let(:group) { create(:group, :public) }
6
  let(:project) { create(:project, namespace: group) }
7 8 9
  let!(:group_member) { create(:group_member, group: group, user: user) }

  describe 'GET #index' do
10 11
    context 'as a user' do
      it 'redirects to Groups Dashboard' do
12
        sign_in(user)
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

        get :index

        expect(response).to redirect_to(dashboard_groups_path)
      end
    end

    context 'as a guest' do
      it 'redirects to Explore Groups' do
        get :index

        expect(response).to redirect_to(explore_groups_path)
      end
    end
  end
28

29
  describe 'GET #subgroups', :nested_groups do
30 31 32 33 34 35 36 37
    let!(:public_subgroup) { create(:group, :public, parent: group) }
    let!(:private_subgroup) { create(:group, :private, parent: group) }

    context 'as a user' do
      before do
        sign_in(user)
      end

38
      it 'shows all subgroups' do
39 40
        get :subgroups, id: group.to_param

41
        expect(assigns(:nested_groups)).to contain_exactly(public_subgroup, private_subgroup)
42 43
      end

44
      context 'being member of private subgroup' do
45
        it 'shows public and private subgroups the user is member of' do
46
          group_member.destroy!
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
          private_subgroup.add_guest(user)

          get :subgroups, id: group.to_param

          expect(assigns(:nested_groups)).to contain_exactly(public_subgroup, private_subgroup)
        end
      end
    end

    context 'as a guest' do
      it 'shows the public subgroups' do
        get :subgroups, id: group.to_param

        expect(assigns(:nested_groups)).to contain_exactly(public_subgroup)
      end
    end
  end

65 66 67 68 69
  describe 'GET #issues' do
    let(:issue_1) { create(:issue, project: project) }
    let(:issue_2) { create(:issue, project: project) }

    before do
70 71
      create_list(:award_emoji, 3, awardable: issue_2)
      create_list(:award_emoji, 2, awardable: issue_1)
72
      create_list(:award_emoji, 2, :downvote, awardable: issue_2)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

      sign_in(user)
    end

    context 'sorting by votes' do
      it 'sorts most popular issues' do
        get :issues, id: group.to_param, sort: 'upvotes_desc'
        expect(assigns(:issues)).to eq [issue_2, issue_1]
      end

      it 'sorts least popular issues' do
        get :issues, id: group.to_param, sort: 'downvotes_desc'
        expect(assigns(:issues)).to eq [issue_2, issue_1]
      end
    end
  end

  describe 'GET #merge_requests' do
    let(:merge_request_1) { create(:merge_request, source_project: project) }
    let(:merge_request_2) { create(:merge_request, :simple, source_project: project) }

    before do
95 96
      create_list(:award_emoji, 3, awardable: merge_request_2)
      create_list(:award_emoji, 2, awardable: merge_request_1)
Z
Z.J. van de Weg 已提交
97
      create_list(:award_emoji, 2, :downvote, awardable: merge_request_2)
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

      sign_in(user)
    end

    context 'sorting by votes' do
      it 'sorts most popular merge requests' do
        get :merge_requests, id: group.to_param, sort: 'upvotes_desc'
        expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1]
      end

      it 'sorts least popular merge requests' do
        get :merge_requests, id: group.to_param, sort: 'downvotes_desc'
        expect(assigns(:merge_requests)).to eq [merge_request_2, merge_request_1]
      end
    end
  end
114 115 116 117 118 119

  describe 'DELETE #destroy' do
    context 'as another user' do
      it 'returns 404' do
        sign_in(create(:user))

120
        delete :destroy, id: group.to_param
121 122 123 124 125 126 127 128 129 130 131

        expect(response.status).to eq(404)
      end
    end

    context 'as the group owner' do
      before do
        sign_in(user)
      end

      it 'schedules a group destroy' do
132
        Sidekiq::Testing.fake! do
133
          expect { delete :destroy, id: group.to_param }.to change(GroupDestroyWorker.jobs, :size).by(1)
134
        end
135 136 137
      end

      it 'redirects to the root path' do
138
        delete :destroy, id: group.to_param
139 140 141 142 143

        expect(response).to redirect_to(root_path)
      end
    end
  end
144 145 146 147 148 149

  describe 'PUT update' do
    before do
      sign_in(user)
    end

150
    it 'updates the path successfully' do
151 152 153 154 155 156 157 158 159 160
      post :update, id: group.to_param, group: { path: 'new_path' }

      expect(response).to have_http_status(302)
      expect(controller).to set_flash[:notice]
    end

    it 'does not update the path on error' do
      allow_any_instance_of(Group).to receive(:move_dir).and_raise(Gitlab::UpdatePathError)
      post :update, id: group.to_param, group: { path: 'new_path' }

J
James Lopez 已提交
161 162
      expect(assigns(:group).errors).not_to be_empty
      expect(assigns(:group).path).not_to eq('new_path')
163
    end
164 165 166 167 168 169 170 171 172 173 174 175 176
  end

  describe '#ensure_canonical_path' do
    before do
      sign_in(user)
    end

    context 'for a GET request' do
      context 'when requesting groups at the root path' do
        before do
          allow(request).to receive(:original_fullpath).and_return("/#{group_full_path}")
          get :show, id: group_full_path
        end
177

178 179
        context 'when requesting the canonical path with different casing' do
          let(:group_full_path) { group.to_param.upcase }
180

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
          it 'redirects to the correct casing' do
            expect(response).to redirect_to(group)
            expect(controller).not_to set_flash[:notice]
          end
        end

        context 'when requesting a redirected path' do
          let(:redirect_route) { group.redirect_routes.create(path: 'old-path') }
          let(:group_full_path) { redirect_route.path }

          it 'redirects to the canonical path' do
            expect(response).to redirect_to(group)
            expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
          end

          context 'when the old group path is a substring of the scheme or host' do
            let(:redirect_route) { group.redirect_routes.create(path: 'http') }

            it 'does not modify the requested host' do
              expect(response).to redirect_to(group)
              expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
            end
          end

          context 'when the old group path is substring of groups' do
            # I.e. /groups/oups should not become /grfoo/oups
            let(:redirect_route) { group.redirect_routes.create(path: 'oups') }

            it 'does not modify the /groups part of the path' do
              expect(response).to redirect_to(group)
              expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
            end
          end
        end
215 216
      end

217
      context 'when requesting groups under the /groups path' do
218 219 220 221 222 223 224 225 226
        context 'when requesting the canonical path' do
          context 'non-show path' do
            context 'with exactly matching casing' do
              it 'does not redirect' do
                get :issues, id: group.to_param

                expect(response).not_to have_http_status(301)
              end
            end
227

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
            context 'with different casing' do
              it 'redirects to the correct casing' do
                get :issues, id: group.to_param.upcase

                expect(response).to redirect_to(issues_group_path(group.to_param))
                expect(controller).not_to set_flash[:notice]
              end
            end
          end

          context 'show path' do
            context 'with exactly matching casing' do
              it 'does not redirect' do
                get :show, id: group.to_param

                expect(response).not_to have_http_status(301)
              end
            end

            context 'with different casing' do
              it 'redirects to the correct casing at the root path' do
                get :show, id: group.to_param.upcase

                expect(response).to redirect_to(group)
                expect(controller).not_to set_flash[:notice]
              end
            end
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
          end
        end

        context 'when requesting a redirected path' do
          let(:redirect_route) { group.redirect_routes.create(path: 'old-path') }

          it 'redirects to the canonical path' do
            get :issues, id: redirect_route.path

            expect(response).to redirect_to(issues_group_path(group.to_param))
            expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
          end

          context 'when the old group path is a substring of the scheme or host' do
            let(:redirect_route) { group.redirect_routes.create(path: 'http') }

            it 'does not modify the requested host' do
              get :issues, id: redirect_route.path

              expect(response).to redirect_to(issues_group_path(group.to_param))
              expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
            end
          end

          context 'when the old group path is substring of groups' do
            # I.e. /groups/oups should not become /grfoo/oups
            let(:redirect_route) { group.redirect_routes.create(path: 'oups') }

            it 'does not modify the /groups part of the path' do
              get :issues, id: redirect_route.path

              expect(response).to redirect_to(issues_group_path(group.to_param))
              expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
            end
          end

          context 'when the old group path is substring of groups plus the new path' do
            # I.e. /groups/oups/oup should not become /grfoos
            let(:redirect_route) { group.redirect_routes.create(path: 'oups/oup') }

            it 'does not modify the /groups part of the path' do
              get :issues, id: redirect_route.path

              expect(response).to redirect_to(issues_group_path(group.to_param))
              expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
            end
          end
        end
303 304 305
      end
    end

306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
    context 'for a POST request' do
      context 'when requesting the canonical path with different casing' do
        it 'does not 404' do
          post :update, id: group.to_param.upcase, group: { path: 'new_path' }

          expect(response).not_to have_http_status(404)
        end

        it 'does not redirect to the correct casing' do
          post :update, id: group.to_param.upcase, group: { path: 'new_path' }

          expect(response).not_to have_http_status(301)
        end
      end

      context 'when requesting a redirected path' do
        let(:redirect_route) { group.redirect_routes.create(path: 'old-path') }
323

324 325
        it 'returns not found' do
          post :update, id: redirect_route.path, group: { path: 'new_path' }
326

327 328
          expect(response).to have_http_status(404)
        end
329 330
      end
    end
331

332 333 334 335
    context 'for a DELETE request' do
      context 'when requesting the canonical path with different casing' do
        it 'does not 404' do
          delete :destroy, id: group.to_param.upcase
336

337 338
          expect(response).not_to have_http_status(404)
        end
339

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
        it 'does not redirect to the correct casing' do
          delete :destroy, id: group.to_param.upcase

          expect(response).not_to have_http_status(301)
        end
      end

      context 'when requesting a redirected path' do
        let(:redirect_route) { group.redirect_routes.create(path: 'old-path') }

        it 'returns not found' do
          delete :destroy, id: redirect_route.path

          expect(response).to have_http_status(404)
        end
355 356 357 358
      end
    end
  end

359 360 361
  def group_moved_message(redirect_route, group)
    "Group '#{redirect_route.path}' was moved to '#{group.full_path}'. Please update any links and bookmarks that may still have the old path."
  end
362
end