From 138b0b5c432b6d5c4dd1fdd8361d23286928b57f Mon Sep 17 00:00:00 2001
From: Marten Veldthuis <marten@roqua.nl>
Date: Tue, 30 Mar 2021 10:30:57 +0000
Subject: [PATCH] Validate uniqueness of export keys

---
 .../compiler/services/definition_validator.rb  | 10 +++++++---
 .../services/definition_validator_spec.rb      | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/lib/quby/compiler/services/definition_validator.rb b/lib/quby/compiler/services/definition_validator.rb
index 6785a6b..6cf8c58 100644
--- a/lib/quby/compiler/services/definition_validator.rb
+++ b/lib/quby/compiler/services/definition_validator.rb
@@ -25,7 +25,6 @@ module Quby
           validate_outcome_tables(questionnaire)
           validate_markdown_fields(questionnaire) if questionnaire.validate_html
           validate_raw_content_items(questionnaire) if questionnaire.validate_html
-          validate_scores(questionnaire)
         # Some compilation errors are Exceptions (pure syntax errors) and some StandardErrors (NameErrors)
         rescue Exception => exception # rubocop:disable Lint/RescueException
           definition.errors.add(:sourcecode, {message: "Questionnaire error: #{definition.key}\n" \
@@ -81,6 +80,13 @@ module Quby
             fail "Score #{score.key} does not have a score schema" unless score_schema
             fail "Score label langer dan 100 tekens (geeft problemen oru accare)\n #{score_schema.label}" if score_schema.label&.length > 100
           end
+
+          export_keys = questionnaire.score_schemas.flat_map { |_key, score_schema|
+            score_schema.subscore_schemas.map(&:export_key)
+          }
+
+          duplicate_export_keys = export_keys.tally.select { |key, count| count > 1 }.keys
+          fail "Score export keys not unique, duplicates: #{duplicate_export_keys}" if duplicate_export_keys.present?
         end
 
         def validate_question_options(questionnaire, question)
@@ -241,8 +247,6 @@ scores_schema tables to the resulting seed."
 
         def validate_score_label_present(score)
           fail "Score #{score.key} label must be passed in as an option." unless score.label.present?
-
-
         end
 
         def validate_subquestion_absence_in_select(question)
diff --git a/spec/quby/compiler/services/definition_validator_spec.rb b/spec/quby/compiler/services/definition_validator_spec.rb
index 65309bc..09a1aac 100644
--- a/spec/quby/compiler/services/definition_validator_spec.rb
+++ b/spec/quby/compiler/services/definition_validator_spec.rb
@@ -821,5 +821,23 @@ module Quby::Compiler::Services
         expect(definition.valid?).to be true
       end
     end
+
+    describe '#validate_scores' do
+      it 'fails on duplicate export keys' do
+        definition = make_definition(<<-END)
+          title "Test"
+          score :tot, label: "Totaalscore", schema: [{:export_key=>:tot, :label=>"Score", :key=>:value}] do
+            {}
+          end
+
+          score :tot2, label: "Totaalscore", schema: [{:export_key=>:tot, :label=>"Score", :key=>:value}] do
+            {}
+          end
+        END
+        expect(definition.valid?).to be false
+        expect(definition.errors.full_messages.first).to \
+            include('Score export keys not unique, duplicates: [:tot]')
+      end
+    end
   end
 end
-- 
GitLab