• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MarkUsProject / Markus / 20143075828

11 Dec 2025 06:18PM UTC coverage: 91.513%. Remained the same
20143075828

Pull #7763

github

web-flow
Merge 9f55e660a into 3421ef3b2
Pull Request #7763: Release 2.9.0

914 of 1805 branches covered (50.64%)

Branch coverage included in aggregate %.

1584 of 1666 new or added lines in 108 files covered. (95.08%)

573 existing lines in 35 files now uncovered.

43650 of 46892 relevant lines covered (93.09%)

121.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.95
/spec/controllers/main_controller_spec.rb
1
describe MainController do
1✔
2
  include SessionHandler
1✔
3

4
  let(:student) { create(:student) }
3✔
5
  let(:ta) { create(:ta) }
3✔
6
  let(:instructor) { create(:instructor) }
17✔
7
  let(:instructor2) { create(:instructor) }
1✔
8
  let(:admin_user) { create(:admin_user) }
3✔
9

10
  context 'A non-authenticated user' do
1✔
11
    it 'should not be able to login with a blank username' do
1✔
12
      post :login, params: { user_login: '', user_password: 'a' }
1✔
13
      expect(flash[:error]).to have_message(I18n.t('main.username_not_blank'))
1✔
14
    end
15

16
    it 'should not be able to login with a blank password' do
1✔
17
      post :login, params: { user_login: 'a', user_password: '' }
1✔
18
      expect(flash[:error]).to have_message(I18n.t('main.password_not_blank'))
1✔
19
    end
20

21
    describe 'login_remote_auth' do
1✔
22
      before do
1✔
23
        get :login_remote_auth
2✔
24
      end
25

26
      it 'should set the auth_type to remote' do
1✔
27
        expect(session[:auth_type]).to eq 'remote'
1✔
28
      end
29

30
      it 'should redirect to the remote login page' do
1✔
31
        expect(response).to redirect_to(Settings.remote_auth_login_url)
1✔
32
      end
33
    end
34
  end
35

36
  context 'An Instructor' do
1✔
37
    let :all_assignments do
1✔
UNCOV
38
      a2 = create(:assignment, due_date: 1.day.ago)
×
39
      a1 = create(:assignment, due_date: 2.days.ago)
×
40
      a3 = create(:assignment, due_date: 1.day.from_now)
×
41
      [a1, a2, a3]
×
42
    end
43

44
    context 'after logging in without remote user auth' do
1✔
45
      before do
1✔
46
        sign_in instructor
4✔
47
      end
48

49
      it 'should not display any errors' do
1✔
50
        expect(flash[:error]).to be_nil
1✔
51
      end
52

53
      it 'should set the session real_user to the correct user' do
1✔
54
        expect(real_user&.user_name).to eq(instructor.user_name)
1✔
55
      end
56

57
      it 'should start the session timeout counter' do
1✔
58
        expect(session[:timeout]).not_to be_nil
1✔
59
      end
60

61
      it 'should redirect the login route to the courses index route' do
1✔
62
        get :login
1✔
63
        expect(response).to redirect_to action: 'index', controller: 'courses'
1✔
64
      end
65
    end
66

67
    context 'after logging in with remote user auth' do
1✔
68
      let(:user_name) { instructor.user_name }
7✔
69

70
      before do
1✔
71
        allow(self).to receive(:reset_session)
9✔
72
        clear_session
9✔
73
        env_hash = { HTTP_X_FORWARDED_USER: user_name }
9✔
74
        request.headers.merge! env_hash
9✔
75
        session[:auth_type] = 'remote'
9✔
76
      end
77

78
      it 'should set the session real_user to the correct user' do
1✔
79
        expect(real_user&.user_name).to eq(instructor.user_name)
1✔
80
      end
81

82
      it 'should redirect the login route to the courses index route' do
1✔
83
        get :login
1✔
84
        expect(response).to redirect_to action: 'index', controller: 'courses'
1✔
85
      end
86

87
      context 'when MarkUs is in restricted mode' do
1✔
88
        before do
1✔
89
          allow(Settings).to receive_messages(remote_validate_file: Rails.root
2✔
90
                                                     .join('spec/fixtures/files/dummy_remote_validate.sh'),
91
                                              validate_ip: true)
92
          allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return('192.168.0.1')
2✔
93
        end
94

95
        it 'should return an error if user ip is not in the approved ip range' do
