From 8be200b78bf41533e0da9403eaf7399a52b63a3b Mon Sep 17 00:00:00 2001 From: Naragod Date: Wed, 21 Jan 2026 15:31:33 -0500 Subject: [PATCH 1/7] ISSUE-7795: Remove size cap of qr code creation --- app/jobs/generate_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/generate_job.rb b/app/jobs/generate_job.rb index 6262d0495a..9976483aca 100644 --- a/app/jobs/generate_job.rb +++ b/app/jobs/generate_job.rb @@ -11,7 +11,7 @@ def perform(exam_template, num_copies, start, enqueuing_user = nil) # Start a new page with the same size and layout as the current page start_new_page(size: page.page_size[2..4], layout: page.orientation) qrcode_content = "#{exam_template.name}-#{exam_num}-#{page_num + 1}" - qrcode = RQRCode::QRCode.new qrcode_content, level: :l, size: 2 + qrcode = RQRCode::QRCode.new qrcode_content, level: :l alignment = page_num.even? ? :right : :left render_qr_code(qrcode, align: alignment, dot: 4.0, stroke: false) draw_text(qrcode_content, From 1b8909d103ac754727af9a09a2764c7ca5e7f3f8 Mon Sep 17 00:00:00 2001 From: Naragod Date: Wed, 21 Jan 2026 15:35:44 -0500 Subject: [PATCH 2/7] ISSUE-7795: Add test cases --- spec/jobs/generate_job_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/jobs/generate_job_spec.rb b/spec/jobs/generate_job_spec.rb index f8bee52c8f..7a72ab9843 100644 --- a/spec/jobs/generate_job_spec.rb +++ b/spec/jobs/generate_job_spec.rb @@ -85,6 +85,20 @@ expect(pdf_mock.pages.length).to eq 18 end + + context 'with a long exam template name' do + let(:exam_template) do + create(:exam_template_midterm, name: 'Test_Midterm_Exam_Template_V2') + end + + it 'should generate QR codes without overflow errors' do + expect { GenerateJob.perform_now(exam_template, 1, 0, user) }.not_to raise_error + end + + it 'should generate QR codes for high exam numbers without overflow errors' do + expect { GenerateJob.perform_now(exam_template, 1, 999, user) }.not_to raise_error + end + end end end From 439b983b46cc7a637f21eedf88c436a281e634f3 Mon Sep 17 00:00:00 2001 From: Naragod Date: Wed, 21 Jan 2026 15:38:37 -0500 Subject: [PATCH 3/7] ISSUE-7795: Update Changelog --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index e096873ab6..7120f92a3e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ - Update autotest settings form UI (#7777) - Store start and end date for courses (#7783) - Update batch test runs table UI (#7790) +- Remove QR code name size limit (#7796) ### 🐛 Bug fixes - Fixed the editing form of marking schemes to include newly added assessments (#7788) From f0576583cbdb0d50d3f7ecc56067419a5ec65303 Mon Sep 17 00:00:00 2001 From: Naragod Date: Thu, 22 Jan 2026 12:32:10 -0500 Subject: [PATCH 4/7] ISSUE-7795: Revert changes --- app/jobs/generate_job.rb | 2 +- spec/jobs/generate_job_spec.rb | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/app/jobs/generate_job.rb b/app/jobs/generate_job.rb index 9976483aca..6262d0495a 100644 --- a/app/jobs/generate_job.rb +++ b/app/jobs/generate_job.rb @@ -11,7 +11,7 @@ def perform(exam_template, num_copies, start, enqueuing_user = nil) # Start a new page with the same size and layout as the current page start_new_page(size: page.page_size[2..4], layout: page.orientation) qrcode_content = "#{exam_template.name}-#{exam_num}-#{page_num + 1}" - qrcode = RQRCode::QRCode.new qrcode_content, level: :l + qrcode = RQRCode::QRCode.new qrcode_content, level: :l, size: 2 alignment = page_num.even? ? :right : :left render_qr_code(qrcode, align: alignment, dot: 4.0, stroke: false) draw_text(qrcode_content, diff --git a/spec/jobs/generate_job_spec.rb b/spec/jobs/generate_job_spec.rb index 7a72ab9843..f8bee52c8f 100644 --- a/spec/jobs/generate_job_spec.rb +++ b/spec/jobs/generate_job_spec.rb @@ -85,20 +85,6 @@ expect(pdf_mock.pages.length).to eq 18 end - - context 'with a long exam template name' do - let(:exam_template) do - create(:exam_template_midterm, name: 'Test_Midterm_Exam_Template_V2') - end - - it 'should generate QR codes without overflow errors' do - expect { GenerateJob.perform_now(exam_template, 1, 0, user) }.not_to raise_error - end - - it 'should generate QR codes for high exam numbers without overflow errors' do - expect { GenerateJob.perform_now(exam_template, 1, 999, user) }.not_to raise_error - end - end end end From 4e6b5153890f14854e817539e317b2a2fea01c21 Mon Sep 17 00:00:00 2001 From: Naragod Date: Thu, 22 Jan 2026 12:32:53 -0500 Subject: [PATCH 5/7] ISSUE-7795: Limit length of file name to 20 or fewer characters --- app/controllers/exam_templates_controller.rb | 6 ++- app/models/exam_template.rb | 3 +- config/locales/views/exam_templates/en.yml | 4 +- .../exam_templates_controller_spec.rb | 38 +++++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/app/controllers/exam_templates_controller.rb b/app/controllers/exam_templates_controller.rb index 3a90083db4..bd07dc41dc 100644 --- a/app/controllers/exam_templates_controller.rb +++ b/app/controllers/exam_templates_controller.rb @@ -35,7 +35,8 @@ def create redirect_to edit_course_exam_template_path(current_course, exam_template) return else - flash_message(:error, t('exam_templates.create.failure')) + errors = exam_template&.errors&.full_messages&.join(', ') + flash_message(:error, t('exam_templates.create.failure', errors: errors.present? ? ": #{errors}" : '')) end end redirect_to course_assignment_exam_templates_path(current_course, assignment) @@ -71,7 +72,8 @@ def update if old_exam_template.update(exam_template_params) flash_message(:success, t('exam_templates.update.success')) else - flash_message(:error, t('exam_templates.update.failure')) + errors = old_exam_template.errors.full_messages.join(', ') + flash_message(:error, t('exam_templates.update.failure', errors: errors.present? ? ": #{errors}" : '')) end else new_template_filename = new_uploaded_io.original_filename diff --git a/app/models/exam_template.rb b/app/models/exam_template.rb index b75932fc05..d85fb5590e 100644 --- a/app/models/exam_template.rb +++ b/app/models/exam_template.rb @@ -8,7 +8,8 @@ class ExamTemplate < ApplicationRecord has_one :course, through: :assignment validates :filename, :num_pages, :name, presence: true validates :name, - uniqueness: { scope: :assignment } + uniqueness: { scope: :assignment }, + length: { maximum: 20, message: 'must be at most 20 characters to fit in the QR code' } validates :num_pages, numericality: { greater_than_or_equal_to: 0, only_integer: true } diff --git a/config/locales/views/exam_templates/en.yml b/config/locales/views/exam_templates/en.yml index b00c3cd1ed..f5a8ca02c7 100644 --- a/config/locales/views/exam_templates/en.yml +++ b/config/locales/views/exam_templates/en.yml @@ -29,7 +29,7 @@ en: create: add_division: Add Template Division add_new: Add Exam Template - failure: Exam Template not successfully created + failure: "Exam Template not successfully created%{errors}" success: Exam Template successfully created upload: Upload Template delete: @@ -94,7 +94,7 @@ en: scan_error: Some files have not been scanned properly. submission_in_progress: Scanning QR codes done, now preparing PDF pages for grading update: - failure: Exam Template has not been successfully updated + failure: "Exam Template has not been successfully updated%{errors}" instruction: Replace template file success: Exam Template has been successfully updated upload_scans: diff --git a/spec/controllers/exam_templates_controller_spec.rb b/spec/controllers/exam_templates_controller_spec.rb index 756713f4b4..b9c7f26b4e 100644 --- a/spec/controllers/exam_templates_controller_spec.rb +++ b/spec/controllers/exam_templates_controller_spec.rb @@ -22,6 +22,24 @@ it('should respond with 302') { expect(response).to have_http_status :found } end + describe '#create with a name that is too long' do + let(:file_io) { fixture_file_upload('scanned_exams/midterm1-v2-test.pdf', 'application/pdf') } + let(:params) do + { create_template: { file_io: file_io, name: 'Test_Midterm_Exam_Template_V2' }, + assignment_id: exam_template.assignment.id, course_id: course.id } + end + + before { post_as user, :create, params: params } + + it 'does not create an ExamTemplate' do + expect(ExamTemplate.find_by(name: 'Test_Midterm_Exam_Template_V2')).to be_nil + end + + it 'displays a flash error about name length' do + expect(flash[:error].first).to include('Name must be at most 20 characters to fit in the QR code') + end + end + describe '#create with empty filename' do let(:file_io) { fixture_file_upload('scanned_exams/midterm1-v2-test.pdf', 'application/pdf') } let(:params) do @@ -84,6 +102,26 @@ end end + context 'when updating with a name that is too long' do + let(:params) do + { exam_template: { name: 'Test_Midterm_Exam_Template_V2' }, + id: exam_template.id, course_id: course.id } + end + + it 'does not update the exam template name' do + original_name = exam_template.name + expect(exam_template.reload.name).to eq original_name + end + + it 'displays a flash error about name length' do + expect(flash[:error].first).to include('Name must be at most 20 characters to fit in the QR code') + end + + it 'responds with 302' do + expect(response).to have_http_status :found + end + end + context 'when replacing the exam template file with a PDF file' do let(:file_io) { fixture_file_upload('scanned_exams/midterm1-v2-test.pdf') } let(:params) do From 8b863ae810edce278f46d7a5b266f8c225d7d621 Mon Sep 17 00:00:00 2001 From: Naragod Date: Thu, 22 Jan 2026 22:13:37 -0500 Subject: [PATCH 6/7] ISSUE-7795: Simplify name --- app/models/exam_template.rb | 2 +- spec/controllers/exam_templates_controller_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/exam_template.rb b/app/models/exam_template.rb index d85fb5590e..cdb86067c7 100644 --- a/app/models/exam_template.rb +++ b/app/models/exam_template.rb @@ -9,7 +9,7 @@ class ExamTemplate < ApplicationRecord validates :filename, :num_pages, :name, presence: true validates :name, uniqueness: { scope: :assignment }, - length: { maximum: 20, message: 'must be at most 20 characters to fit in the QR code' } + length: { maximum: 20, message: 'must be at most 20 characters' } validates :num_pages, numericality: { greater_than_or_equal_to: 0, only_integer: true } diff --git a/spec/controllers/exam_templates_controller_spec.rb b/spec/controllers/exam_templates_controller_spec.rb index b9c7f26b4e..833526a0ef 100644 --- a/spec/controllers/exam_templates_controller_spec.rb +++ b/spec/controllers/exam_templates_controller_spec.rb @@ -36,7 +36,7 @@ end it 'displays a flash error about name length' do - expect(flash[:error].first).to include('Name must be at most 20 characters to fit in the QR code') + expect(flash[:error].first).to include('Name must be at most 20 characters') end end @@ -114,7 +114,7 @@ end it 'displays a flash error about name length' do - expect(flash[:error].first).to include('Name must be at most 20 characters to fit in the QR code') + expect(flash[:error].first).to include('Name must be at most 20 characters') end it 'responds with 302' do From 6933d0c04f9a1789ee2389564f84fef77a64c489 Mon Sep 17 00:00:00 2001 From: Naragod Date: Thu, 22 Jan 2026 22:42:55 -0500 Subject: [PATCH 7/7] ISSUE-7795: Fix normalization issue --- config/locales/views/exam_templates/en.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/views/exam_templates/en.yml b/config/locales/views/exam_templates/en.yml index f5a8ca02c7..b4b887603e 100644 --- a/config/locales/views/exam_templates/en.yml +++ b/config/locales/views/exam_templates/en.yml @@ -29,7 +29,7 @@ en: create: add_division: Add Template Division add_new: Add Exam Template - failure: "Exam Template not successfully created%{errors}" + failure: Exam Template not successfully created%{errors} success: Exam Template successfully created upload: Upload Template delete: @@ -94,7 +94,7 @@ en: scan_error: Some files have not been scanned properly. submission_in_progress: Scanning QR codes done, now preparing PDF pages for grading update: - failure: "Exam Template has not been successfully updated%{errors}" + failure: Exam Template has not been successfully updated%{errors} instruction: Replace template file success: Exam Template has been successfully updated upload_scans: