projects_controller_spec.rb 8.83 KB
Newer Older
1 2 3 4
require('spec_helper')

describe ProjectsController do
  let(:project) { create(:project) }
Ciro Santilli's avatar
Ciro Santilli committed
5
  let(:public_project) { create(:project, :public) }
6 7
  let(:user)    { create(:user) }
  let(:jpg)     { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') }
Marin Jankovski's avatar
Marin Jankovski committed
8
  let(:txt)     { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') }
9

10
  describe "GET show" do
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
    context "user not project member" do
      before { sign_in(user) }

      context "user does not have access to project" do
        let(:private_project) { create(:project, :private) }

        it "does not initialize notification setting" do
          get :show, namespace_id: private_project.namespace.path, id: private_project.path
          expect(assigns(:notification_setting)).to be_nil
        end
      end

      context "user has access to project" do
        context "and does not have notification setting" do
          it "initializes notification as disabled" do
            get :show, namespace_id: public_project.namespace.path, id: public_project.path
27
            expect(assigns(:notification_setting).level).to eq("global")
28 29 30 31 32 33
          end
        end

        context "and has notification setting" do
          before do
            setting = user.notification_settings_for(public_project)
34
            setting.level = :watch
35 36 37 38 39
            setting.save
          end

          it "shows current notification setting" do
            get :show, namespace_id: public_project.namespace.path, id: public_project.path
40
            expect(assigns(:notification_setting).level).to eq("watch")
41 42 43 44
          end
        end
      end
    end
45

46 47
    context "rendering default project view" do
      render_views
48

Douwe Maan's avatar
Douwe Maan committed
49
      it "renders the activity view" do
50 51
        allow(controller).to receive(:current_user).and_return(user)
        allow(user).to receive(:project_view).and_return('activity')
Douwe Maan's avatar
Douwe Maan committed
52

53 54 55 56
        get :show, namespace_id: public_project.namespace.path, id: public_project.path
        expect(response).to render_template('_activity')
      end

Douwe Maan's avatar
Douwe Maan committed
57
      it "renders the readme view" do
58 59
        allow(controller).to receive(:current_user).and_return(user)
        allow(user).to receive(:project_view).and_return('readme')
Douwe Maan's avatar
Douwe Maan committed
60

61 62 63 64
        get :show, namespace_id: public_project.namespace.path, id: public_project.path
        expect(response).to render_template('_readme')
      end

Douwe Maan's avatar
Douwe Maan committed
65
      it "renders the files view" do
66 67
        allow(controller).to receive(:current_user).and_return(user)
        allow(user).to receive(:project_view).and_return('files')
Douwe Maan's avatar
Douwe Maan committed
68

69 70 71 72
        get :show, namespace_id: public_project.namespace.path, id: public_project.path
        expect(response).to render_template('_files')
      end
    end
73

74
    context "when requested with case sensitive namespace and project path" do
75 76 77
      context "when there is a match with the same casing" do
        it "loads the project" do
          get :show, namespace_id: public_project.namespace.path, id: public_project.path
78

79
          expect(assigns(:project)).to eq(public_project)
80
          expect(response).to have_http_status(200)
81
        end
82 83
      end

84 85 86 87 88 89 90 91 92
      context "when there is a match with different casing" do
        it "redirects to the normalized path" do
          get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase

          expect(assigns(:project)).to eq(public_project)
          expect(response).to redirect_to("/#{public_project.path_with_namespace}")
        end


93
        # MySQL queries are case insensitive by default, so this spec would fail.
94
        if Gitlab::Database.postgresql?
95
          context "when there is also a match with the same casing" do
96

97
            let!(:other_project) { create(:project, :public, namespace: public_project.namespace, path: public_project.path.upcase) }
98

99
            it "loads the exactly matched project" do
100

101 102 103
              get :show, namespace_id: public_project.namespace.path, id: public_project.path.upcase

              expect(assigns(:project)).to eq(other_project)
104
              expect(response).to have_http_status(200)
105
            end
106 107
          end
        end
108 109
      end
    end
110 111

    context "when the url contains .atom" do
112
      let(:public_project_with_dot_atom) { build(:project, :public, name: 'my.atom', path: 'my.atom') }
113

114
      it 'expect an error creating the project' do
115
        expect(public_project_with_dot_atom).not_to be_valid
116 117
      end
    end
118 119 120 121 122 123 124 125 126 127 128

    context 'when the project is pending deletions' do
      it 'renders a 404 error' do
        project = create(:project, pending_delete: true)
        sign_in(user)

        get :show, namespace_id: project.namespace.path, id: project.path

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

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
  describe "#update" do
    render_views

    let(:admin) { create(:admin) }

    it "sets the repository to the right path after a rename" do
      new_path = 'renamed_path'
      project_params = { path: new_path }
      controller.instance_variable_set(:@project, project)
      sign_in(admin)

      put :update,
          namespace_id: project.namespace.to_param,
          id: project.id,
          project: project_params

      expect(project.repository.path).to include(new_path)
      expect(assigns(:repository).path).to eq(project.repository.path)
149
      expect(response).to have_http_status(200)
150 151 152
    end
  end

153 154 155 156 157 158 159 160 161 162 163
  describe "#destroy" do
    let(:admin) { create(:admin) }

    it "redirects to the dashboard" do
      controller.instance_variable_set(:@project, project)
      sign_in(admin)

      orig_id = project.id
      delete :destroy, namespace_id: project.namespace.path, id: project.path

      expect { Project.find(orig_id) }.to raise_error(ActiveRecord::RecordNotFound)
164
      expect(response).to have_http_status(302)
165 166 167 168
      expect(response).to redirect_to(dashboard_projects_path)
    end
  end

Ciro Santilli's avatar
Ciro Santilli committed
169
  describe "POST #toggle_star" do
170
    it "toggles star if user is signed in" do
Ciro Santilli's avatar
Ciro Santilli committed
171
      sign_in(user)
172
      expect(user.starred?(public_project)).to be_falsey
173 174
      post(:toggle_star,
           namespace_id: public_project.namespace.to_param,
Vinnie Okada's avatar
Vinnie Okada committed
175
           id: public_project.to_param)
176
      expect(user.starred?(public_project)).to be_truthy
177 178
      post(:toggle_star,
           namespace_id: public_project.namespace.to_param,
Vinnie Okada's avatar
Vinnie Okada committed
179
           id: public_project.to_param)
180
      expect(user.starred?(public_project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
181 182 183
    end

    it "does nothing if user is not signed in" do
184 185
      post(:toggle_star,
           namespace_id: project.namespace.to_param,
Vinnie Okada's avatar
Vinnie Okada committed
186
           id: public_project.to_param)
187
      expect(user.starred?(public_project)).to be_falsey
188 189
      post(:toggle_star,
           namespace_id: project.namespace.to_param,
Vinnie Okada's avatar
Vinnie Okada committed
190
           id: public_project.to_param)
191
      expect(user.starred?(public_project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
192 193
    end
  end
194

Douwe Maan's avatar
Douwe Maan committed
195
  describe "DELETE remove_fork" do
196 197 198 199 200 201 202 203
    context 'when signed in' do
      before do
        sign_in(user)
      end

      context 'with forked project' do
        let(:project_fork) { create(:project, namespace: user.namespace) }

204
        before do
205
          create(:forked_project_link, forked_to_project: project_fork)
206 207 208 209
        end

        it 'should remove fork from project' do
          delete(:remove_fork,
210 211 212 213
              namespace_id: project_fork.namespace.to_param,
              id: project_fork.to_param, format: :js)

          expect(project_fork.forked?).to be_falsey
Douwe Maan's avatar
Douwe Maan committed
214
          expect(flash[:notice]).to eq('The fork relationship has been removed.')
215 216 217 218
          expect(response).to render_template(:remove_fork)
        end
      end

219 220
      context 'when project not forked' do
        let(:unforked_project) { create(:project, namespace: user.namespace) }
221

222 223 224 225 226 227 228 229
        it 'should do nothing if project was not forked' do
          delete(:remove_fork,
              namespace_id: unforked_project.namespace.to_param,
              id: unforked_project.to_param, format: :js)

          expect(flash[:notice]).to be_nil
          expect(response).to render_template(:remove_fork)
        end
230 231 232 233
      end
    end

    it "does nothing if user is not signed in" do
234
      delete(:remove_fork,
235 236
          namespace_id: project.namespace.to_param,
          id: project.to_param, format: :js)
237
      expect(response).to have_http_status(401)
238 239
    end
  end
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259

  describe "GET refs" do
    it "should get a list of branches and tags" do
      get :refs, namespace_id: public_project.namespace.path, id: public_project.path

      parsed_body = JSON.parse(response.body)
      expect(parsed_body["Branches"]).to include("master")
      expect(parsed_body["Tags"]).to include("v1.0.0")
      expect(parsed_body["Commits"]).to be_nil
    end

    it "should get a list of branches, tags and commits" do
      get :refs, namespace_id: public_project.namespace.path, id: public_project.path, ref: "123456"

      parsed_body = JSON.parse(response.body)
      expect(parsed_body["Branches"]).to include("master")
      expect(parsed_body["Tags"]).to include("v1.0.0")
      expect(parsed_body["Commits"]).to include("123456")
    end
  end
260
end