1✔
96
          get :login
1✔
97
          expect(flash[:error].size).to be 1
1✔
98
        end
99

100
        context 'with an allowed ip' do
1✔
101
          before do
1✔
102
            allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return('0.0.0.0')
1✔
103
          end
104

105
          it 'should redirect to the courses index route' do
1✔
106
            get :login
1✔
107
            expect(response).to redirect_to action: 'index', controller: 'courses'
1✔
108
          end
109
        end
110
      end
111

112
      context 'going to a page that requires authentication' do
1✔
113
        before { post :logout }
3✔
114

115
        it 'should respond with redirect' do
1✔
116
          expect(response).to have_http_status(:redirect)
1✔
117
        end
118

119
        it 'should not start the session timeout counter' do
1✔
120
          expect(session[:timeout]).to be_nil
1✔
121
        end
122
      end
123

124
      context 'when there is no user with the given user_name' do
1✔
125
        let(:user_name) { build(:end_user).user_name }
4✔
126

127
        it 'should redirect to the login page' do
1✔
128
          post :logout
1✔
129
          expect(response).to redirect_to action: 'login', controller: 'main'
1✔
130
        end
131

132
        it 'should flash an error message when going to login' do
1✔
133
          get :login
1✔
134
          expect(flash[:error]).not_to be_empty
1✔
135
        end
136

137
        it 'should flash an error message when going a non-login page' do
1✔
138
          post :logout
1✔
139
          expect(flash[:error]).not_to be_empty
1✔
140
        end
141
      end
142
    end
143

144
    context 'after logging in with a bad username' do
1✔
145
      it 'should not be able to login with an incorrect username' do
1✔
146
        post :login, params: { user_login: instructor.user_name + 'BAD', user_password: 'a' }
1✔
147
        expect(flash[:error]).to have_message(I18n.t('main.login_failed'))
1✔
148
      end
149
    end
150

151
    context 'logging in during an LTI launch' do
1✔
152
      let(:lti) { create(:lti_deployment) }
1✔
153

154
      before do
1✔
155
        cookies.encrypted.permanent[:lti_data] = JSON.generate({ lti_redirect: redirect_login_canvas_path })
2✔
156
      end
157

158
      it 'redirects to redirect_login' do
1✔
159
        sign_in instructor
1✔
160
        expect(response).to redirect_to action: 'redirect_login', controller: 'canvas'
1✔
161
      end
162

163
      context 'when logged in during lti launch' do
1✔
164
        let(:lti) { create(:lti_deployment) }
1✔
165

166
        before do
1✔
167
          sign_in instructor
1✔
168
          cookies.encrypted.permanent[:lti_data] = JSON.generate({ lti_redirect: redirect_login_canvas_path })
1✔
169
        end
170

171
        it 'redirects to course picker if lti data is present' do
1✔
172
          get :login
1✔
173
          expect(response).to have_http_status(:found)
1✔
174
        end
175
      end
176
    end
177

178
    context 'after logging out' do
1✔
179
      before do
1✔
180
        post :login, params: { user_login: instructor.user_name, user_password: 'a' }
3✔
181
        get :logout
3✔
182
      end
183

184
      it 'should unset the session real_user_name' do
1✔
185
        expect(session[:real_user_name]).to be_nil
1✔
186
      end
187

188
      it 'should unset the timeout counter' do
1✔
189
        expect(session[:timeout]).to be_nil
1✔
190
      end
191

192
      it 'should redirect all routes to the login page' do
1✔
193
        get :about
1✔
194
        expect(response).to redirect_to action: 'login', controller: 'main'
1✔
195
      end
196
    end
197
  end
198

199
  context 'A student' do
1✔
200
    shared_examples 'student tests' do
1✔
201
      it 'should redirect to the courses controller' do
2✔
202
        expect(response).to redirect_to controller: 'courses', action: 'index'
2✔
203
      end
204
    end
205

206
    context 'after logging in without remote user auth' do
1✔
207
      before do
1✔
208
        sign_in student
1✔
209
      end
210

211
      it_behaves_like 'student tests'
1✔
212
    end
213

214
    context 'after logging in with remote user auth' do
1✔
215
      before do
1✔
216
        env_hash = { HTTP_X_FORWARDED_USER: student.user_name }
1✔
217
        request.headers.merge! env_hash
1✔
218
        sign_in student
1✔
219
      end
220

