Skip to content

Commit 5ecc5fa

Browse files
committed
Add ProFormA validity checks and disable exporting not invalid
1 parent 5309eb3 commit 5ecc5fa

File tree

9 files changed

+147
-4
lines changed

9 files changed

+147
-4
lines changed

app/assets/stylesheets/tasks.css.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@
110110
margin-bottom: 0 !important;
111111
}
112112
}
113+
.button-box{
114+
115+
.btn.disabled{
116+
border: 1px solid lightgray;
117+
}
118+
}
119+
120+
.disabled-btn-wrapper {
121+
width: 100%;
122+
}
113123

114124
.completeness-checklist-container {
115125
background: white;

app/controllers/task_contributions_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def show
4545
@files = @task.files
4646
@tests = @task.tests
4747
@model_solutions = @task.model_solutions
48+
@proforma_valid = ProformaService::Validation.call(task: @task)
4849

4950
@user_rating = @task.ratings&.find_by(user: current_user)&.rating
5051
render 'tasks/show'

app/controllers/tasks_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def show
3838
@tests = @task.tests
3939
@model_solutions = @task.model_solutions
4040

41+
@proforma_valid = ProformaService::Validation.call(task: @task)
4142
@user_rating = @task.ratings&.find_by(user: current_user) || Rating.new(Rating::CATEGORIES.index_with {|_category| 0 })
4243
end
4344

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module ProformaService
4+
class Validation < ServiceBase
5+
def initialize(task:)
6+
super()
7+
@task = task
8+
end
9+
10+
# Returns a hash: { <version> => valid?, nil => all_versions_valid? }
11+
def execute
12+
result = ProformaXML::SCHEMA_VERSIONS.index_with {|version| version_valid?(version:) }
13+
result[nil] = result.values.all?
14+
result
15+
end
16+
17+
private
18+
19+
def version_valid?(version:)
20+
ProformaService::ExportTask.call(task: @task, options: {version:})
21+
true
22+
rescue ProformaXML::PostGenerateValidationError
23+
false
24+
end
25+
end
26+
end

app/views/tasks/show.html.slim

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,13 +519,22 @@
519519
.wrapper
520520
- if policy(@task).download?
521521
.dropdown.btn-group
522-
= button_tag class: 'btn btn-light dropdown-toggle', data: {bs_toggle: 'dropdown'} do
523-
= t('common.button.download_zip')
522+
- if @proforma_valid[nil]
523+
= button_tag class: 'btn btn-light dropdown-toggle', data: {bs_toggle: 'dropdown'} do
524+
= t('common.button.download_zip')
525+
- else
526+
.disabled-btn-wrapper data-bs-toggle='tooltip' title=t('.not_proforma_valid', version: '')
527+
= button_tag class: 'btn btn-light dropdown-toggle disabled', 'data-bs-toggle': 'dropdown' do
528+
= t('common.button.download_zip')
524529
ul.scrollable.dropdown-menu role='menu'
525530
li.dropdown-header = "#{t('common.button.available_versions')}: "
526531
- ProformaXML::SCHEMA_VERSIONS.each do |proforma_version|
527532
li
528-
= link_to(proforma_version, download_task_path(@task, version: proforma_version), class: 'btn btn-light dropdown-item', target: '_blank', rel: 'noopener noreferrer')
533+
- if @proforma_valid[proforma_version]
534+
= link_to proforma_version, download_task_path(@task, version: proforma_version), class: 'btn btn-light dropdown-item', target: '_blank', rel: 'noopener noreferrer'
535+
- else
536+
.disabled-btn-wrapper data-bs-toggle='tooltip' title=t('.not_proforma_valid', version: " (#{proforma_version})")
537+
= link_to(proforma_version, download_task_path(@task, version: proforma_version), class: 'btn btn-light dropdown-item disabled', target: '_blank', rel: 'noopener noreferrer')
529538

530539
- else
531540
div data-bs-toggle='tooltip' title=unavailable_tooltip data-bs-delay=150
@@ -535,6 +544,7 @@
535544
.dropdown.btn-group
536545
= button_tag class: 'btn btn-light dropdown-toggle', data: {bs_toggle: 'dropdown'} do
537546
= t('.button.export')
547+
538548
ul.scrollable.dropdown-menu role='menu'
539549
li.dropdown-header = "#{t('tasks.show.export_to')}: "
540550
- if current_user.available_account_links.empty?
@@ -543,7 +553,12 @@
543553
- else
544554
- current_user.available_account_links.each do |acc_link|
545555
li
546-
= button_to(acc_link.name, export_external_start_task_path(account_link: acc_link), method: :post, remote: true, class: 'dropdown-item export-test')
556+
- if @proforma_valid[acc_link.proforma_version || ProformaXML::SCHEMA_VERSION_LATEST]
557+
= link_to(acc_link.name, export_external_start_task_path(account_link: acc_link), method: :post, remote: true, class: 'dropdown-item export-test')
558+
- else
559+
.disabled-btn-wrapper data-bs-toggle='tooltip' title=t('.not_proforma_valid', version: " (#{acc_link.proforma_version || ProformaXML::SCHEMA_VERSION_LATEST})")
560+
= link_to(acc_link.name, export_external_start_task_path(account_link: acc_link), method: :post, remote: true, class: 'dropdown-item export-test disabled')
561+
547562
- else
548563
div data-bs-toggle='tooltip' title=unavailable_tooltip data-bs-delay=150
549564
= button_tag class: 'btn btn-outline-dark dropdown-toggle disabled', data: {bs_toggle: 'dropdown'} do

config/locales/de/views/tasks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ de:
113113
no_license: Keine
114114
no_model_solution_present: Keine Musterlösungen vorhanden
115115
no_tests: Keine Tests enthalten
116+
not_proforma_valid: Die Aufgabe ist nicht in ProFormA%{version} exportierbar
116117
owner_required_tooltip: Sie müssen der Autor der Aufgabe sein, um die Funktion zu verwenden.
117118
remove_task_from_collection_warning: Sind Sie sicher, dass Sie diese Aufgabe aus der Sammlung entfernen wollen?
118119
task_contribution:

config/locales/en/views/tasks.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ en:
113113
no_license: None
114114
no_model_solution_present: No Model Solutions present
115115
no_tests: No Tests included
116+
not_proforma_valid: The task is not exportable in ProFormA%{version}.
116117
owner_required_tooltip: This feature can only be used by the owner of the task.
117118
remove_task_from_collection_warning: Are you sure you want to remove this Task from the Collection?
118119
task_contribution:

spec/controllers/tasks_controller_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,25 @@
219219
expect(response).to redirect_to([contribution.base, contribution])
220220
end
221221
end
222+
223+
context 'when checking proforma validity' do
224+
before do
225+
stub_const('ProformaXML::SCHEMA_VERSIONS', ['2.0'])
226+
227+
validation_result = {nil => true, '2.0' => false}
228+
allow(ProformaService::Validation).to receive(:call).with(task: task).and_return(validation_result)
229+
end
230+
231+
it 'assigns proforma_valid to instance variable' do
232+
get_request
233+
expect(assigns(:proforma_valid)).to be_a(Hash)
234+
end
235+
236+
it 'includes all values in proforma_valid hash' do
237+
get_request
238+
expect(assigns(:proforma_valid)).to eql({nil => true, '2.0' => false})
239+
end
240+
end
222241
end
223242
end
224243

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe ProformaService::Validation do
6+
describe '.new' do
7+
subject(:validation) do
8+
described_class.new(task:)
9+
end
10+
11+
let(:task) { build(:task) }
12+
13+
it 'assigns task' do
14+
expect(validation.instance_variable_get(:@task)).to be task
15+
end
16+
end
17+
18+
describe '.call' do
19+
subject(:validation) { described_class.call(task:) }
20+
21+
let(:task) { create(:task) }
22+
23+
before do
24+
stub_const('ProformaXML::SCHEMA_VERSIONS', ['2.0', '2.1'])
25+
end
26+
27+
context 'when the task is valid for all schema versions' do
28+
before do
29+
allow(ProformaService::ExportTask).to receive(:call).and_return(true)
30+
end
31+
32+
it 'returns a hash with all versions as valid' do
33+
expect(validation[nil]).to be true
34+
expect(validation['2.0']).to be true
35+
expect(validation['2.1']).to be true
36+
end
37+
end
38+
39+
context 'when the task is invalid for a schema version' do
40+
before do
41+
allow(ProformaService::ExportTask).to receive(:call).and_raise(ProformaXML::PostGenerateValidationError, '["not valid"]')
42+
end
43+
44+
it 'returns a hash with all versions as invalid' do
45+
expect(validation[nil]).to be false
46+
expect(validation['2.0']).to be false
47+
expect(validation['2.1']).to be false
48+
end
49+
end
50+
51+
context 'when some versions are valid and others are invalid' do
52+
before do
53+
allow(ProformaService::ExportTask).to receive(:call)
54+
.with(task: task, options: {version: '2.0'})
55+
.and_return(true)
56+
57+
allow(ProformaService::ExportTask).to receive(:call)
58+
.with(task: task, options: {version: '2.1'})
59+
.and_raise(ProformaXML::PostGenerateValidationError, '["not valid"]')
60+
end
61+
62+
it 'returns a hash with correct validity for each version' do
63+
expect(validation['2.0']).to be true
64+
expect(validation['2.1']).to be false
65+
expect(validation[nil]).to be false
66+
end
67+
end
68+
end
69+
end

0 commit comments

Comments
 (0)