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

describe GroupsController do
4 5
  let(:user) { create(:user) }
  let(:group) { create(:group) }
6
  let(:project) { create(:empty_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 30 31 32 33 34 35 36 37 38 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
  describe 'GET #subgroups' do
    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

      it 'shows the public subgroups' do
        get :subgroups, id: group.to_param

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

      context 'being member' do
        it 'shows public and private subgroups the user is member of' do
          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

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

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

      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
94 95
      create_list(:award_emoji, 3, awardable: merge_request_2)
      create_list(:award_emoji, 2, awardable: merge_request_1)
Z
Z.J. van de Weg 已提交
96
      create_list(:award_emoji, 2, :downvote, awardable: merge_request_2)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

      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
113 114 115 116 117 118

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

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

        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
131
        Sidekiq::Testing.fake! do
132
          expect { delete :destroy, id: group.to_param }.to change(GroupDestroyWorker.jobs, :size).by(1)
133
        end
134 135 136
      end

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

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

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

149
    it 'updates the path successfully' do
150 151 152 153 154 155 156 157 158 159
      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 已提交
160 161
      expect(assigns(:group).errors).not_to be_empty
      expect(assigns(:group).path).not_to eq('new_path')
162
    end
163 164 165 166 167 168 169 170 171 172 173 174 175
  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
176

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

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
          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
214 215
      end

216 217 218 219
      context 'when requesting groups under the /groups path' do
        context 'when requesting the canonical path with different casing' do
          it 'redirects to the correct casing' do
            get :issues, id: group.to_param.upcase
220

221 222 223 224 225 226 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 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
            expect(response).to redirect_to(issues_group_path(group.to_param))
            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') }

          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
271 272 273
      end
    end

274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
    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') }
291

292 293
        it 'returns not found' do
          post :update, id: redirect_route.path, group: { path: 'new_path' }
294

295 296
          expect(response).to have_http_status(404)
        end
297 298
      end
    end
299

300 301 302 303
    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
304

305 306
          expect(response).not_to have_http_status(404)
        end
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
        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
323 324 325 326
      end
    end
  end

327 328 329
  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
330
end