<commit_before>class CertificateGenerator < ActiveRecord::Base

  belongs_to :user
  belongs_to :response_set
  belongs_to :certification_campaign

  has_one :dataset, through: :response_set
  has_one :certificate, through: :response_set
  has_one :survey, through: :response_set

  serialize :request, HashWithIndifferentAccess

  TYPES =  {
    none: 'string',
    one: 'radio',
    any: 'checkbox',
    repeater: 'repeating'
  }

  def self.schema(request)
    survey = Survey.newest_survey_for_access_code request['jurisdiction']
    return {errors: ['Jurisdiction not found']} if !survey

    schema = {}
    survey.questions.each do |q|
      next if q.display_type == 'label'
      schema[q.reference_identifier] = question = {question: q.text, type: TYPES[q.type], required: q.is_mandatory}

      if q.type == :one || q.type == :any
        question['options'] = {}
        q.answers.each{|a| question['options'][a.reference_identifier] = a.text }
      end

      question
    end

    {schema: schema}
  end

  # attempt to build a certificate from the request
  def self.update(dataset, request, jurisdiction, user)

    # Finds a migrated survey if there is one
    survey = Survey.newest_survey_for_access_code Survey::migrate_access_code(jurisdiction)
    return {success: false, errors: ['Jurisdiction not found']} if !survey

    if user.admin?
      response_set = ResponseSet.where(dataset_id: dataset).latest
    else
      response_set = ResponseSet.where(dataset_id: dataset, user_id: user).latest
    end
    return {success: false, errors: ['Dataset not found']} if !response_set

    if survey != response_set.survey || !response_set.modifications_allowed?
      response_set = ResponseSet.clone_response_set(response_set, {survey_id: survey.id, user_id: user.id, dataset_id: response_set.dataset_id})
    end

    generator = response_set.certificate_generator || self.create(response_set: response_set, user: user)
    generator.request = request
    certificate = generator.generate(jurisdiction, false)
    response_set = certificate.response_set

    errors = []

    response_set.responses_with_url_type.each do |response|
      if response.error
        errors.push("The question '#{response.question.reference_identifier}' must have a valid URL")
      end
    end

    survey.questions.where(is_mandatory: true).each do |question|
      response = response_set.responses.detect {|r| r.question_id == question.id}

      if !response || response.empty?
        errors.push("The question '#{question.reference_identifier}' is mandatory")
      end
    end

    {success: true, published: response_set.published?, errors: errors}
  end

  def generate(jurisdiction, create_user, dataset = nil)
    build_response_set(survey: Survey.newest_survey_for_access_code(jurisdiction))
    # mass assignment protection avoidance
    response_set.dataset = dataset if dataset
    save!

    # find the questions which are to be answered
    survey.questions
          .where({reference_identifier: request.keys})
          .includes(:answers)
          .each {|question| answer question}
<commit_msg>Only build response set if necessary<commit_after>class CertificateGenerator < ActiveRecord::Base

  belongs_to :user
  belongs_to :response_set
  belongs_to :certification_campaign

  has_one :dataset, through: :response_set
  has_one :certificate, through: :response_set
  has_one :survey, through: :response_set

  serialize :request, HashWithIndifferentAccess

  TYPES =  {
    none: 'string',
    one: 'radio',
    any: 'checkbox',
    repeater: 'repeating'
  }

  def self.schema(request)
    survey = Survey.newest_survey_for_access_code request['jurisdiction']
    return {errors: ['Jurisdiction not found']} if !survey

    schema = {}
    survey.questions.each do |q|
      next if q.display_type == 'label'
      schema[q.reference_identifier] = question = {question: q.text, type: TYPES[q.type], required: q.is_mandatory}

      if q.type == :one || q.type == :any
        question['options'] = {}
        q.answers.each{|a| question['options'][a.reference_identifier] = a.text }
      end

      question
    end

    {schema: schema}
  end

  # attempt to build a certificate from the request
  def self.update(dataset, request, jurisdiction, user)

    # Finds a migrated survey if there is one
    survey = Survey.newest_survey_for_access_code Survey::migrate_access_code(jurisdiction)
    return {success: false, errors: ['Jurisdiction not found']} if !survey

    if user.admin?
      response_set = ResponseSet.where(dataset_id: dataset).latest
    else
      response_set = ResponseSet.where(dataset_id: dataset, user_id: user).latest
    end
    return {success: false, errors: ['Dataset not found']} if !response_set

    if survey != response_set.survey || !response_set.modifications_allowed?
      response_set = ResponseSet.clone_response_set(response_set, {survey_id: survey.id, user_id: user.id, dataset_id: response_set.dataset_id})
    end

    generator = response_set.certificate_generator || self.create(response_set: response_set, user: user)
    generator.request = request
    certificate = generator.generate(jurisdiction, false)
    response_set = certificate.response_set

    errors = []

    response_set.responses_with_url_type.each do |response|
      if response.error
        errors.push("The question '#{response.question.reference_identifier}' must have a valid URL")
      end
    end

    survey.questions.where(is_mandatory: true).each do |question|
      response = response_set.responses.detect {|r| r.question_id == question.id}

      if !response || response.empty?
        errors.push("The question '#{question.reference_identifier}' is mandatory")
      end
    end

    {success: true, published: response_set.published?, errors: errors}
  end

  def generate(jurisdiction, create_user, dataset = nil)
    unless response_set
      build_response_set(survey: Survey.newest_survey_for_access_code(jurisdiction))
      # mass assignment protection avoidance
      response_set.dataset = dataset if dataset
      save!
    end

    # find the questions which are to be answered
    survey.questions
          .where({reference_identifier: request.keys})
          .includes(:answers)
          .each {|question| answer question}

{'fraction_non_alphanumeric': 0.0986518636003172, 'fraction_numerical': 0.0, 'mean_word_length': 3.7024608501118568, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '910950', 'n_tokens_mistral': 1907, 'n_tokens_neox': 1842, 'n_words': 468}