Skip to content

Commit 152b140

Browse files
authored
test: Add system tests for exercise administration (#3008)
The exercise administration form is a critical pass. The test will secure the functionality with the upcoming changes. Relates to #2922
1 parent 773e751 commit 152b140

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'Exercise creation', :js do
6+
let!(:ruby) { create(:ruby) }
7+
let(:teacher) { create(:teacher) }
8+
9+
before do
10+
visit(sign_in_path)
11+
fill_in('email', with: teacher.email)
12+
fill_in('password', with: attributes_for(:teacher)[:password])
13+
click_button(I18n.t('sessions.new.link'))
14+
wait_for_ajax
15+
end
16+
17+
context 'when an exercise is created' do
18+
let(:submission_deadline) { 3.months.from_now.beginning_of_minute }
19+
let(:late_submission_deadline) { submission_deadline + 1.week }
20+
let(:title) { 'Ruby challenge' }
21+
let(:internal_title) { 'Project Ruby: Table flip' }
22+
23+
let(:code) do
24+
<<~RUBY
25+
def self.❨╯°□°❩╯︵┻━┻
26+
puts "Calm down, bro"
27+
end
28+
RUBY
29+
end
30+
31+
let(:description) do
32+
<<~TEXT
33+
Ruby challenge
34+
35+
Do something with Ruby.
36+
TEXT
37+
end
38+
39+
before do
40+
visit(exercises_path)
41+
click_on I18n.t('shared.new_model', model: Exercise.model_name.human)
42+
wait_for_ajax
43+
end
44+
45+
it 'creates an exercise with nested data' do
46+
fill_in Exercise.human_attribute_name(:title), with: title
47+
fill_in Exercise.human_attribute_name(:internal_title), with: internal_title
48+
49+
# description
50+
within('.markdown-editor__wrapper') do
51+
find('.ProseMirror').set(description)
52+
end
53+
54+
chosenjs_select_helper(Exercise.human_attribute_name(:execution_environment), ruby.name)
55+
56+
chosenjs_date_time_select_helper(Exercise.human_attribute_name(:submission_deadline), submission_deadline)
57+
58+
chosenjs_date_time_select_helper(Exercise.human_attribute_name(:late_submission_deadline), late_submission_deadline)
59+
60+
check Exercise.human_attribute_name(:public)
61+
62+
click_on I18n.t('exercises.form.add_file')
63+
64+
within(find_by_id('files').all('li').last) do
65+
fill_in CodeOcean::File.human_attribute_name(:name), with: 'main'
66+
67+
chosenjs_select_helper(CodeOcean::File.human_attribute_name(:file_type), ruby.file_type.name)
68+
chosenjs_select_helper(CodeOcean::File.human_attribute_name(:role), I18n.t('code_ocean/files.roles.main_file'))
69+
70+
check(CodeOcean::File.human_attribute_name(:read_only))
71+
72+
find_by_id('editor-edit').click
73+
send_keys code.strip
74+
end
75+
76+
click_button I18n.t('shared.create', model: Exercise.model_name.human)
77+
78+
expect(page).to have_text \
79+
I18n.t('shared.object_created', model: Exercise.model_name.human)
80+
81+
# Exercise is created with expected attributes
82+
expect(page).to have_text(title)
83+
expect(page).to have_text(internal_title)
84+
expect(page).to have_text(submission_deadline.to_s)
85+
expect(page).to have_text(late_submission_deadline.to_s)
86+
expect(page).to have_text(ruby.name)
87+
88+
description.lines.each do |line|
89+
expect(page).to have_text(line.delete("\n"))
90+
end
91+
92+
# Exercise includes the code
93+
find('span', text: 'main.rb').click
94+
95+
code.lines.each do |code_line|
96+
expect(page).to have_text(code_line.delete("\n"))
97+
end
98+
end
99+
end
100+
101+
context 'when an exercise is updated' do
102+
let!(:exercise) { create(:fibonacci, user: teacher) }
103+
let(:deleted_file_name) { 'reference.rb' }
104+
let(:updated_file_name) { 'exercise.rb' }
105+
106+
before do
107+
visit(exercises_path)
108+
end
109+
110+
it 'updates an exercise with nested data' do
111+
click_on exercise.title
112+
click_on I18n.t('shared.edit')
113+
114+
fill_in Exercise.human_attribute_name(:difficulty), with: 5
115+
116+
find('span', text: updated_file_name).click
117+
118+
within('.card', text: updated_file_name) do
119+
fill_in CodeOcean::File.human_attribute_name(:name), with: 'main_exercise'
120+
end
121+
122+
find('span', text: deleted_file_name).click
123+
124+
within('.card', text: deleted_file_name) do
125+
accept_confirm do
126+
find('div.btn', text: I18n.t('shared.destroy')).click
127+
end
128+
end
129+
130+
click_button I18n.t('shared.update', model: Exercise.model_name.human)
131+
132+
expect(page).to have_text("#{Exercise.human_attribute_name(:difficulty)}\n5")
133+
expect(page).to have_text('main_exercise.rb')
134+
expect(page).to have_no_text(deleted_file_name)
135+
end
136+
end
137+
138+
def chosenjs_select_helper(name, value)
139+
id = first('label', text: name)[:for]
140+
141+
set_value_for_chosenjs_element(id, value)
142+
end
143+
144+
def chosenjs_date_time_select_helper(name, date)
145+
id = first('label', text: name)[:for]
146+
147+
set_value_for_chosenjs_element("#{id}_1i", date.year.to_s)
148+
set_value_for_chosenjs_element("#{id}_2i", date.strftime('%B'))
149+
set_value_for_chosenjs_element("#{id}_3i", date.day.to_s)
150+
set_value_for_chosenjs_element("#{id}_4i", date.hour.to_s)
151+
set_value_for_chosenjs_element("#{id}_5i", date.min.to_s)
152+
end
153+
154+
def set_value_for_chosenjs_element(id, value)
155+
element = find_by_id("#{id}_chosen")
156+
element.click
157+
158+
within(element) do
159+
first('.chosen-results li', text: value).click
160+
end
161+
end
162+
end

0 commit comments

Comments
 (0)