221
      it_behaves_like 'student tests'
1✔
222
    end
223
  end
224

225
  context 'A TA' do
1✔
226
    shared_examples 'ta tests' do
1✔
227
      it 'should redirect to the courses controller' do
2✔
228
        expect(response).to redirect_to controller: 'courses', action: 'index'
2✔
229
      end
230
    end
231

232
    context 'after logging in without remote user auth' do
1✔
233
      before do
1✔
234
        sign_in ta
1✔
235
      end
236

237
      it_behaves_like 'ta tests'
1✔
238
    end
239

240
    context 'after logging in with remote user auth' do
1✔
241
      before do
1✔
242
        env_hash = { HTTP_X_FORWARDED_USER: ta.user_name }
1✔
243
        request.headers.merge! env_hash
1✔
244
        sign_in ta
1✔
245
      end
246

247
      it_behaves_like 'ta tests'
1✔
248
    end
249
  end
250

251
  context 'An Admin User' do
1✔
252
    shared_examples 'admin tests' do
1✔
253
      it 'redirects to the main_admin controller' do
2✔
254
        expect(response).to redirect_to(admin_path)
2✔
255
      end
256
    end
257

258
    context 'after logging in without remote user auth' do
1✔
259
      before do
1✔
260
        sign_in admin_user
1✔
261
      end
262

263
      it_behaves_like 'admin tests'
1✔
264
    end
265

266
    context 'after logging in with remote user auth' do
1✔
267
      before do
1✔
268
        env_hash = { HTTP_X_FORWARDED_USER: admin_user.user_name }
1✔
269
        request.headers.merge! env_hash
1✔
270
        sign_in admin_user
1✔
271
      end
272

273
      it_behaves_like 'admin tests'
1✔
274
    end
275
  end
276

277
  context 'when role switched' do
1✔
278
    let(:course1) { create(:course) }
10✔
279
    let(:course2) { create(:course) }
3✔
280
    let(:instructor) { create(:instructor, course_id: course1.id) }
10✔
281
    let(:instructor2) { create(:instructor, course_id: course2.id) }
1✔
282
    let(:student) { create(:student, course_id: course1.id) }
10✔
283

284
    before do
1✔
285
      @controller = CoursesController.new
9✔
286
      post_as instructor, :switch_role, params: { id: course1.id, effective_user_login: student.user_name }
9✔
287
    end
288

289
    it 'redirects the login route to the course homepage' do
1✔
290
      @controller = MainController.new
1✔
291
      get :login
1✔
292
      expect(response).to redirect_to course_assignments_path(session[:role_switch_course_id])
1✔
293
    end
294

295
    it 'flashes a forbidden error message on attempt to access another course' do
1✔
296
      @controller = CoursesController.new
1✔
297
      get :show, params: { id: course2.id }
1✔
298
      expect(flash[:error]).not_to be_empty
1✔
299
    end
300

301
    it 'redirects to the original course on attempt to access another course' do
1✔
302
      @controller = CoursesController.new
1✔
303
      get :show, params: { id: course2.id }
1✔
304
      expect(response).to redirect_to course_assignments_path(session[:role_switch_course_id])
1✔
305
    end
306

307
    context 'when user tries to log out' do
1✔
308
      before do
1✔
309
        @controller = MainController.new
5✔
310
        get :logout
5✔
311
      end
312

313
      it 'should unset the session real_user_name' do
1✔
314
        expect(session[:real_user_name]).to be_nil
1✔
315
      end
316

317
      it 'should unset the timeout counter' do
1✔
318
        expect(session[:timeout]).to be_nil
1✔
319
      end
320

321
      it 'should unset the session user_name' do
1✔
322
        expect(session[:user_name]).to be_nil
1✔
323
      end
324

325
      it 'should unset the session role_switch_course_id' do
1✔
326
        expect(session[:role_switch_course_id]).to be_nil
1✔
327
      end
328

329
      it 'should redirect all routes to the login page' do
1✔
330
        get :about
1✔
331
        expect(response).to redirect_to action: 'login', controller: 'main'
1✔
332
      end
333
    end
334

335
    it 'allows user to properly access about' do
1✔
336
      @controller = MainController.new
1✔
337
      request.headers['accept'] = 'text/javascript'
1✔
338
      get :about, xhr: true
1✔
339
      expect(response).to have_http_status(:ok)
1✔
340
    end
341
  end
342
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc