From 3b99b0870f89957e83e161fa3c44062af430e304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Felipe=20Pimentel?= Date: Tue, 12 Nov 2024 00:07:52 -0300 Subject: [PATCH 1/8] Add factories and validation tests for admission forms --- app/models/admissions/filled_form_field.rb | 2 +- .../factory_admission_application.rb | 17 + .../admissions/factory_admission_process.rb | 19 + .../admissions/factory_filled_form.rb | 15 + .../admissions/factory_filled_form_field.rb | 18 + .../factory_filled_form_field_scholarity.rb | 23 + .../admissions/factory_form_condition.rb | 17 + .../admissions/factory_form_field.rb | 16 + .../admissions/factory_form_template.rb | 15 + .../filled_form_field_scholarity_spec.rb | 150 +++++ .../admissions/filled_form_field_spec.rb | 514 ++++++++++++++++++ spec/models/admissions/filled_form_spec.rb | 52 ++ spec/models/admissions/form_condition_spec.rb | 91 ++++ spec/models/admissions/form_field_spec.rb | 97 ++++ spec/models/admissions/form_template_spec.rb | 77 +++ spec/support/matchers/error_matchers.rb | 52 ++ 16 files changed, 1174 insertions(+), 1 deletion(-) create mode 100644 spec/factories/admissions/factory_admission_application.rb create mode 100644 spec/factories/admissions/factory_admission_process.rb create mode 100644 spec/factories/admissions/factory_filled_form.rb create mode 100644 spec/factories/admissions/factory_filled_form_field.rb create mode 100644 spec/factories/admissions/factory_filled_form_field_scholarity.rb create mode 100644 spec/factories/admissions/factory_form_condition.rb create mode 100644 spec/factories/admissions/factory_form_field.rb create mode 100644 spec/factories/admissions/factory_form_template.rb create mode 100644 spec/models/admissions/filled_form_field_scholarity_spec.rb create mode 100644 spec/models/admissions/filled_form_field_spec.rb create mode 100644 spec/models/admissions/filled_form_spec.rb create mode 100644 spec/models/admissions/form_condition_spec.rb create mode 100644 spec/models/admissions/form_field_spec.rb create mode 100644 spec/models/admissions/form_template_spec.rb diff --git a/app/models/admissions/filled_form_field.rb b/app/models/admissions/filled_form_field.rb index 6414f4d1..aadcabfc 100644 --- a/app/models/admissions/filled_form_field.rb +++ b/app/models/admissions/filled_form_field.rb @@ -189,7 +189,7 @@ def validate_file_field(configuration, is_photo: false) values << ".jpg" if is_photo filename = self.file.filename.downcase if values.none? { |ext| filename.end_with?(ext.downcase) } - add_error(:extension, valid: configuration["values"].join(', ')) + add_error(:extension, valid: configuration["values"].join(", ")) end end end diff --git a/spec/factories/admissions/factory_admission_application.rb b/spec/factories/admissions/factory_admission_application.rb new file mode 100644 index 00000000..3dfe8c72 --- /dev/null +++ b/spec/factories/admissions/factory_admission_application.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_application, class: Admissions::AdmissionApplication, aliases: [ + "admissions/admission_application" + ] do + name { "ana" } + email { "ana@email.com" } + admission_process + filled_form + end +end diff --git a/spec/factories/admissions/factory_admission_process.rb b/spec/factories/admissions/factory_admission_process.rb new file mode 100644 index 00000000..ce54f6a4 --- /dev/null +++ b/spec/factories/admissions/factory_admission_process.rb @@ -0,0 +1,19 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_process, class: Admissions::AdmissionProcess, aliases: [ + "admissions/admission_process" + ] do + name { "Mestrado 2024.1" } + year { 2024 } + semester { 1 } + start_date { Date.parse("2024/01/01") } + end_date { Date.parse("2024/02/01") } + form_template + end +end diff --git a/spec/factories/admissions/factory_filled_form.rb b/spec/factories/admissions/factory_filled_form.rb new file mode 100644 index 00000000..cfc476b6 --- /dev/null +++ b/spec/factories/admissions/factory_filled_form.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :filled_form, class: Admissions::FilledForm, aliases: [ + "admissions/filled_form" + ] do + form_template + is_filled { false } + end +end diff --git a/spec/factories/admissions/factory_filled_form_field.rb b/spec/factories/admissions/factory_filled_form_field.rb new file mode 100644 index 00000000..1c567cfc --- /dev/null +++ b/spec/factories/admissions/factory_filled_form_field.rb @@ -0,0 +1,18 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :filled_form_field, class: Admissions::FilledFormField, aliases: [ + "admissions/filled_form_field" + ] do + value { "1" } + file { nil } + list { nil } + filled_form + form_field + end +end diff --git a/spec/factories/admissions/factory_filled_form_field_scholarity.rb b/spec/factories/admissions/factory_filled_form_field_scholarity.rb new file mode 100644 index 00000000..d6c784b5 --- /dev/null +++ b/spec/factories/admissions/factory_filled_form_field_scholarity.rb @@ -0,0 +1,23 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :filled_form_field_scholarity, class: Admissions::FilledFormFieldScholarity, aliases: [ + "admissions/filled_form_field_scholarity" + ] do + filled_form_field + level { "Graduação" } + status { "Completo" } + institution { "UFF" } + course { "Computação" } + location { "Niteroi/RJ" } + grade { "9" } + grade_interval { "0..10" } + start_date { 5.years.ago } + end_date { 1.year.ago } + end +end diff --git a/spec/factories/admissions/factory_form_condition.rb b/spec/factories/admissions/factory_form_condition.rb new file mode 100644 index 00000000..2ab56b27 --- /dev/null +++ b/spec/factories/admissions/factory_form_condition.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :form_condition, class: Admissions::FormCondition, aliases: [ + "admissions/form_condition" + ] do + mode { Admissions::FormCondition::NONE } + field { "a" } + condition { "=" } + value { "1" } + end +end diff --git a/spec/factories/admissions/factory_form_field.rb b/spec/factories/admissions/factory_form_field.rb new file mode 100644 index 00000000..23d4feca --- /dev/null +++ b/spec/factories/admissions/factory_form_field.rb @@ -0,0 +1,16 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :form_field, class: Admissions::FormField, aliases: [ + "admissions/form_field" + ] do + name { "Campo" } + field_type { Admissions::FormField::TEXT } + form_template + end +end diff --git a/spec/factories/admissions/factory_form_template.rb b/spec/factories/admissions/factory_form_template.rb new file mode 100644 index 00000000..10bd2944 --- /dev/null +++ b/spec/factories/admissions/factory_form_template.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :form_template, class: Admissions::FormTemplate, aliases: [ + "admissions/form_template" + ] do + name { "Formulario" } + template_type { "Formulário" } + end +end diff --git a/spec/models/admissions/filled_form_field_scholarity_spec.rb b/spec/models/admissions/filled_form_field_scholarity_spec.rb new file mode 100644 index 00000000..8aa0f652 --- /dev/null +++ b/spec/models/admissions/filled_form_field_scholarity_spec.rb @@ -0,0 +1,150 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + + +RSpec.describe Admissions::FilledFormFieldScholarity, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:filled_form_field).required(true) } + + before(:all) do + @destroy_later = [] + @form_template = FactoryBot.create(:form_template) + @filled_form = FactoryBot.create(:filled_form, form_template: @form_template) + @form_field = FactoryBot.create( + :form_field, form_template: @form_template, + field_type: Admissions::FormField::SCHOLARITY, + configuration: '{"values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + ) + @filled_form_field = FactoryBot.build( + :filled_form_field, filled_form: @filled_form, form_field: @form_field + ) + @filled_form_field_scholarity = @filled_form_field.scholarities.build( + filled_form_field: @filled_form_field, + level: 1, + status: 1, + institution: "UFF", + course: "Computação", + location: "Niteroi/RJ", + grade: "9", + grade_interval: "0..10", + start_date: 5.years.ago, + end_date: 1.year.ago + ) + @filled_form_field_scholarity.filled_form_field = @filled_form_field + end + after(:all) do + @filled_form.delete + @form_field.delete + @form_template.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:filled_form_field_scholarity) do + @filled_form_field_scholarity.filled_form_field = @filled_form_field + @filled_form_field_scholarity + end + subject { filled_form_field_scholarity } + describe "Validations" do + it { should be_valid } + describe "that_value_follows_configuration_rules" do + before(:each) do + filled_form_field_scholarity.assign_attributes( + level: 1, + status: 1, + institution: "UFF", + course: "Computação", + location: "Niteroi/RJ", + grade: "9", + grade_interval: "0..10", + start_date: 5.years.ago, + end_date: 1.year.ago + ) + end + it "should be valid when all values are filled" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + expect(filled_form_field_scholarity).to be_valid + expect(@filled_form_field).to be_valid + end + it "should be valid when no values are required" do + @form_field.configuration = '{"scholarity_level_required": false, "scholarity_status_required": false, "scholarity_institution_required": false, "scholarity_course_required": false, "scholarity_location_required": false, "scholarity_grade_required": false, "scholarity_grade_interval_required": false, "scholarity_start_date_required": false, "scholarity_end_date_required": false, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.assign_attributes( + level: 1, + status: nil, + institution: nil, + course: nil, + location: nil, + grade: nil, + grade_interval: nil, + start_date: nil, + end_date: nil + ) + expect(filled_form_field_scholarity).to be_valid + expect(@filled_form_field).to be_valid + end + it "should have error when level is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.level = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Nível") + end + it "should have error when status is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.status = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Situação") + end + it "should have error when institution is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.institution = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Instituição") + end + it "should have error when course is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.course = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Curso") + end + it "should have error when location is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.location = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Cidade/Estado") + end + it "should have error when grade is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.grade = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "CR ou conceito obtido") + end + it "should have error when grade_interval is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.grade_interval = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Intervalo de CR ou conceito") + end + it "should have error when start_date is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.start_date = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Data de início") + end + it "should have error when end_date is required but blank" do + @form_field.configuration = '{"scholarity_level_required": true, "scholarity_status_required": true, "scholarity_institution_required": true, "scholarity_course_required": true, "scholarity_location_required": true, "scholarity_grade_required": true, "scholarity_grade_interval_required": true, "scholarity_start_date_required": true, "scholarity_end_date_required": true, "values": ["Graduação", "Mestrado", "Doutorado"], "statuses": ["Completo", "Incompleto"]}' + filled_form_field_scholarity.end_date = nil + expect(@filled_form_field).not_to be_valid + expect(@filled_form_field).to have_field_error(:scholarity_blank).on(:value).with_parameters(attr: "Data de término") + end + end + end + + describe "Methods" do + # ToDo: test to_label + end +end diff --git a/spec/models/admissions/filled_form_field_spec.rb b/spec/models/admissions/filled_form_field_spec.rb new file mode 100644 index 00000000..da4bb4ee --- /dev/null +++ b/spec/models/admissions/filled_form_field_spec.rb @@ -0,0 +1,514 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + + +RSpec.describe Admissions::FilledFormField, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:filled_form).required(true) } + it { should belong_to(:form_field).required(true) } + it { should have_many(:scholarities).dependent(:delete_all) } + + before(:all) do + @destroy_later = [] + @form_template = FactoryBot.create(:form_template) + @filled_form = FactoryBot.create(:filled_form, form_template: @form_template) + @form_field = FactoryBot.create(:form_field, form_template: @form_template) + end + after(:all) do + @filled_form.delete + @form_field.delete + @form_template.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:filled_form) do + Admissions::FilledFormField.new( + value: "1", + filled_form: @filled_form, + form_field: @form_field + ) + end + subject { filled_form } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:filled_form) } + it { should validate_presence_of(:form_field) } + describe "that_either_value_or_file_is_filled" do + it "should be valid when no values are filled" do + @form_field.configuration = '{"required": false}' + filled_form.value = nil + filled_form.file = nil + filled_form.list = nil + expect(filled_form).to be_valid + end + it "should be valid when only one value is filled" do + filled_form.value = "1" + filled_form.file = nil + filled_form.list = nil + expect(filled_form).to be_valid + end + it "should have error when more than one value is filled" do + @form_field.field_type = Admissions::FormField::TEXT + filled_form.value = "1" + filled_form.file = nil + filled_form.list = [1, 2] + expect(filled_form).to have_field_error(:multiple_filling).on :value + @form_field.field_type = Admissions::FormField::TEXT + filled_form.list = nil + end + it "should have error when more than one value is filled and attribute type is different" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + filled_form.value = "1" + filled_form.file = nil + filled_form.list = [1, 2] + expect(filled_form).to have_field_error(:multiple_filling).on :list + @form_field.field_type = Admissions::FormField::TEXT + filled_form.list = nil + end + end + describe "that_value_follows_configuration_rules" do + before(:each) do + filled_form.assign_attributes(value: nil, list: nil, file: nil) + end + describe "string fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::STRING + @form_field.configuration = '{"required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::STRING + @form_field.configuration = '{"required": true}' + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::STRING + @form_field.configuration = '{"required": true}' + filled_form.value = nil + expect(filled_form).to have_field_error(:blank).on :value + end + end + describe "select fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::SELECT + @form_field.configuration = '{"required": false, "values": "[1, 2]"}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::SELECT + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::SELECT + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.value = nil + expect(filled_form).to have_field_error(:blank).on :value + end + end + describe "radio fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::RADIO + @form_field.configuration = '{"required": false, "values": "[1, 2]"}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::RADIO + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::RADIO + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.value = nil + expect(filled_form).to have_field_error(:blank).on :value + end + end + describe "collection_checkbox fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": false, "values": "[1, 2]"}' + filled_form.list = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.list = ["1", "2"] + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]"}' + filled_form.list = nil + expect(filled_form).to have_field_error(:blank).on :list + end + it "valid when selection count >= minselection" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]", "minselection": 2}' + filled_form.list = ["1", "2"] + expect(filled_form).to be_valid + end + it "invalid when selection < minselection" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]", "minselection": 2}' + filled_form.list = ["1"] + expect(filled_form).to have_field_error(:minselection).on(:list).with_parameters(count: 2) + end + it "valid when selection count <= maxselection" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]", "maxselection": 2}' + filled_form.list = ["1", "2"] + expect(filled_form).to be_valid + end + it "invalid when selection > maxselection" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"required": true, "values": "[1, 2]", "maxselection": 2}' + filled_form.list = ["1", "2", "3"] + expect(filled_form).to have_field_error(:maxselection).on(:list).with_parameters(count: 2) + end + end + describe "text fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true}' + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true}' + filled_form.value = nil + expect(filled_form).to have_field_error(:blank).on :value + end + end + describe "city fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": false, "state_required": false, "country_required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when it only contains country and state, but city is not required" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": false, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when it only contains country, but city and state are not required" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": false, "state_required": false, "country_required": true}' + filled_form.value = " <$> <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "invalid when city is blank, but it is required " do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to have_field_error(:city_blank).on :value + end + it "invalid when state is blank, but it is required " do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> <$> Brasil" + expect(filled_form).to have_field_error(:state_blank).on :value + end + it "invalid when country is blank, but it is required " do + @form_field.field_type = Admissions::FormField::CITY + @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> " + expect(filled_form).to have_field_error(:country_blank).on :value + end + end + describe "residency fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::RESIDENCY + @form_field.configuration = '{"required": false, "number_required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when it only contains number, but street is not required" do + @form_field.field_type = Admissions::FormField::RESIDENCY + @form_field.configuration = '{"required": false, "number_required": true}' + filled_form.value = " <$> 1" + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::RESIDENCY + @form_field.configuration = '{"required": true, "number_required": true}' + filled_form.value = "Rua X <$> 1" + expect(filled_form).to be_valid + end + it "invalid when street is blank, but it is required " do + @form_field.field_type = Admissions::FormField::RESIDENCY + @form_field.configuration = '{"required": true, "number_required": true}' + filled_form.value = " <$> 1" + expect(filled_form).to have_field_error(:street_blank).on :value + end + it "invalid when number is blank, but it is required " do + @form_field.field_type = Admissions::FormField::RESIDENCY + @form_field.configuration = '{"required": true, "number_required": true}' + filled_form.value = "Rua X <$> " + expect(filled_form).to have_field_error(:number_blank).on :value + end + end + describe "number fields should be" do + it "valid when they are integers" do + @form_field.field_type = Admissions::FormField::NUMBER + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "valid when they are floats" do + @form_field.field_type = Admissions::FormField::NUMBER + filled_form.value = "1.1" + expect(filled_form).to be_valid + end + it "invalid when filled with elements that are not numbers" do + @form_field.field_type = Admissions::FormField::NUMBER + filled_form.value = "aaa" + expect(filled_form).to have_field_error(:invalid_number).on :value + end + end + describe "date fields should be" do + it "valid when they have date formats" do + @form_field.field_type = Admissions::FormField::DATE + filled_form.value = "11/11/2024" + expect(filled_form).to be_valid + end + it "invalid when filled with elements that are not dates" do + @form_field.field_type = Admissions::FormField::DATE + filled_form.value = "aaa" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + it "invalid when filled with dates that are not in the %d/%m/%Y format" do + @form_field.field_type = Admissions::FormField::DATE + filled_form.value = "01/30/2024" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + end + describe "student fields" do + describe "special_city should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": false, "state_required": false, "country_required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when it only contains country and state, but city is not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": false, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when it only contains country, but city and state are not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": false, "state_required": false, "country_required": true}' + filled_form.value = " <$> <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "invalid when city is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to have_field_error(:city_blank).on :value + end + it "invalid when state is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> <$> Brasil" + expect(filled_form).to have_field_error(:state_blank).on :value + end + it "invalid when country is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> " + expect(filled_form).to have_field_error(:country_blank).on :value + end + end + describe "special_birth_city should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": false, "country_required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when it only contains country and state, but city is not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when it only contains country, but city and state are not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": false, "country_required": true}' + filled_form.value = " <$> <$> Brasil" + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form).to be_valid + end + it "invalid when city is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = " <$> RJ <$> Brasil" + expect(filled_form).to have_field_error(:city_blank).on :value + end + it "invalid when state is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> <$> Brasil" + expect(filled_form).to have_field_error(:state_blank).on :value + end + it "invalid when country is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' + filled_form.value = "Niteroi <$> RJ <$> " + expect(filled_form).to have_field_error(:country_blank).on :value + end + end + describe "special_address should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address", "required": false, "number_required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when it only contains number, but street is not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address", "required": false, "number_required": true}' + filled_form.value = " <$> 1" + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' + filled_form.value = "Rua X <$> 1" + expect(filled_form).to be_valid + end + it "invalid when street is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' + filled_form.value = " <$> 1" + expect(filled_form).to have_field_error(:street_blank).on :value + end + it "invalid when number is blank, but it is required " do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' + filled_form.value = "Rua X <$> " + expect(filled_form).to have_field_error(:number_blank).on :value + end + end + describe "birthdate should be" do + it "valid when they have date formats" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "birthdate"}' + filled_form.value = "11/11/2024" + expect(filled_form).to be_valid + end + it "invalid when filled with elements that are not dates" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "birthdate"}' + filled_form.value = "aaa" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + it "invalid when filled with dates that are not in the %d/%m/%Y format" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "birthdate"}' + filled_form.value = "01/30/2024" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + end + describe "identity_expedition_date should be" do + it "valid when they have date formats" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "identity_expedition_date"}' + filled_form.value = "11/11/2024" + expect(filled_form).to be_valid + end + it "invalid when filled with elements that are not dates" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "identity_expedition_date"}' + filled_form.value = "aaa" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + it "invalid when filled with dates that are not in the %d/%m/%Y format" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "identity_expedition_date"}' + filled_form.value = "01/30/2024" + expect(filled_form).to have_field_error(:invalid_date).on :value + end + end + describe "other types of fields should be" do + it "valid when null and not required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "name", "required": false}' + filled_form.value = nil + expect(filled_form).to be_valid + end + it "valid when filled" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "name", "required": true}' + filled_form.value = "1" + expect(filled_form).to be_valid + end + it "invalid when null and required" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "name", "required": true}' + filled_form.value = nil + expect(filled_form).to have_field_error(:blank).on :value + end + end + end + # ToDo: validate file field (Admissions::FormField::FILE) + # - size_of_file + # - validate_file_field + # - Admissions::FormField::STUDENT_FIELD with field == "photo" + end + end + + describe "Methods" do + # ToDo: test set_default_values + # ToDo: test to_label + # ToDo: test to_text + # ToDo: test simple_value + # ToDo: test set_model_field + # ToDo: test get_type + # ToDo: test convert_value + # ToDo: test convert_string + # ToDo: test convert_number + # ToDo: test convert_date + end +end diff --git a/spec/models/admissions/filled_form_spec.rb b/spec/models/admissions/filled_form_spec.rb new file mode 100644 index 00000000..c8bc6d6f --- /dev/null +++ b/spec/models/admissions/filled_form_spec.rb @@ -0,0 +1,52 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + + +RSpec.describe Admissions::FilledForm, type: :model do + it { should be_able_to_be_destroyed } + it { should have_one(:admission_application).dependent(:restrict_with_exception) } + it { should have_one(:letter_request).dependent(:restrict_with_exception) } + it { should have_one(:admission_phase_evaluation).dependent(:destroy) } + it { should have_one(:admission_phase_result).dependent(:destroy) } + it { should have_one(:admission_ranking_result).dependent(:destroy) } + it { should have_many(:fields).dependent(:delete_all) } + it { should belong_to(:form_template).required(true) } + + before(:all) do + @destroy_later = [] + @form_template = FactoryBot.create(:form_template) + end + after(:all) do + @form_template.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:filled_form) do + Admissions::FilledForm.new( + form_template: @form_template, + is_filled: false + ) + end + subject { filled_form } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:form_template) } + end + + describe "Methods" do + # ToDo: test to_label + # ToDo: test to_fields_hash + # ToDo: test prepare_missing_fields + # ToDo: test sync_fields_before + # ToDo: test sync_fields_after + # ToDo: test consolidate + # ToDo: test find_cpf_field + # ToDo: test erase_non_filled_file_fields + end +end diff --git a/spec/models/admissions/form_condition_spec.rb b/spec/models/admissions/form_condition_spec.rb new file mode 100644 index 00000000..338de46a --- /dev/null +++ b/spec/models/admissions/form_condition_spec.rb @@ -0,0 +1,91 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::FormCondition, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:parent).required(false) } + it { should have_many(:form_conditions).dependent(:destroy) } + it { should have_many(:admission_phases_as_approval).dependent(:nullify) } + it { should have_many(:admission_committees).dependent(:nullify) } + it { should have_many(:admission_report_configs).dependent(:nullify) } + it { should have_many(:ranking_configs).dependent(:nullify) } + + before(:all) do + @destroy_later = [] + @field_a = FactoryBot.create(:form_field, name: "a") + @field_b = FactoryBot.create(:form_field, name: "b") + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + after(:all) do + @field_a.destroy + @field_b.destroy + end + let(:form_condition) do + Admissions::FormCondition.new( + mode: Admissions::FormCondition::NONE, + field: "a", + condition: "=", + value: "1" + ) + end + subject { form_condition } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:mode) } + describe "validate conditions" do + before(:each) do + form_condition.mode = Admissions::FormCondition::CONDITION + end + it { should validate_presence_of(:field) } + describe "that_field_name_exists" do + it "should be valid if field exists" do + form_condition.field = "a" + expect(form_condition).to be_valid + end + it "should have error if field does not exist" do + form_condition.field = "c" + expect(form_condition).to have_error(:field_not_found).on(:base).with_parameters(field: "c") + form_condition.field = "a" + end + end + end + describe "validate other modes" do + it "should be valid if field is blank" do + form_condition.mode = Admissions::FormCondition::NONE + form_condition.field = "" + expect(form_condition).to be_valid + end + end + end + describe "Duplication" do + it "should duplicate sub form_conditions" do + other = form_condition.form_conditions.build( + mode: Admissions::FormCondition::NONE, + field: "b", + condition: "=", + value: "1" + ) + expect(form_condition.form_conditions.size).to eql(1) + duplicate = form_condition.dup + expect(duplicate.form_conditions[0]).not_to be(other) + other.destroy + end + end + describe "Methods" do + # ToDo: test recursive_simple_validation + # ToDo: test update_pendencies + # ToDo: test to_label + # ToDo: test compare + # ToDo: test check_truth + # ToDo: test new_from_hash + # ToDo: test to_hash + # ToDo: test widget + end +end diff --git a/spec/models/admissions/form_field_spec.rb b/spec/models/admissions/form_field_spec.rb new file mode 100644 index 00000000..c78d2630 --- /dev/null +++ b/spec/models/admissions/form_field_spec.rb @@ -0,0 +1,97 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + + +RSpec.describe Admissions::FormField, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:filled_fields).dependent(:restrict_with_exception) } + it { should have_one(:ranking_config_as_position).dependent(:destroy) } + it { should have_one(:ranking_config_as_machine).dependent(:destroy) } + + before(:all) do + @destroy_later = [] + @form_template = FactoryBot.create(:form_template) + end + after(:all) do + @form_template.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:form_field) do + Admissions::FormField.new( + name: "Campo", + form_template: @form_template, + field_type: Admissions::FormField::STRING + ) + end + subject { form_field } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:form_template) } + it do + should validate_uniqueness_of(:sync).scoped_to(:form_template_id).allow_nil + end + it { should validate_inclusion_of(:field_type).in_array(Admissions::FormField::FIELD_TYPES) } + # ToDo: test sync + describe "configuration" do + context "should be valid when" do + it "field_type does not require extra configurations" do + form_field.field_type = Admissions::FormField::STRING + expect(form_field).to have(0).errors_on :base + end + end + context "for select field_type" do + context "should be valid when" do + it "configuration has values" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = JSON.dump({ values: ["a", "b"] }) + expect(form_field).to be_valid + expect(form_field).to have(0).errors_on :base + end + it "configurarion has valid sql" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = JSON.dump({ values_use_sql: true, values_sql: "select * from enrollments" }) + expect(form_field).to be_valid + expect(form_field).to have(0).errors_on :base + end + end + context "should have error when" do + it "configuration does not have sql nor values" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = nil + expect(form_field).not_to be_valid + expect(form_field).to have_error(:values_present_error).on :base + end + it "configuration has blank value" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = JSON.dump({ values: [""] }) + expect(form_field).not_to be_valid + expect(form_field).to have_error(:values_blank_error).on :base + end + end + it "configuration has blank sql" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = JSON.dump({ values_use_sql: true, values_sql: "" }) + expect(form_field).not_to be_valid + expect(form_field).to have_error(:values_sql_present_error).on :base + end + it "configuration has invalid sql" do + form_field.field_type = Admissions::FormField::SELECT + form_field.configuration = JSON.dump({ values_use_sql: true, values_sql: "select * from invalid" }) + expect(form_field).not_to be_valid + expect(form_field).to have(1).errors_on :base + end + end + end + end + + describe "Methods" do + end +end diff --git a/spec/models/admissions/form_template_spec.rb b/spec/models/admissions/form_template_spec.rb new file mode 100644 index 00000000..8174ad08 --- /dev/null +++ b/spec/models/admissions/form_template_spec.rb @@ -0,0 +1,77 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::FormTemplate, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:fields).dependent(:destroy) } + it { should have_many(:admission_process_forms).dependent(:restrict_with_exception) } + it { should have_many(:admission_process_letters).dependent(:restrict_with_exception) } + it { should have_many(:phase_member_forms).dependent(:restrict_with_exception) } + it { should have_many(:phase_shared_forms).dependent(:restrict_with_exception) } + it { should have_many(:phase_consolidation_forms).dependent(:restrict_with_exception) } + it { should have_one(:ranking_config).dependent(:destroy) } + it { should have_many(:admission_report_configs).dependent(:restrict_with_exception) } + + before(:all) do + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:form_template) do + Admissions::FormTemplate.new( + name: "Form", + template_type: Admissions::FormTemplate::ADMISSION_FORM, + ) + end + subject { form_template } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:template_type) } + it { should validate_inclusion_of(:template_type).in_array(Admissions::FormTemplate::TEMPLATE_TYPES) } + end + describe "Duplication" do + it "should duplicate fields" do + field = form_template.fields.build( + name: "str", + field_type: Admissions::FormField::STRING + ) + expect(form_template.fields.size).to eql(1) + duplicate = form_template.dup + expect(duplicate.fields[0]).not_to be(field) + field.destroy + end + end + describe "Methods" do + describe "has_file_fields?" do + it "should return false if it doesn't have any fields" do + expect(form_template.has_file_fields?).to eql(false) + expect(form_template.fields.size).to eql(0) + end + it "should return false if it doesn't have any file fields" do + field = form_template.fields.build( + name: "str", + field_type: Admissions::FormField::STRING + ) + expect(form_template.has_file_fields?).to eql(false) + expect(form_template.fields.size).to eql(1) + field.destroy + end + it "should return true if it hasfile fields" do + field = form_template.fields.build( + name: "file", + field_type: Admissions::FormField::FILE + ) + expect(form_template.has_file_fields?).to eql(true) + expect(form_template.fields.size).to eql(1) + field.destroy + end + end + end +end diff --git a/spec/support/matchers/error_matchers.rb b/spec/support/matchers/error_matchers.rb index 6f12b979..890ed1ec 100644 --- a/spec/support/matchers/error_matchers.rb +++ b/spec/support/matchers/error_matchers.rb @@ -49,3 +49,55 @@ def error_message(record, atributo, erro) "deve incluir erro de '#{erro}'" end end + + +RSpec::Matchers.define :have_field_error do |erro| + def error_message(record, atributo, erro) + translation_missing_message = "Translation missing:" + parameters = @parameters.blank? ? {} : @parameters + + message = I18n.t( + "activerecord.errors.full_messages.format", + attribute: record.form_field.name, + message: I18n.t(:"activerecord.errors.models.#{record.class.to_s.underscore}.#{erro}", **parameters) + ) + if message.include?(translation_missing_message) + message = I18n.translate("activerecord.errors.models.#{record.class.to_s.underscore}.#{erro}", **parameters) + message = message.include?(translation_missing_message) ? I18n.translate("activerecord.errors.models.#{record.class.to_s.underscore}.attributes.#{atributo}.#{erro}", **parameters) : message + end + message + end + + chain :on do |atributo| + @atributo = atributo + end + + chain :with_parameters do |parameters| + @parameters = parameters + end + + match do |record| + unless @atributo + raise "Deve incluir um atributo" + end + record.valid? + mensagem = error_message(record, @atributo, erro.to_s) + record.errors[@atributo].to_a.detect { |e| e == mensagem } + end + + failure_message do |record| + if @atributo + %{Esperava que [#{record.errors[@atributo].join(', ')}] incluísse "#{error_message(record, @atributo, erro.to_s)}"} + end + end + + failure_message_when_negated do |record| + if @atributo + %{Esperava que [#{record.errors[@atributo].join(', ')}] não incluísse "#{error_message(record, @atributo, erro.to_s)}"} + end + end + + description do + "deve incluir erro de '#{erro}'" + end +end From 235c702b812eab51e683740ef7d9aabfc7443637 Mon Sep 17 00:00:00 2001 From: Joao Felipe Pimentel Date: Thu, 28 Nov 2024 17:58:06 -0300 Subject: [PATCH 2/8] add admission phase and admission process validation tests --- app/models/admissions/admission_process.rb | 2 + .../admissions/factory_admission_phase.rb | 24 ++ .../admissions/factory_admission_process.rb | 10 + .../models/admissions/admission_phase_spec.rb | 56 ++++ .../admissions/admission_process_spec.rb | 250 ++++++++++++++++++ 5 files changed, 342 insertions(+) create mode 100644 spec/factories/admissions/factory_admission_phase.rb create mode 100644 spec/models/admissions/admission_phase_spec.rb create mode 100644 spec/models/admissions/admission_process_spec.rb diff --git a/app/models/admissions/admission_process.rb b/app/models/admissions/admission_process.rb index f802aa32..45e53aad 100644 --- a/app/models/admissions/admission_process.rb +++ b/app/models/admissions/admission_process.rb @@ -55,6 +55,7 @@ def max_edit_date end def end_greater_than_start_date + return if self.start_date.nil? || self.end_date.nil? if self.end_date < self.start_date self.errors.add(:base, :end_greater_than_start_date) end @@ -77,6 +78,7 @@ def max_greater_than_min_letters end def simple_url_is_unique_while_open + return if self.end_date.nil? return if self.end_date < Date.today if self.simple_url.to_i.to_s == self.simple_url diff --git a/spec/factories/admissions/factory_admission_phase.rb b/spec/factories/admissions/factory_admission_phase.rb new file mode 100644 index 00000000..9103e339 --- /dev/null +++ b/spec/factories/admissions/factory_admission_phase.rb @@ -0,0 +1,24 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_phase, class: Admissions::AdmissionPhase, aliases: [ + "admissions/admission_phase" + ] do + #association :approval_condition, factory: form_condition + #association :keep_in_phase_condition, factory: form_condition + #association :member_form, factory: form_template + #association :shared_form, factory: form_template + #association :consolidation_form, factory: form_template + #association :candidate_form, factory: form_template + name { "Fase 1" } + can_edit_candidate { false } + candidate_can_see_member { false } + candidate_can_see_shared { false } + candidate_can_see_consolidation { false } + end +end diff --git a/spec/factories/admissions/factory_admission_process.rb b/spec/factories/admissions/factory_admission_process.rb index ce54f6a4..0a03c99e 100644 --- a/spec/factories/admissions/factory_admission_process.rb +++ b/spec/factories/admissions/factory_admission_process.rb @@ -10,10 +10,20 @@ "admissions/admission_process" ] do name { "Mestrado 2024.1" } + simple_url { "mestrado" } year { 2024 } semester { 1 } start_date { Date.parse("2024/01/01") } end_date { Date.parse("2024/02/01") } + edit_date { Date.parse("2024/02/15") } form_template + # letter_template + min_letters { 0 } + max_letters { 0 } + allow_multiple_applications { false } + visible { true } + staff_can_edit { true } + staff_can_undo { true } + require_session { false } end end diff --git a/spec/models/admissions/admission_phase_spec.rb b/spec/models/admissions/admission_phase_spec.rb new file mode 100644 index 00000000..5abc956e --- /dev/null +++ b/spec/models/admissions/admission_phase_spec.rb @@ -0,0 +1,56 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionPhase, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:admission_phase_committees).dependent(:destroy) } + it { should have_many(:admission_committees).through(:admission_phase_committees) } + it { should have_many(:admission_phase_results).dependent(:destroy) } + it { should have_many(:admission_phase_evaluations).dependent(:destroy) } + it { should have_many(:admission_process_phases).dependent(:destroy) } + it { should have_many(:admission_applications).dependent(:destroy) } + it { should have_many(:admission_pendencies).dependent(:destroy) } + it { should have_many(:admission_process_rankings).dependent(:nullify) } + + it { should belong_to(:approval_condition).required(false) } + it { should belong_to(:keep_in_phase_condition).required(false) } + it { should belong_to(:member_form).required(false) } + it { should belong_to(:shared_form).required(false) } + it { should belong_to(:consolidation_form).required(false) } + it { should belong_to(:candidate_form).required(false) } + + before(:all) do + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_phase) do + Admissions::AdmissionPhase.new( + name: "Fase 1", + can_edit_candidate: false, + candidate_can_see_member: false, + candidate_can_see_shared: false, + candidate_can_see_consolidation: false, + ) + end + subject { admission_phase } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + end + describe "Duplication" do + # ToDo: initialize_dup + end + describe "Methods" do + # ToDo: committee_users_for_candidate + # ToDo: update_pendencies + # ToDo: create_pendencies_for_candidate + # ToDo: prepare_application_forms + end +end diff --git a/spec/models/admissions/admission_process_spec.rb b/spec/models/admissions/admission_process_spec.rb new file mode 100644 index 00000000..3a77591e --- /dev/null +++ b/spec/models/admissions/admission_process_spec.rb @@ -0,0 +1,250 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionProcess, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:admission_applications).dependent(:restrict_with_exception) } + it { should have_many(:phases).dependent(:restrict_with_exception) } + it { should have_many(:rankings).dependent(:destroy) } + + it { should belong_to(:form_template).required(true) } + it { should belong_to(:letter_template).required(false) } + it { should belong_to(:level).required(false) } + it { should belong_to(:enrollment_status).required(false) } + + before(:all) do + @form_template = FactoryBot.create(:form_template) + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + @form_template.delete + end + let(:admission_process) do + Admissions::AdmissionProcess.new( + name: "Mestrado 2024.1", + year: 2024, + semester: 1, + start_date: Date.parse("2024/01/01"), + end_date: Date.parse("2024/02/01"), + edit_date: Date.parse("2024/02/15"), + form_template: @form_template + ) + end + subject { admission_process } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:form_template) } + it { should validate_numericality_of(:min_letters).is_greater_than(-1).only_integer.allow_nil } + it { should validate_numericality_of(:max_letters).is_greater_than(-1).only_integer.allow_nil } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:year) } + it { should validate_presence_of(:semester) } + it { should validate_inclusion_of(:semester).in_array(YearSemester::SEMESTERS) } + it { should validate_presence_of(:start_date) } + it { should validate_presence_of(:end_date) } + describe "end_date" do + context "should be valid when" do + it "end_date is greater than start_date" do + admission_process.end_date = admission_process.start_date + 1.month + expect(admission_process).to have(0).errors_on :base + admission_process.end_date = Date.parse("2024/02/01") + end + end + context "should have error end_greater_than_start_date when" do + it "start_date is greater than end_date" do + admission_process.end_date = admission_process.start_date - 1.month + expect(admission_process).to have_error(:end_greater_than_start_date).on :base + admission_process.end_date = Date.parse("2024/02/01") + end + end + end + describe "letters" do + context "should be valid when" do + it "max_letters is nil" do + admission_process.min_letters = 1 + admission_process.max_letters = nil + expect(admission_process).to have(0).errors_on :base + admission_process.min_letters = nil + end + it "max_letters is greater than min_letters" do + admission_process.min_letters = 1 + admission_process.max_letters = 2 + expect(admission_process).to have(0).errors_on :base + admission_process.min_letters = nil + admission_process.max_letters = nil + end + end + context "should have error max_greater_than_min_letters when" do + it "min_letters is greater than max_greater_than_min_letters" do + admission_process.min_letters = 2 + admission_process.max_letters = 1 + expect(admission_process).to have_error(:max_greater_than_min_letters).on :base + admission_process.min_letters = nil + admission_process.max_letters = nil + end + end + end + describe "simple_url" do + context "should be valid when" do + it "there are no other processes with the same simple_url in the same range" do + admission_process.simple_url = "mestrado" + admission_process.start_date = Date.parse("2024/01/01") + admission_process.end_date = Date.today + 1.month + # Date overlap, different simple url + @destroy_later << FactoryBot.create(:admission_process, + start_date: admission_process.start_date, + end_date: admission_process.end_date, + simple_url: "doutorado" + ) + # Same simple url, different date + @destroy_later << FactoryBot.create(:admission_process, + start_date: admission_process.start_date - 3.months, + end_date: admission_process.end_date - 2.months, + simple_url: "mestrado" + ) + expect(admission_process).to have(0).errors_on :simple_url + end + it "admission process was in the past" do + admission_process.simple_url = "mestrado" + admission_process.start_date = Date.parse("2024/01/01") + admission_process.end_date = Date.parse("2024/02/01") + # Date overlap, different simple url + @destroy_later << FactoryBot.create(:admission_process, + start_date: admission_process.start_date, + end_date: admission_process.end_date, + simple_url: "mestrado" + ) + expect(admission_process).to have(0).errors_on :simple_url + end + + end + context "should have error simple_url_integer when" do + it "it is a number" do + admission_process.start_date = Date.parse("2024/01/01") + admission_process.end_date = Date.today + 1.month + admission_process.simple_url = "1" + expect(admission_process).to have_error(:simple_url_integer).on :simple_url + end + it "it overlaps a date" do + admission_process.simple_url = "mestrado" + admission_process.start_date = Date.parse("2024/01/01") + admission_process.end_date = Date.today + 1.month + @destroy_later << FactoryBot.create(:admission_process, + start_date: admission_process.start_date - 1.month, + end_date: admission_process.end_date - 1.day, + simple_url: "mestrado" + ) + expect(admission_process).to have_error(:simple_url_collides_in_date_range).on :simple_url + end + end + + end + end + describe "Duplication" do + # ToDo: initialize_dup + end + describe "Methods" do + describe "max_edit_date" do + it "should be end_date when edit_date is nil" do + admission_process.edit_date = nil + expect(admission_process.max_edit_date).to eq(admission_process.end_date) + end + it "should be edit_date when edit_date is filled" do + admission_process.edit_date = Date.parse("2024/02/15") + expect(admission_process.max_edit_date).to eq(Date.parse("2024/02/15")) + end + end + describe "has_letters" do + it "should be false when both min_letters and max_letters are nil" do + admission_process.min_letters = nil + admission_process.max_letters = nil + expect(admission_process.has_letters).to eq(false) + end + it "should be true when min_letters is filled" do + admission_process.min_letters = 1 + admission_process.max_letters = nil + expect(admission_process.has_letters).to eq(true) + end + it "should be true when max_letters is greater than 0" do + admission_process.min_letters = nil + admission_process.max_letters = 2 + expect(admission_process.has_letters).to eq(true) + end + it "should be false when max_letters is 0" do + admission_process.min_letters = nil + admission_process.max_letters = 0 + expect(admission_process.has_letters).to eq(false) + end + end + describe "is_open?" do + it "should return false if today is before start date" do + admission_process.start_date = Date.today + 1.day + admission_process.end_date = Date.today + 1.month + expect(admission_process.is_open?).to eq(false) + end + it "should return false if today is after end date" do + admission_process.start_date = Date.today - 1.month + admission_process.end_date = Date.today - 1.day + expect(admission_process.is_open?).to eq(false) + end + it "should return true if today is between start and end date" do + admission_process.start_date = Date.today - 1.month + admission_process.end_date = Date.today + 1.month + expect(admission_process.is_open?).to eq(true) + end + end + describe "is_open_to_edit?" do + it "should return false if today is before start date" do + admission_process.start_date = Date.today + 1.day + admission_process.edit_date = Date.today + 1.month + admission_process.end_date = admission_process.edit_date + expect(admission_process.is_open_to_edit?).to eq(false) + end + it "should return false if today is after edit date" do + admission_process.start_date = Date.today - 1.month + admission_process.edit_date = Date.today - 1.day + admission_process.end_date = admission_process.edit_date + expect(admission_process.is_open_to_edit?).to eq(false) + end + it "should return true if today is between start and edit date" do + admission_process.start_date = Date.today - 1.month + admission_process.edit_date = Date.today + 1.month + admission_process.end_date = admission_process.edit_date + expect(admission_process.is_open_to_edit?).to eq(true) + end + end + describe "year_semester" do + it "should return 'year.semester'" do + admission_process.year = 2024 + admission_process.semester = 1 + expect(admission_process.year_semester).to eq("2024.1") + end + end + describe "title" do + it "should return 'name (year.semester)'" do + admission_process.name = "Mestrado" + admission_process.year = 2024 + admission_process.semester = 1 + expect(admission_process.title).to eq("Mestrado (2024.1)") + end + end + describe "to_label" do + it "should return 'name (year.semester)'" do + admission_process.name = "Mestrado" + admission_process.year = 2024 + admission_process.semester = 1 + expect(admission_process.to_label).to eq("Mestrado (2024.1)") + end + end + # ToDo: admission_applications_count + # ToDo: simple_id + # ToDo: current_phase + # ToDo: check_partial_consolidation_conditions + end +end From 78dc9be33fc601df898b03b8a586e3c703ec08bb Mon Sep 17 00:00:00 2001 From: Joao Felipe Pimentel Date: Sat, 7 Dec 2024 13:47:47 -0300 Subject: [PATCH 3/8] add admission_application and letter_requests validation tests --- app/models/admissions/letter_request.rb | 1 + .../factory_admission_application.rb | 4 + .../admissions/factory_admission_process.rb | 6 + .../admissions/factory_letter_request.rb | 17 +++ .../admissions/admission_application_spec.rb | 143 ++++++++++++++++++ spec/models/admissions/letter_request_spec.rb | 48 ++++++ 6 files changed, 219 insertions(+) create mode 100644 spec/factories/admissions/factory_letter_request.rb create mode 100644 spec/models/admissions/admission_application_spec.rb create mode 100644 spec/models/admissions/letter_request_spec.rb diff --git a/app/models/admissions/letter_request.rb b/app/models/admissions/letter_request.rb index 30209b80..a2d6e2db 100644 --- a/app/models/admissions/letter_request.rb +++ b/app/models/admissions/letter_request.rb @@ -33,6 +33,7 @@ class Admissions::LetterRequest < ActiveRecord::Base after_initialize :initialize_filled_form def initialize_filled_form + return if self.admission_application.blank? self.filled_form ||= Admissions::FilledForm.new( is_filled: false, form_template: self.admission_application.admission_process.letter_template diff --git a/spec/factories/admissions/factory_admission_application.rb b/spec/factories/admissions/factory_admission_application.rb index 3dfe8c72..62a2a97f 100644 --- a/spec/factories/admissions/factory_admission_application.rb +++ b/spec/factories/admissions/factory_admission_application.rb @@ -13,5 +13,9 @@ email { "ana@email.com" } admission_process filled_form + + trait :in_process_with_letters do + admission_process { create(:admission_process, :with_letter_template) } + end end end diff --git a/spec/factories/admissions/factory_admission_process.rb b/spec/factories/admissions/factory_admission_process.rb index 0a03c99e..e86988a7 100644 --- a/spec/factories/admissions/factory_admission_process.rb +++ b/spec/factories/admissions/factory_admission_process.rb @@ -25,5 +25,11 @@ staff_can_edit { true } staff_can_undo { true } require_session { false } + + trait :with_letter_template do + letter_template { create(:form_template, template_type: "Carta de Recomendação") } + min_letters { nil } + max_letters { nil } + end end end diff --git a/spec/factories/admissions/factory_letter_request.rb b/spec/factories/admissions/factory_letter_request.rb new file mode 100644 index 00000000..b96cdc01 --- /dev/null +++ b/spec/factories/admissions/factory_letter_request.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :letter_request, class: Admissions::LetterRequest, aliases: [ + "admissions/letter_request" + ] do + name { "Ana" } + email { "ana@ic.uff.br" } + admission_application { create(:admission_application, :in_process_with_letters) } + filled_form + end +end diff --git a/spec/models/admissions/admission_application_spec.rb b/spec/models/admissions/admission_application_spec.rb new file mode 100644 index 00000000..11172936 --- /dev/null +++ b/spec/models/admissions/admission_application_spec.rb @@ -0,0 +1,143 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionProcess, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:letter_requests).dependent(:delete_all) } + it { should have_many(:evaluations).dependent(:destroy) } + it { should have_many(:results).dependent(:destroy) } + it { should have_many(:rankings).dependent(:destroy) } + it { should have_many(:pendencies).dependent(:destroy) } + + it { should belong_to(:admission_process).required(true) } + it { should belong_to(:filled_form).required(true) } + it { should belong_to(:admission_phase).required(false) } + it { should belong_to(:student).required(false) } + it { should belong_to(:enrollment).required(false) } + + before(:all) do + @admission_process = FactoryBot.create(:admission_process, :with_letter_template) + @filled_form = FactoryBot.create(:filled_form) + @destroy_later = [] + end + after(:all) do + @admission_process.delete + @filled_form.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_application) do + @filled_form.is_filled = true + Admissions::AdmissionApplication.new( + name: "Ana", + email: "ana@email.com", + admission_process: @admission_process, + filled_form: @filled_form + ) + end + subject { admission_application } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:email) } + context "when allow_multiple_applications is false" do + before { @admission_process.allow_multiple_applications = false } + it { should validate_uniqueness_of(:email).scoped_to(:admission_process_id) } + end + #context "when allow_multiple_applications is false" do + # before { @admission_process.allow_multiple_applications = true } + # it { should_not validate_uniqueness_of(:email).scoped_to(:admission_process_id) } + # end + describe "number_of_letters_in_filled_form" do + context "should be valid when" do + it "filled_form is blank" do + admission_application.filled_form = nil + @admission_process.min_letters = 1 + expect(admission_application).not_to have_error(:min_letters).with_parameters(count: 1).on :base + @admission_process.max_letters = 1 + admission_application.letter_requests.build + admission_application.letter_requests.build + expect(admission_application).not_to have_error(:max_letters).with_parameters(count: 1).on :base + end + it "admission_process is blank" do + admission_application.admission_process = nil + @admission_process.min_letters = 1 + expect(admission_application).not_to have_error(:min_letters).with_parameters(count: 1).on :base + @admission_process.max_letters = 1 + admission_application.admission_process = @admission_process + admission_application.letter_requests.build + admission_application.letter_requests.build + admission_application.admission_process = nil + expect(admission_application).not_to have_error(:max_letters).with_parameters(count: 1).on :base + end + it "admission_process has no letters" do + admission_application.admission_process = nil + @admission_process.max_letters = 0 + expect(admission_application).not_to have_error(:min_letters).with_parameters(count: 1).on :base + expect(admission_application).not_to have_error(:max_letters).with_parameters(count: 1).on :base + end + it "filled_form is not filled" do + admission_application.filled_form.is_filled = false + @admission_process.min_letters = 1 + expect(admission_application).not_to have_error(:min_letters).with_parameters(count: 1).on :base + @admission_process.max_letters = 1 + admission_application.letter_requests.build + admission_application.letter_requests.build + expect(admission_application).not_to have_error(:max_letters).with_parameters(count: 1).on :base + end + end + context "should have error min_letters when" do + it "filled_form is filled and min_letters is greater than 0" do + @admission_process.min_letters = 1 + @admission_process.max_letters = nil + expect(admission_application).to have_error(:min_letters).with_parameters(count: 1).on :base + end + end + context "should have error max_letters when" do + it "filled_form is filled and max_letters is greater than 0" do + @admission_process.max_letters = 1 + admission_application.letter_requests.build + admission_application.letter_requests.build + expect(admission_application).to have_error(:max_letters).with_parameters(count: 1).on :base + end + end + end + end + # ToDo: test scopes + # ToDo: test before_save + + + describe "Methods" do + # ToDo: pendency_condition + # ToDo: phase_condition + # ToDo: to_label + # ToDo: requested_letters + # ToDo: filled_letters + # ToDo: missing_letters? + # ToDo: prepare_missing_letters + # ToDo: satisfies_condition + # ToDo: attribute_as_field + # ToDo: fields_hash + # ToDo: consolidate_phase + # ToDo: consolidate_phase! + # ToDo: descriptive_status + # ToDo: candidate_can_edit + # ToDo: students_by_cpf + # ToDo: students_by_email + # ToDo: students + # ToDo: assign_form + # ToDo: update_student + # ToDo: update_enrollment + # ToDo: undo_consolidation + # ToDo: phase_name + # ToDo: identifier + # ToDo: can_edit_itself + # ToDo: ordered_rankings + end +end diff --git a/spec/models/admissions/letter_request_spec.rb b/spec/models/admissions/letter_request_spec.rb new file mode 100644 index 00000000..3511ce92 --- /dev/null +++ b/spec/models/admissions/letter_request_spec.rb @@ -0,0 +1,48 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::LetterRequest, type: :model do + it { should be_able_to_be_destroyed } + + it { should belong_to(:admission_application).required(true) } + it { should belong_to(:filled_form).required(true) } + + before(:all) do + @admission_application = FactoryBot.create(:admission_application, :in_process_with_letters) + @filled_form = FactoryBot.create(:filled_form) + @destroy_later = [] + end + after(:all) do + @admission_application.delete + @filled_form.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:letter_request) do + Admissions::LetterRequest.new( + name: "Ana", + email: "ana@email.com", + admission_application: @admission_application, + filled_form: @filled_form + ) + end + subject { letter_request } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:email) } + end + # ToDo: test before_save + # ToDo: test after_initialize + + describe "Methods" do + # ToDo: status + # ToDo: is_filled + end +end From ca88674a4b7b6f3a5d6ea17b419d96dc3d05c7bb Mon Sep 17 00:00:00 2001 From: Joao Felipe Pimentel Date: Sun, 8 Dec 2024 01:59:07 -0300 Subject: [PATCH 4/8] add validation tests for admission models --- app/models/admissions/admission_committee.rb | 2 +- .../admissions/admission_phase_evaluation.rb | 1 + .../admissions/factory_admission_committee.rb | 14 +++++ .../factory_admission_committee_member.rb | 15 ++++++ .../admissions/factory_admission_pendency.rb | 17 ++++++ .../admissions/factory_admission_phase.rb | 17 +++--- .../factory_admission_phase_committee.rb | 15 ++++++ .../factory_admission_phase_evaluation.rb | 17 ++++++ .../factory_admission_phase_result.rb | 17 ++++++ .../factory_admission_process_phase.rb | 15 ++++++ .../admission_committee_member_spec.rb | 43 +++++++++++++++ .../admissions/admission_committee_spec.rb | 40 ++++++++++++++ .../admissions/admission_pendency_spec.rb | 52 +++++++++++++++++++ .../admission_phase_committee_spec.rb | 41 +++++++++++++++ .../admission_phase_evaluation_spec.rb | 52 +++++++++++++++++++ .../admissions/admission_phase_result_spec.rb | 49 +++++++++++++++++ .../admission_process_phase_spec.rb | 48 +++++++++++++++++ 17 files changed, 448 insertions(+), 7 deletions(-) create mode 100644 spec/factories/admissions/factory_admission_committee.rb create mode 100644 spec/factories/admissions/factory_admission_committee_member.rb create mode 100644 spec/factories/admissions/factory_admission_pendency.rb create mode 100644 spec/factories/admissions/factory_admission_phase_committee.rb create mode 100644 spec/factories/admissions/factory_admission_phase_evaluation.rb create mode 100644 spec/factories/admissions/factory_admission_phase_result.rb create mode 100644 spec/factories/admissions/factory_admission_process_phase.rb create mode 100644 spec/models/admissions/admission_committee_member_spec.rb create mode 100644 spec/models/admissions/admission_committee_spec.rb create mode 100644 spec/models/admissions/admission_pendency_spec.rb create mode 100644 spec/models/admissions/admission_phase_committee_spec.rb create mode 100644 spec/models/admissions/admission_phase_evaluation_spec.rb create mode 100644 spec/models/admissions/admission_phase_result_spec.rb create mode 100644 spec/models/admissions/admission_process_phase_spec.rb diff --git a/app/models/admissions/admission_committee.rb b/app/models/admissions/admission_committee.rb index 336a851c..d0e9cecd 100644 --- a/app/models/admissions/admission_committee.rb +++ b/app/models/admissions/admission_committee.rb @@ -15,7 +15,7 @@ class Admissions::AdmissionCommittee < ActiveRecord::Base has_many :admission_phases, through: :admission_phase_committees, class_name: "Admissions::AdmissionPhase" - belongs_to :form_condition, optional:true, + belongs_to :form_condition, optional: true, class_name: "Admissions::FormCondition" validates :name, presence: true diff --git a/app/models/admissions/admission_phase_evaluation.rb b/app/models/admissions/admission_phase_evaluation.rb index 59bed7a3..68d64079 100644 --- a/app/models/admissions/admission_phase_evaluation.rb +++ b/app/models/admissions/admission_phase_evaluation.rb @@ -23,6 +23,7 @@ class Admissions::AdmissionPhaseEvaluation < ActiveRecord::Base after_initialize :initialize_filled_form def initialize_filled_form + return if self.admission_phase.blank? self.filled_form ||= Admissions::FilledForm.new( is_filled: false, form_template: self.admission_phase.member_form diff --git a/spec/factories/admissions/factory_admission_committee.rb b/spec/factories/admissions/factory_admission_committee.rb new file mode 100644 index 00000000..e9f8c942 --- /dev/null +++ b/spec/factories/admissions/factory_admission_committee.rb @@ -0,0 +1,14 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_committee, class: Admissions::AdmissionCommittee, aliases: [ + "admissions/admission_committee" + ] do + name { "Comitê" } + end +end diff --git a/spec/factories/admissions/factory_admission_committee_member.rb b/spec/factories/admissions/factory_admission_committee_member.rb new file mode 100644 index 00000000..39be7f8c --- /dev/null +++ b/spec/factories/admissions/factory_admission_committee_member.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_committee_member, class: Admissions::AdmissionCommitteeMember, aliases: [ + "admissions/admission_committee_member" + ] do + admission_committee + user + end +end diff --git a/spec/factories/admissions/factory_admission_pendency.rb b/spec/factories/admissions/factory_admission_pendency.rb new file mode 100644 index 00000000..24e8313e --- /dev/null +++ b/spec/factories/admissions/factory_admission_pendency.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_pendency, class: Admissions::AdmissionPendency, aliases: [ + "admissions/admission_pendency" + ] do + admission_phase + admission_application + mode { Admissions::AdmissionPendency::SHARED } + status { Admissions::AdmissionPendency::PENDENT } + end +end diff --git a/spec/factories/admissions/factory_admission_phase.rb b/spec/factories/admissions/factory_admission_phase.rb index 9103e339..140022d9 100644 --- a/spec/factories/admissions/factory_admission_phase.rb +++ b/spec/factories/admissions/factory_admission_phase.rb @@ -9,16 +9,21 @@ factory :admission_phase, class: Admissions::AdmissionPhase, aliases: [ "admissions/admission_phase" ] do - #association :approval_condition, factory: form_condition - #association :keep_in_phase_condition, factory: form_condition - #association :member_form, factory: form_template - #association :shared_form, factory: form_template - #association :consolidation_form, factory: form_template - #association :candidate_form, factory: form_template + # association :approval_condition, factory: form_condition + # association :keep_in_phase_condition, factory: form_condition + # association :consolidation_form, factory: form_template + # association :candidate_form, factory: form_template name { "Fase 1" } can_edit_candidate { false } candidate_can_see_member { false } candidate_can_see_shared { false } candidate_can_see_consolidation { false } + + trait :with_member_form do + member_form { create(:form_template) } + end + trait :with_shared_form do + shared_form { create(:form_template) } + end end end diff --git a/spec/factories/admissions/factory_admission_phase_committee.rb b/spec/factories/admissions/factory_admission_phase_committee.rb new file mode 100644 index 00000000..b02e33bd --- /dev/null +++ b/spec/factories/admissions/factory_admission_phase_committee.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_phase_committee, class: Admissions::AdmissionPhaseCommittee, aliases: [ + "admissions/admission_phase_committee" + ] do + admission_phase + admission_committee + end +end diff --git a/spec/factories/admissions/factory_admission_phase_evaluation.rb b/spec/factories/admissions/factory_admission_phase_evaluation.rb new file mode 100644 index 00000000..000a0e9e --- /dev/null +++ b/spec/factories/admissions/factory_admission_phase_evaluation.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_phase_evaluation, class: Admissions::AdmissionPhaseEvaluation, aliases: [ + "admissions/admission_phase_evaluation" + ] do + admission_phase { create(:admission_phase, :with_member_form) } + user + admission_application + filled_form + end +end diff --git a/spec/factories/admissions/factory_admission_phase_result.rb b/spec/factories/admissions/factory_admission_phase_result.rb new file mode 100644 index 00000000..d4f92f25 --- /dev/null +++ b/spec/factories/admissions/factory_admission_phase_result.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_phase_result, class: Admissions::AdmissionPhaseResult, aliases: [ + "admissions/admission_phase_result" + ] do + admission_phase { create(:admission_phase, :with_shared_form) } + admission_application + filled_form + mode { Admissions::AdmissionPhaseResult::SHARED } + end +end diff --git a/spec/factories/admissions/factory_admission_process_phase.rb b/spec/factories/admissions/factory_admission_process_phase.rb new file mode 100644 index 00000000..a9b2589c --- /dev/null +++ b/spec/factories/admissions/factory_admission_process_phase.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_process_phase, class: Admissions::AdmissionProcessPhase, aliases: [ + "admissions/admission_process_phase" + ] do + admission_process + admission_phase + end +end diff --git a/spec/models/admissions/admission_committee_member_spec.rb b/spec/models/admissions/admission_committee_member_spec.rb new file mode 100644 index 00000000..c36062d5 --- /dev/null +++ b/spec/models/admissions/admission_committee_member_spec.rb @@ -0,0 +1,43 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionCommitteeMember, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_committee).required(true) } + it { should belong_to(:user).required(true) } + + before(:all) do + @admission_committee = FactoryBot.create(:admission_committee) + @role = FactoryBot.create(:role_professor) + @user = FactoryBot.create(:user, role: @role) + @destroy_later = [] + end + after(:all) do + @admission_committee.delete + @user.delete + @role.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_committee_member) do + Admissions::AdmissionCommitteeMember.new( + admission_committee: @admission_committee, + user: @user + ) + end + subject { admission_committee_member } + describe "Validations" do + it { should be_valid } + end + # ToDo: test after_commit + + describe "Methods" do + # ToDo: to_label + end +end diff --git a/spec/models/admissions/admission_committee_spec.rb b/spec/models/admissions/admission_committee_spec.rb new file mode 100644 index 00000000..d03d7b12 --- /dev/null +++ b/spec/models/admissions/admission_committee_spec.rb @@ -0,0 +1,40 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionCommittee, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:members).dependent(:destroy) } + it { should have_many(:users).through(:members) } + it { should have_many(:admission_phase_committees).dependent(:destroy) } + it { should have_many(:admission_phases).through(:admission_phase_committees) } + + it { should belong_to(:form_condition).required(false) } + + before(:all) do + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_committee) do + Admissions::AdmissionCommittee.new( + name: "Comitê", + ) + end + subject { admission_committee } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + end + # ToDo: test after_commit + + describe "Methods" do + # ToDo: to_label + # ToDo: initialize_dup + end +end diff --git a/spec/models/admissions/admission_pendency_spec.rb b/spec/models/admissions/admission_pendency_spec.rb new file mode 100644 index 00000000..d57cd9dd --- /dev/null +++ b/spec/models/admissions/admission_pendency_spec.rb @@ -0,0 +1,52 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionPendency, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_phase).required(true) } + it { should belong_to(:admission_application).required(true) } + it { should belong_to(:user).required(false) } + + before(:all) do + @admission_phase = FactoryBot.create(:admission_phase) + @admission_application = FactoryBot.create(:admission_application) + @destroy_later = [] + end + after(:all) do + @admission_phase.delete + @admission_application.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_pendency) do + Admissions::AdmissionPendency.new( + admission_phase: @admission_phase, + admission_application: @admission_application, + mode: Admissions::AdmissionPendency::SHARED, + status: Admissions::AdmissionPendency::PENDENT, + ) + end + subject { admission_pendency } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:mode) } + it { should validate_inclusion_of(:mode).in_array(Admissions::AdmissionPendency::MODES) } + it { should validate_presence_of(:status) } + it { should validate_inclusion_of(:status).in_array(Admissions::AdmissionPendency::STATUSES) } + it { should validate_uniqueness_of(:admission_phase_id).scoped_to([:admission_application_id, :user_id, :mode]) } + end + # ToDo: test scopes + + describe "Methods" do + # ToDo: status_value + # ToDo: candidate_pendencies + # ToDo: member_pendencies + # ToDo: shared_pendencies + end +end diff --git a/spec/models/admissions/admission_phase_committee_spec.rb b/spec/models/admissions/admission_phase_committee_spec.rb new file mode 100644 index 00000000..96dda98e --- /dev/null +++ b/spec/models/admissions/admission_phase_committee_spec.rb @@ -0,0 +1,41 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionPhaseCommittee, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_phase).required(true) } + it { should belong_to(:admission_committee).required(true) } + + before(:all) do + @destroy_later = [] + @admission_phase = FactoryBot.create(:admission_phase) + @admission_committee = FactoryBot.create(:admission_committee) + end + after(:all) do + @admission_phase.delete + @admission_committee.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_phase_committee) do + Admissions::AdmissionPhaseCommittee.new( + admission_phase: @admission_phase, + admission_committee: @admission_committee + ) + end + subject { admission_phase_committee } + describe "Validations" do + it { should be_valid } + end + # ToDo: test after_commit + + describe "Methods" do + # ToDo: to_label + end +end diff --git a/spec/models/admissions/admission_phase_evaluation_spec.rb b/spec/models/admissions/admission_phase_evaluation_spec.rb new file mode 100644 index 00000000..0bc26025 --- /dev/null +++ b/spec/models/admissions/admission_phase_evaluation_spec.rb @@ -0,0 +1,52 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionPhaseEvaluation, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_phase).required(true) } + it { should belong_to(:user).required(true) } + it { should belong_to(:admission_application).required(true) } + it { should belong_to(:filled_form).required(true) } + + before(:all) do + @destroy_later = [] + @admission_phase = FactoryBot.create(:admission_phase, :with_member_form) + @role = FactoryBot.create(:role_professor) + @user = FactoryBot.create(:user, role: @role) + @admission_application = FactoryBot.create(:admission_application) + @filled_form = FactoryBot.create(:filled_form) + end + after(:all) do + @admission_phase.delete + @user.delete + @role.delete + @admission_application.delete + @filled_form.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_phase_evaluation) do + Admissions::AdmissionPhaseEvaluation.new( + admission_phase: @admission_phase, + user: @user, + admission_application: @admission_application, + filled_form: @filled_form + ) + end + subject { admission_phase_evaluation } + describe "Validations" do + it { should be_valid } + it { should validate_uniqueness_of(:admission_phase_id).scoped_to([:admission_application_id, :user_id]) } + end + # ToDo: test after_initialize + + describe "Methods" do + # ToDo: to_label + end +end diff --git a/spec/models/admissions/admission_phase_result_spec.rb b/spec/models/admissions/admission_phase_result_spec.rb new file mode 100644 index 00000000..647f05cc --- /dev/null +++ b/spec/models/admissions/admission_phase_result_spec.rb @@ -0,0 +1,49 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionPhaseResult, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_phase).required(true) } + it { should belong_to(:admission_application).required(true) } + it { should belong_to(:filled_form).required(true) } + + before(:all) do + @destroy_later = [] + @admission_phase = FactoryBot.create(:admission_phase, :with_shared_form) + @admission_application = FactoryBot.create(:admission_application) + @filled_form = FactoryBot.create(:filled_form) + end + after(:all) do + @admission_phase.delete + @admission_application.delete + @filled_form.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_phase_result) do + Admissions::AdmissionPhaseResult.new( + admission_phase: @admission_phase, + admission_application: @admission_application, + filled_form: @filled_form, + mode: Admissions::AdmissionPhaseResult::SHARED + ) + end + subject { admission_phase_result } + describe "Validations" do + it { should be_valid } + it { should validate_uniqueness_of(:admission_phase_id).scoped_to([:admission_application_id, :mode]) } + it { should validate_presence_of(:mode) } + it { should validate_inclusion_of(:mode).in_array(Admissions::AdmissionPhaseResult::RESULT_MODES) } + end + # ToDo: test after_initialize + + describe "Methods" do + # ToDo: to_label + end +end diff --git a/spec/models/admissions/admission_process_phase_spec.rb b/spec/models/admissions/admission_process_phase_spec.rb new file mode 100644 index 00000000..263fad05 --- /dev/null +++ b/spec/models/admissions/admission_process_phase_spec.rb @@ -0,0 +1,48 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionProcessPhase, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_process).required(true) } + it { should belong_to(:admission_phase).required(true) } + + before(:all) do + @destroy_later = [] + @admission_process = FactoryBot.create(:admission_process) + @admission_phase = FactoryBot.create(:admission_phase) + end + after(:all) do + @admission_process.delete + @admission_phase.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_process_phase) do + Admissions::AdmissionProcessPhase.new( + admission_process: @admission_process, + admission_phase: @admission_phase + ) + end + subject { admission_process_phase } + describe "Validations" do + it { should be_valid } + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + @admission_process.name = "Processo" + @admission_process.year = 2024 + @admission_process.semester = 2 + @admission_phase.name = "Fase" + expect(admission_process_phase.to_label).to eq("Processo (2024.2) - Fase") + end + end + end +end From 4e9c3d1d7a8697591b8d023b0c6a35938d14ac8b Mon Sep 17 00:00:00 2001 From: Joao Felipe Pimentel Date: Sun, 8 Dec 2024 21:40:25 -0300 Subject: [PATCH 5/8] add remaining validation tests for admissions --- .../admissions/admission_process_ranking.rb | 1 + .../admissions/admission_ranking_result.rb | 1 + .../factory_admission_process_ranking.rb | 15 +++ .../factory_admission_ranking_result.rb | 16 ++++ .../factory_admission_report_column.rb | 22 +++++ .../factory_admission_report_config.rb | 15 +++ .../factory_admission_report_group.rb | 17 ++++ .../admissions/factory_ranking_column.rb | 25 +++++ .../admissions/factory_ranking_config.rb | 32 +++++++ .../admissions/factory_ranking_group.rb | 15 +++ .../admissions/factory_ranking_machine.rb | 14 +++ .../admissions/factory_ranking_process.rb | 15 +++ .../admission_process_ranking_spec.rb | 73 +++++++++++++++ .../admission_ranking_result_spec.rb | 55 +++++++++++ .../admission_report_column_spec.rb | 56 +++++++++++ .../admission_report_config_spec.rb | 51 ++++++++++ .../admissions/admission_report_group_spec.rb | 53 +++++++++++ spec/models/admissions/ranking_column_spec.rb | 92 +++++++++++++++++++ spec/models/admissions/ranking_config_spec.rb | 78 ++++++++++++++++ spec/models/admissions/ranking_group_spec.rb | 50 ++++++++++ .../models/admissions/ranking_machine_spec.rb | 40 ++++++++ .../models/admissions/ranking_process_spec.rb | 49 ++++++++++ 22 files changed, 785 insertions(+) create mode 100644 spec/factories/admissions/factory_admission_process_ranking.rb create mode 100644 spec/factories/admissions/factory_admission_ranking_result.rb create mode 100644 spec/factories/admissions/factory_admission_report_column.rb create mode 100644 spec/factories/admissions/factory_admission_report_config.rb create mode 100644 spec/factories/admissions/factory_admission_report_group.rb create mode 100644 spec/factories/admissions/factory_ranking_column.rb create mode 100644 spec/factories/admissions/factory_ranking_config.rb create mode 100644 spec/factories/admissions/factory_ranking_group.rb create mode 100644 spec/factories/admissions/factory_ranking_machine.rb create mode 100644 spec/factories/admissions/factory_ranking_process.rb create mode 100644 spec/models/admissions/admission_process_ranking_spec.rb create mode 100644 spec/models/admissions/admission_ranking_result_spec.rb create mode 100644 spec/models/admissions/admission_report_column_spec.rb create mode 100644 spec/models/admissions/admission_report_config_spec.rb create mode 100644 spec/models/admissions/admission_report_group_spec.rb create mode 100644 spec/models/admissions/ranking_column_spec.rb create mode 100644 spec/models/admissions/ranking_config_spec.rb create mode 100644 spec/models/admissions/ranking_group_spec.rb create mode 100644 spec/models/admissions/ranking_machine_spec.rb create mode 100644 spec/models/admissions/ranking_process_spec.rb diff --git a/app/models/admissions/admission_process_ranking.rb b/app/models/admissions/admission_process_ranking.rb index b726ace0..b8e46319 100644 --- a/app/models/admissions/admission_process_ranking.rb +++ b/app/models/admissions/admission_process_ranking.rb @@ -17,6 +17,7 @@ class Admissions::AdmissionProcessRanking < ActiveRecord::Base def that_phase_is_part_of_the_process return if self.admission_phase.blank? + return if self.admission_process.blank? self.admission_process.phases.each do |p| return if p.admission_phase == self.admission_phase end diff --git a/app/models/admissions/admission_ranking_result.rb b/app/models/admissions/admission_ranking_result.rb index c11ff481..9d4c7365 100644 --- a/app/models/admissions/admission_ranking_result.rb +++ b/app/models/admissions/admission_ranking_result.rb @@ -20,6 +20,7 @@ class Admissions::AdmissionRankingResult < ActiveRecord::Base after_initialize :initialize_filled_form def initialize_filled_form + return if self.ranking_config.nil? self.filled_form ||= Admissions::FilledForm.new( is_filled: false, form_template: self.ranking_config.form_template diff --git a/spec/factories/admissions/factory_admission_process_ranking.rb b/spec/factories/admissions/factory_admission_process_ranking.rb new file mode 100644 index 00000000..b29061e1 --- /dev/null +++ b/spec/factories/admissions/factory_admission_process_ranking.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_process_ranking, class: Admissions::AdmissionProcessRanking, aliases: [ + "admissions/admission_process_ranking" + ] do + ranking_config + admission_process + end +end diff --git a/spec/factories/admissions/factory_admission_ranking_result.rb b/spec/factories/admissions/factory_admission_ranking_result.rb new file mode 100644 index 00000000..029897e1 --- /dev/null +++ b/spec/factories/admissions/factory_admission_ranking_result.rb @@ -0,0 +1,16 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_ranking_result, class: Admissions::AdmissionRankingResult, aliases: [ + "admissions/admission_ranking_result" + ] do + ranking_config + admission_application + filled_form + end +end diff --git a/spec/factories/admissions/factory_admission_report_column.rb b/spec/factories/admissions/factory_admission_report_column.rb new file mode 100644 index 00000000..b54d30cc --- /dev/null +++ b/spec/factories/admissions/factory_admission_report_column.rb @@ -0,0 +1,22 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_report_column, class: Admissions::AdmissionReportColumn, aliases: [ + "admissions/admission_report_column" + ] do + admission_report_group + name { "coluna" } + before(:create) do |column| + if !Admissions::FormField.field_name_exists?( + column.name, in_main: true, in_letter: true + ) + FactoryBot.create(:form_field, name: column.name) + end + end + end +end diff --git a/spec/factories/admissions/factory_admission_report_config.rb b/spec/factories/admissions/factory_admission_report_config.rb new file mode 100644 index 00000000..e0b4f4c3 --- /dev/null +++ b/spec/factories/admissions/factory_admission_report_config.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_report_config, class: Admissions::AdmissionReportConfig, aliases: [ + "admissions/admission_report_config" + ] do + name { "Configuração de Relatório" } + group_column_tabular { Admissions::AdmissionReportConfig::COLUMN } + end +end diff --git a/spec/factories/admissions/factory_admission_report_group.rb b/spec/factories/admissions/factory_admission_report_group.rb new file mode 100644 index 00000000..ede0a437 --- /dev/null +++ b/spec/factories/admissions/factory_admission_report_group.rb @@ -0,0 +1,17 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :admission_report_group, class: Admissions::AdmissionReportGroup, aliases: [ + "admissions/admission_report_group" + ] do + admission_report_config + mode { Admissions::AdmissionReportGroup::MAIN } + pdf_format { Admissions::AdmissionReportGroup::LIST } + operation { Admissions::AdmissionReportGroup::INCLUDE } + end +end diff --git a/spec/factories/admissions/factory_ranking_column.rb b/spec/factories/admissions/factory_ranking_column.rb new file mode 100644 index 00000000..1ce017f1 --- /dev/null +++ b/spec/factories/admissions/factory_ranking_column.rb @@ -0,0 +1,25 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :ranking_column, class: Admissions::RankingColumn, aliases: [ + "admissions/ranking_column" + ] do + name { "Coluna" } + order { Admissions::RankingColumn::ASC } + + after(:build) do |column, factory| + if !Admissions::FormField.field_name_exists?(column.name) + FactoryBot.create(:form_field, name: column.name) + end + if column.ranking_config.blank? && column.admission_report_config.blank? + column.ranking_config = FactoryBot.build(:ranking_config, default_column: nil) + column.ranking_config.ranking_columns << column + end + end + end +end diff --git a/spec/factories/admissions/factory_ranking_config.rb b/spec/factories/admissions/factory_ranking_config.rb new file mode 100644 index 00000000..3c650b1e --- /dev/null +++ b/spec/factories/admissions/factory_ranking_config.rb @@ -0,0 +1,32 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :ranking_config, class: Admissions::RankingConfig, aliases: [ + "admissions/ranking_config" + ] do + transient do + default_column { "Coluna" } + default_machine { create(:ranking_machine) } + end + name { "Configuração de Ranking" } + behavior_on_invalid_condition { Admissions::RankingConfig::IGNORE_CONDITION } + behavior_on_invalid_ranking { Admissions::RankingConfig::IGNORE_RANKING } + + after(:build) do |config, factory| + if factory.default_column.present? + if !Admissions::FormField.field_name_exists?(factory.default_column) + FactoryBot.create(:form_field, name: factory.default_column) + end + config.ranking_columns.build(name: factory.default_column, order: Admissions::RankingColumn::ASC) + end + if factory.default_machine.present? + config.ranking_processes.build(ranking_machine: factory.default_machine) + end + end + end +end diff --git a/spec/factories/admissions/factory_ranking_group.rb b/spec/factories/admissions/factory_ranking_group.rb new file mode 100644 index 00000000..04457956 --- /dev/null +++ b/spec/factories/admissions/factory_ranking_group.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :ranking_group, class: Admissions::RankingGroup, aliases: [ + "admissions/ranking_group" + ] do + ranking_config + name { "AC"} + end +end diff --git a/spec/factories/admissions/factory_ranking_machine.rb b/spec/factories/admissions/factory_ranking_machine.rb new file mode 100644 index 00000000..b9c0b28f --- /dev/null +++ b/spec/factories/admissions/factory_ranking_machine.rb @@ -0,0 +1,14 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :ranking_machine, class: Admissions::RankingMachine, aliases: [ + "admissions/ranking_machine" + ] do + name { "Máquina de Ranking" } + end +end diff --git a/spec/factories/admissions/factory_ranking_process.rb b/spec/factories/admissions/factory_ranking_process.rb new file mode 100644 index 00000000..57efb928 --- /dev/null +++ b/spec/factories/admissions/factory_ranking_process.rb @@ -0,0 +1,15 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# Read about factories at https://github.com/thoughtbot/factory_bot + +# frozen_string_literal: true + +FactoryBot.define do + factory :ranking_process, class: Admissions::RankingProcess, aliases: [ + "admissions/ranking_process" + ] do + ranking_config + ranking_machine + end +end diff --git a/spec/models/admissions/admission_process_ranking_spec.rb b/spec/models/admissions/admission_process_ranking_spec.rb new file mode 100644 index 00000000..d3e98f1b --- /dev/null +++ b/spec/models/admissions/admission_process_ranking_spec.rb @@ -0,0 +1,73 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionProcessRanking, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:ranking_config).required(true) } + it { should belong_to(:admission_process).required(true) } + it { should belong_to(:admission_phase).required(false) } + + before(:all) do + @ranking_config = FactoryBot.create(:ranking_config) + @admission_process = FactoryBot.create(:admission_process) + @admission_phase = FactoryBot.create(:admission_phase) + @admission_process_phase = FactoryBot.create(:admission_process_phase, admission_process: @admission_process, admission_phase: @admission_phase) + end + after(:all) do + @admission_process_phase.delete + @admission_process.delete + @admission_phase.delete + @ranking_config.delete + end + let(:admission_process_ranking) do + Admissions::AdmissionProcessRanking.new( + ranking_config: @ranking_config, + admission_process: @admission_process, + admission_phase: @admission_phase + ) + end + subject { admission_process_ranking } + describe "Validations" do + it { should be_valid } + context "that_phase_is_part_of_the_process" do + it "should be valid if phase is part of the process" do + admission_process_ranking.admission_phase = @admission_phase + expect(admission_process_ranking).to be_valid + end + it "should have error if phase is not part of the process" do + admission_process_ranking.admission_phase = FactoryBot.create(:admission_phase) + expect(admission_process_ranking).to have_error(:phase_not_in_process).on(:admission_phase) + admission_process_ranking.admission_phase = @admission_phase + end + it "should be valid if phase is nil" do + admission_process_ranking.admission_phase = nil + expect(admission_process_ranking).not_to have_error(:phase_not_in_process).on(:admission_phase) + end + it "should be valid if process is nil" do + admission_process_ranking.admission_process = nil + expect(admission_process_ranking).not_to have_error(:phase_not_in_process).on(:admission_phase) + end + end + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + @ranking_config.name = "Config" + @admission_process.name = "Processo" + @admission_process.year = 2024 + @admission_process.semester = 2 + expect(admission_process_ranking.to_label).to eq("Config - Processo (2024.2)") + end + end + # ToDo: generate_ranking + # ToDo: set_candidate_position + # ToDo: filter_sort_candidates + # ToDo: compare_candidates + end + +end diff --git a/spec/models/admissions/admission_ranking_result_spec.rb b/spec/models/admissions/admission_ranking_result_spec.rb new file mode 100644 index 00000000..824254b9 --- /dev/null +++ b/spec/models/admissions/admission_ranking_result_spec.rb @@ -0,0 +1,55 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionRankingResult, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:ranking_config).required(true) } + it { should belong_to(:admission_application).required(true) } + it { should belong_to(:filled_form).required(true) } + + before(:all) do + @destroy_later = [] + @ranking_config = FactoryBot.create(:ranking_config) + @admission_application = FactoryBot.create(:admission_application) + @filled_form = FactoryBot.create(:filled_form) + end + after(:all) do + @ranking_config.delete + @admission_application.delete + @filled_form.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_ranking_result) do + Admissions::AdmissionRankingResult.new( + ranking_config: @ranking_config, + admission_application: @admission_application, + filled_form: @filled_form + ) + end + subject { admission_ranking_result } + describe "Validations" do + it { should be_valid } + it { should validate_uniqueness_of(:ranking_config_id).scoped_to(:admission_application_id) } + end + # ToDo: after_initialize + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + @ranking_config.name = "Config" + @admission_application.name = "Ana" + @admission_application.token = "123" + expect(admission_ranking_result.to_label).to eq("Config / Ana - 123") + end + end + # ToDo: filled_position + # ToDo: filled_machine + end +end diff --git a/spec/models/admissions/admission_report_column_spec.rb b/spec/models/admissions/admission_report_column_spec.rb new file mode 100644 index 00000000..dc24bcd8 --- /dev/null +++ b/spec/models/admissions/admission_report_column_spec.rb @@ -0,0 +1,56 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionReportColumn, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:admission_report_group).required(true) } + + before(:all) do + @destroy_later = [] + @admission_report_group = FactoryBot.create(:admission_report_group) + @admissions_form_field = FactoryBot.create(:form_field, name: "coluna") + end + after(:all) do + @admission_report_group.delete + @admissions_form_field.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_report_column) do + Admissions::AdmissionReportColumn.new( + admission_report_group: @admission_report_group, + name: "coluna" + ) + end + subject { admission_report_column } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + describe "that_field_name_exists" do + it "should be valid if field exists" do + admission_report_column.name = "coluna" + expect(admission_report_column).to be_valid + end + it "should have error if field does not exist" do + admission_report_column.name = "c" + expect(admission_report_column).to have_error(:field_not_found).on(:base).with_parameters(field: "c") + admission_report_column.name = "coluna" + end + end + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + admission_report_column.name = "Coluna" + expect(admission_report_column.to_label).to eq("Coluna") + end + end + end +end diff --git a/spec/models/admissions/admission_report_config_spec.rb b/spec/models/admissions/admission_report_config_spec.rb new file mode 100644 index 00000000..88c066cf --- /dev/null +++ b/spec/models/admissions/admission_report_config_spec.rb @@ -0,0 +1,51 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionReportConfig, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:groups).dependent(:destroy) } + it { should have_many(:ranking_columns).dependent(:destroy) } + it { should belong_to(:form_template).required(false) } + it { should belong_to(:form_condition).required(false) } + + before(:all) do + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_report_config) do + Admissions::AdmissionReportConfig.new( + name: "Configuração de Relatório", + group_column_tabular: Admissions::AdmissionReportConfig::COLUMN + ) + end + subject { admission_report_config } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:group_column_tabular) } + it { should validate_inclusion_of(:group_column_tabular).in_array(Admissions::AdmissionReportConfig::GROUP_COLUMNS) } + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + admission_report_config.name = "Configuração de Relatório" + expect(admission_report_config.to_label).to eq("Configuração de Relatório") + end + end + # ToDo: init_default + # ToDo: init_simple + # ToDo: prepare_table + # ToDo: prepare_row + # ToDo: prepare_excel_row + # ToDo: prepare_html_row + # ToDo: group_column + end +end diff --git a/spec/models/admissions/admission_report_group_spec.rb b/spec/models/admissions/admission_report_group_spec.rb new file mode 100644 index 00000000..286e7972 --- /dev/null +++ b/spec/models/admissions/admission_report_group_spec.rb @@ -0,0 +1,53 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::AdmissionReportGroup, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:columns).dependent(:destroy) } + it { should belong_to(:admission_report_config).required(true) } + + before(:all) do + @destroy_later = [] + @admission_report_config = FactoryBot.create(:admission_report_config) + end + after(:all) do + @admission_report_config.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:admission_report_group) do + Admissions::AdmissionReportGroup.new( + admission_report_config: @admission_report_config, + mode: Admissions::AdmissionReportGroup::MAIN, + pdf_format: Admissions::AdmissionReportGroup::LIST, + operation: Admissions::AdmissionReportGroup::INCLUDE + ) + end + subject { admission_report_group } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:mode) } + it { should validate_inclusion_of(:mode).in_array(Admissions::AdmissionReportGroup::MODES) } + it { should validate_presence_of(:pdf_format) } + it { should validate_inclusion_of(:pdf_format).in_array(Admissions::AdmissionReportGroup::PDF_FORMATS) } + it { should validate_presence_of(:operation) } + it { should validate_inclusion_of(:operation).in_array(Admissions::AdmissionReportGroup::OPERATIONS) } + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + admission_report_group.mode = Admissions::AdmissionReportGroup::MAIN + admission_report_group.operation = Admissions::AdmissionReportGroup::INCLUDE + expect(admission_report_group.to_label).to eq("#{Admissions::AdmissionReportGroup::MAIN} #{Admissions::AdmissionReportGroup::INCLUDE}") + end + end + # ToDo: tabular_config + end +end diff --git a/spec/models/admissions/ranking_column_spec.rb b/spec/models/admissions/ranking_column_spec.rb new file mode 100644 index 00000000..d339d741 --- /dev/null +++ b/spec/models/admissions/ranking_column_spec.rb @@ -0,0 +1,92 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::RankingColumn, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:ranking_config).required(false) } + it { should belong_to(:admission_report_config).required(false) } + + before(:all) do + @destroy_later = [] + @form_field = FactoryBot.create(:form_field, name: "Coluna") + @ranking_config = FactoryBot.create(:ranking_config) + end + after(:all) do + @form_field.delete + @ranking_config.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:ranking_column) do + Admissions::RankingColumn.new( + ranking_config: @ranking_config, + name: "Coluna", + order: Admissions::RankingColumn::ASC + ) + end + subject { ranking_column } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it { should validate_presence_of(:order) } + it { should validate_inclusion_of(:order).in_array(Admissions::RankingColumn::ORDERS) } + describe "that_field_name_exists" do + it "should be valid if field exists" do + ranking_column.name = "Coluna" + expect(ranking_column).to be_valid + end + it "should have error if field does not exist" do + ranking_column.name = "C" + expect(ranking_column).to have_error(:field_not_found).on(:base).with_parameters(field: "C") + ranking_column.name = "Coluna" + end + it "should be valid if name is blank" do + ranking_column.name = "" + expect(ranking_column).not_to have_error(:field_not_found).on(:base).with_parameters(field: "") + end + end + describe "that_it_either_has_ranking_config_or_admission_report_config" do + it "should be valid if it has ranking_config" do + ranking_column.ranking_config = @ranking_config + ranking_column.admission_report_config = nil + expect(ranking_column).to be_valid + end + it "should be valid if it has admission_report_config" do + ranking_column.ranking_config = nil + ranking_column.admission_report_config = FactoryBot.create(:admission_report_config) + expect(ranking_column).to be_valid + end + it "should not be valid if it has neither ranking_config nor admission_report_config" do + ranking_column.ranking_config = nil + ranking_column.admission_report_config = nil + expect(ranking_column).not_to be_valid + expect(ranking_column).to have_error(:at_least_one_relationship).on :base + end + it "should not be valid if it has both ranking_config and admission_report_config" do + ranking_column.ranking_config = @ranking_config + @destroy_later << ranking_column.admission_report_config = FactoryBot.create(:admission_report_config) + expect(ranking_column).not_to be_valid + expect(ranking_column).to have_error(:at_least_one_relationship).on :base + end + end + end + # ToDo: after_initialize + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + ranking_column.name = "Coluna" + ranking_column.order = Admissions::RankingColumn::ASC + expect(ranking_column.to_label).to eq("Coluna #{Admissions::RankingColumn::ASC}") + end + end + # ToDo: compare + # ToDo: convert + end +end diff --git a/spec/models/admissions/ranking_config_spec.rb b/spec/models/admissions/ranking_config_spec.rb new file mode 100644 index 00000000..68b9301b --- /dev/null +++ b/spec/models/admissions/ranking_config_spec.rb @@ -0,0 +1,78 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::RankingConfig, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:ranking_columns).dependent(:destroy) } + it { should have_many(:ranking_groups).dependent(:destroy) } + it { should have_many(:ranking_processes).dependent(:destroy) } + it { should have_many(:admission_process_rankings).dependent(:restrict_with_exception) } + it { should have_many(:admission_ranking_results).dependent(:destroy) } + it { should belong_to(:form_template).required(false) } + it { should belong_to(:position_field).required(false) } + it { should belong_to(:machine_field).required(false) } + it { should belong_to(:form_condition).required(false) } + + before(:all) do + @destroy_later = [] + @form_field = FactoryBot.create(:form_field, name: "Coluna") + @ranking_machine = FactoryBot.create(:ranking_machine) + end + after(:all) do + @form_field.delete + @ranking_machine.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:ranking_config) do + ranking_config = Admissions::RankingConfig.new( + name: "Configuração de Ranking", + behavior_on_invalid_condition: Admissions::RankingConfig::IGNORE_CONDITION, + behavior_on_invalid_ranking: Admissions::RankingConfig::IGNORE_RANKING + ) + ranking_config.ranking_columns.build( + name: "Coluna", + order: Admissions::RankingColumn::ASC + ) + ranking_config.ranking_processes.build( + ranking_machine: @ranking_machine + ) + ranking_config + end + subject { ranking_config } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + it "should validate presence of at least one ranking column" do + ranking_config.ranking_columns.clear + expect(ranking_config).not_to be_valid + expect(ranking_config).to have_error(:too_short).with_parameters(count: 1).on :ranking_columns + end + it "should validate presence of at least one ranking process" do + ranking_config.ranking_processes.clear + expect(ranking_config).not_to be_valid + expect(ranking_config).to have_error(:too_short).with_parameters(count: 1).on :ranking_processes + end + it { should validate_presence_of(:behavior_on_invalid_condition) } + it { should validate_inclusion_of(:behavior_on_invalid_condition).in_array(Admissions::RankingConfig::BEHAVIOR_ON_INVALID_CONDITIONS) } + it { should validate_presence_of(:behavior_on_invalid_ranking) } + it { should validate_inclusion_of(:behavior_on_invalid_ranking).in_array(Admissions::RankingConfig::BEHAVIOR_ON_INVALID_RANKINGS) } + end + # ToDo: before_validation + # ToDo: initialize_dup + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + ranking_config.name = "Ranking" + expect(ranking_config.to_label).to eq("Ranking") + end + end + end +end diff --git a/spec/models/admissions/ranking_group_spec.rb b/spec/models/admissions/ranking_group_spec.rb new file mode 100644 index 00000000..a960c0f8 --- /dev/null +++ b/spec/models/admissions/ranking_group_spec.rb @@ -0,0 +1,50 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::RankingGroup, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:ranking_config).required(true) } + + before(:all) do + @ranking_config = FactoryBot.create(:ranking_config) + end + after(:all) do + @ranking_config.delete + end + let(:ranking_group) do + Admissions::RankingGroup.new( + ranking_config: @ranking_config, + name: "AC", + vacancies: 5 + ) + end + subject { ranking_group } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + ranking_group.vacancies = 5 + ranking_group.name = "AC" + expect(ranking_group.to_label).to eq("AC 5") + end + end + describe "total_vacancies" do + it "returns the correct total vacancies" do + ranking_group.vacancies = 5 + expect(ranking_group.total_vacancies).to eq(5) + end + it "returns infinity if vacancies is nil" do + ranking_group.vacancies = nil + expect(ranking_group.total_vacancies).to eq(Float::INFINITY) + end + end + end +end diff --git a/spec/models/admissions/ranking_machine_spec.rb b/spec/models/admissions/ranking_machine_spec.rb new file mode 100644 index 00000000..ee50d18a --- /dev/null +++ b/spec/models/admissions/ranking_machine_spec.rb @@ -0,0 +1,40 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::RankingMachine, type: :model do + it { should be_able_to_be_destroyed } + it { should have_many(:ranking_processes).dependent(:destroy) } + it { should belong_to(:form_condition).required(false) } + + before(:all) do + @destroy_later = [] + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:ranking_machine) do + Admissions::RankingMachine.new( + name: "Máquina de Ranqueamento" + ) + end + subject { ranking_machine } + describe "Validations" do + it { should be_valid } + it { should validate_presence_of(:name) } + end + # ToDo: initialize_dup + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + ranking_machine.name = "Máquina" + expect(ranking_machine.to_label).to eq("Máquina") + end + end + end +end diff --git a/spec/models/admissions/ranking_process_spec.rb b/spec/models/admissions/ranking_process_spec.rb new file mode 100644 index 00000000..a0c9ef39 --- /dev/null +++ b/spec/models/admissions/ranking_process_spec.rb @@ -0,0 +1,49 @@ +# Copyright (c) Universidade Federal Fluminense (UFF). +# This file is part of SAPOS. Please, consult the license terms in the LICENSE file. + +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Admissions::RankingProcess, type: :model do + it { should be_able_to_be_destroyed } + it { should belong_to(:ranking_config).required(true) } + it { should belong_to(:ranking_machine).required(true) } + + before(:all) do + @destroy_later = [] + @ranking_config = FactoryBot.create(:ranking_config) + @ranking_machine = FactoryBot.create(:ranking_machine) + end + after(:all) do + @ranking_config.delete + @ranking_machine.delete + end + after(:each) do + @destroy_later.each(&:delete) + @destroy_later.clear + end + let(:ranking_process) do + Admissions::RankingProcess.new( + ranking_config: @ranking_config, + ranking_machine: @ranking_machine, + ) + end + subject { ranking_process } + describe "Validations" do + it { should be_valid } + end + + describe "Methods" do + describe "to_label" do + it "returns the correct label" do + @ranking_machine.name = "Machine" + ranking_process.vacancies = 5 + ranking_process.group = "AC" + expect(ranking_process.to_label).to eq("Machine 5-AC") + end + end + # ToDo: calculate_remaining + # ToDo: decrease_vacancies_and_check_remaining! + end +end From 610e23a902d6c75d38e7922c53f180e01f644a82 Mon Sep 17 00:00:00 2001 From: IMonardez Date: Tue, 7 Jan 2025 13:09:01 -0300 Subject: [PATCH 6/8] ISSUE #448: Correction at enrollment_hold tests --- spec/features/student_enrollment_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/student_enrollment_spec.rb b/spec/features/student_enrollment_spec.rb index db72a664..8427c74e 100644 --- a/spec/features/student_enrollment_spec.rb +++ b/spec/features/student_enrollment_spec.rb @@ -109,7 +109,7 @@ @destroy_all << FactoryBot.create(:deferral, deferral_type: @deferral_type2, enrollment: @enrollment1, approval_date: 15.months.ago.at_beginning_of_month) # Holds - @destroy_all << @record = FactoryBot.create(:enrollment_hold, enrollment: @enrollment1, year: 2.years.ago.year, semester: 2, number_of_semesters: 1) + @destroy_all << @record = FactoryBot.create(:enrollment_hold, enrollment: @enrollment1, year: 3.years.ago.year, semester: 2, number_of_semesters: 1) # Scholarships @destroy_all << @sponsor1 = FactoryBot.create(:sponsor, name: "CNPq") From 45765d9e3dc2dd95746f8166dc52155af9e89621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Felipe=20Pimentel?= Date: Thu, 9 Jan 2025 23:03:08 -0300 Subject: [PATCH 7/8] #515: add code_type field to consolidation configuration --- app/assets/javascripts/form_fields/config_base.js | 3 ++- app/assets/javascripts/form_fields/config_select.js | 2 +- app/models/admissions/filled_form_field.rb | 4 ++++ config/locales/admissions/form_field.pt-BR.yml | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/form_fields/config_base.js b/app/assets/javascripts/form_fields/config_base.js index 8809becd..16096e12 100644 --- a/app/assets/javascripts/form_fields/config_base.js +++ b/app/assets/javascripts/form_fields/config_base.js @@ -138,7 +138,8 @@ function form_field_config_base(form_field) { } else if (selected_value == "code") { form_field.widgets = [ config_form_field_codemirror(form_field, "code", "text/x-ruby"), - config_form_field_condition(form_field, "condition", form_field.condition_options) + config_form_field_condition(form_field, "condition", form_field.condition_options), + config_form_field_select(form_field, "code_type", [["number", "Número"], ["string", "Texto"], ["date", "Data"]], { required: false, default: "number" }) ] } else if (selected_value == "email") { form_field.widgets = [ diff --git a/app/assets/javascripts/form_fields/config_select.js b/app/assets/javascripts/form_fields/config_select.js index 322590cd..cc4ab8a8 100644 --- a/app/assets/javascripts/form_fields/config_select.js +++ b/app/assets/javascripts/form_fields/config_select.js @@ -2,7 +2,7 @@ function config_form_field_select(form_field, field, selectable, options) { let r = (Math.random() + 1).toString(36).substring(7); let title = form_field.i18n(field); let id = `${form_field.baseid}_${field}_${r}` - let value = form_field.data[field] || ""; + let value = form_field.data[field] || options["default"] || ""; let options_text = []; let found = null; diff --git a/app/models/admissions/filled_form_field.rb b/app/models/admissions/filled_form_field.rb index aadcabfc..1e393bd1 100644 --- a/app/models/admissions/filled_form_field.rb +++ b/app/models/admissions/filled_form_field.rb @@ -356,6 +356,10 @@ def get_type else "string" end + when Admissions::FormField::CODE + configuration = self.form_field.config_hash + return configuration["code_type"] if configuration["code_type"].present? + "number" else "string" end diff --git a/config/locales/admissions/form_field.pt-BR.yml b/config/locales/admissions/form_field.pt-BR.yml index 9fbc30ab..eaa04f47 100644 --- a/config/locales/admissions/form_field.pt-BR.yml +++ b/config/locales/admissions/form_field.pt-BR.yml @@ -44,6 +44,7 @@ pt-BR: email: Email date: Data configurations: + code_type: "Tipo do resultado" show_config: "Mostrar configuração" hide_config: "Esconder configuração" error_exists: "Há algum problema nas configurações" From 46e14537377738281227bdec86ea7ed6550fe950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Felipe=20Pimentel?= Date: Thu, 9 Jan 2025 23:03:33 -0300 Subject: [PATCH 8/8] Add filled_form_field tests --- .../admissions/filled_form_field_spec.rb | 609 +++++++++++++----- spec/models/admissions/form_field_spec.rb | 1 + 2 files changed, 450 insertions(+), 160 deletions(-) diff --git a/spec/models/admissions/filled_form_field_spec.rb b/spec/models/admissions/filled_form_field_spec.rb index da4bb4ee..bc4ad2c0 100644 --- a/spec/models/admissions/filled_form_field_spec.rb +++ b/spec/models/admissions/filled_form_field_spec.rb @@ -27,14 +27,21 @@ @destroy_later.each(&:delete) @destroy_later.clear end - let(:filled_form) do + let(:filled_form_field) do Admissions::FilledFormField.new( value: "1", filled_form: @filled_form, form_field: @form_field ) end - subject { filled_form } + before(:each) do + @form_field.field_type = Admissions::FormField::STRING + filled_form_field.value = "1" + filled_form_field.filled_form = @filled_form + filled_form_field.form_field = @form_field + + end + subject { filled_form_field } describe "Validations" do it { should be_valid } it { should validate_presence_of(:filled_form) } @@ -42,272 +49,272 @@ describe "that_either_value_or_file_is_filled" do it "should be valid when no values are filled" do @form_field.configuration = '{"required": false}' - filled_form.value = nil - filled_form.file = nil - filled_form.list = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + filled_form_field.file = nil + filled_form_field.list = nil + expect(filled_form_field).to be_valid end it "should be valid when only one value is filled" do - filled_form.value = "1" - filled_form.file = nil - filled_form.list = nil - expect(filled_form).to be_valid + filled_form_field.value = "1" + filled_form_field.file = nil + filled_form_field.list = nil + expect(filled_form_field).to be_valid end it "should have error when more than one value is filled" do @form_field.field_type = Admissions::FormField::TEXT - filled_form.value = "1" - filled_form.file = nil - filled_form.list = [1, 2] - expect(filled_form).to have_field_error(:multiple_filling).on :value + filled_form_field.value = "1" + filled_form_field.file = nil + filled_form_field.list = [1, 2] + expect(filled_form_field).to have_field_error(:multiple_filling).on :value @form_field.field_type = Admissions::FormField::TEXT - filled_form.list = nil + filled_form_field.list = nil end it "should have error when more than one value is filled and attribute type is different" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX - filled_form.value = "1" - filled_form.file = nil - filled_form.list = [1, 2] - expect(filled_form).to have_field_error(:multiple_filling).on :list + filled_form_field.value = "1" + filled_form_field.file = nil + filled_form_field.list = [1, 2] + expect(filled_form_field).to have_field_error(:multiple_filling).on :list @form_field.field_type = Admissions::FormField::TEXT - filled_form.list = nil + filled_form_field.list = nil end end describe "that_value_follows_configuration_rules" do before(:each) do - filled_form.assign_attributes(value: nil, list: nil, file: nil) + filled_form_field.assign_attributes(value: nil, list: nil, file: nil) end describe "string fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::STRING @form_field.configuration = '{"required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::STRING @form_field.configuration = '{"required": true}' - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::STRING @form_field.configuration = '{"required": true}' - filled_form.value = nil - expect(filled_form).to have_field_error(:blank).on :value + filled_form_field.value = nil + expect(filled_form_field).to have_field_error(:blank).on :value end end describe "select fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::SELECT @form_field.configuration = '{"required": false, "values": "[1, 2]"}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::SELECT @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::SELECT @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.value = nil - expect(filled_form).to have_field_error(:blank).on :value + filled_form_field.value = nil + expect(filled_form_field).to have_field_error(:blank).on :value end end describe "radio fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::RADIO @form_field.configuration = '{"required": false, "values": "[1, 2]"}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::RADIO @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::RADIO @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.value = nil - expect(filled_form).to have_field_error(:blank).on :value + filled_form_field.value = nil + expect(filled_form_field).to have_field_error(:blank).on :value end end describe "collection_checkbox fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": false, "values": "[1, 2]"}' - filled_form.list = nil - expect(filled_form).to be_valid + filled_form_field.list = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.list = ["1", "2"] - expect(filled_form).to be_valid + filled_form_field.list = ["1", "2"] + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]"}' - filled_form.list = nil - expect(filled_form).to have_field_error(:blank).on :list + filled_form_field.list = nil + expect(filled_form_field).to have_field_error(:blank).on :list end it "valid when selection count >= minselection" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]", "minselection": 2}' - filled_form.list = ["1", "2"] - expect(filled_form).to be_valid + filled_form_field.list = ["1", "2"] + expect(filled_form_field).to be_valid end it "invalid when selection < minselection" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]", "minselection": 2}' - filled_form.list = ["1"] - expect(filled_form).to have_field_error(:minselection).on(:list).with_parameters(count: 2) + filled_form_field.list = ["1"] + expect(filled_form_field).to have_field_error(:minselection).on(:list).with_parameters(count: 2) end it "valid when selection count <= maxselection" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]", "maxselection": 2}' - filled_form.list = ["1", "2"] - expect(filled_form).to be_valid + filled_form_field.list = ["1", "2"] + expect(filled_form_field).to be_valid end it "invalid when selection > maxselection" do @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX @form_field.configuration = '{"required": true, "values": "[1, 2]", "maxselection": 2}' - filled_form.list = ["1", "2", "3"] - expect(filled_form).to have_field_error(:maxselection).on(:list).with_parameters(count: 2) + filled_form_field.list = ["1", "2", "3"] + expect(filled_form_field).to have_field_error(:maxselection).on(:list).with_parameters(count: 2) end end describe "text fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true}' - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true}' - filled_form.value = nil - expect(filled_form).to have_field_error(:blank).on :value + filled_form_field.value = nil + expect(filled_form_field).to have_field_error(:blank).on :value end end describe "city fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": false, "state_required": false, "country_required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when it only contains country and state, but city is not required" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": false, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when it only contains country, but city and state are not required" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": false, "state_required": false, "country_required": true}' - filled_form.value = " <$> <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "invalid when city is blank, but it is required " do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to have_field_error(:city_blank).on :value + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to have_field_error(:city_blank).on :value end it "invalid when state is blank, but it is required " do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> <$> Brasil" - expect(filled_form).to have_field_error(:state_blank).on :value + filled_form_field.value = "Niteroi <$> <$> Brasil" + expect(filled_form_field).to have_field_error(:state_blank).on :value end it "invalid when country is blank, but it is required " do @form_field.field_type = Admissions::FormField::CITY @form_field.configuration = '{"required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> " - expect(filled_form).to have_field_error(:country_blank).on :value + filled_form_field.value = "Niteroi <$> RJ <$> " + expect(filled_form_field).to have_field_error(:country_blank).on :value end end describe "residency fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::RESIDENCY @form_field.configuration = '{"required": false, "number_required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when it only contains number, but street is not required" do @form_field.field_type = Admissions::FormField::RESIDENCY @form_field.configuration = '{"required": false, "number_required": true}' - filled_form.value = " <$> 1" - expect(filled_form).to be_valid + filled_form_field.value = " <$> 1" + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::RESIDENCY @form_field.configuration = '{"required": true, "number_required": true}' - filled_form.value = "Rua X <$> 1" - expect(filled_form).to be_valid + filled_form_field.value = "Rua X <$> 1" + expect(filled_form_field).to be_valid end it "invalid when street is blank, but it is required " do @form_field.field_type = Admissions::FormField::RESIDENCY @form_field.configuration = '{"required": true, "number_required": true}' - filled_form.value = " <$> 1" - expect(filled_form).to have_field_error(:street_blank).on :value + filled_form_field.value = " <$> 1" + expect(filled_form_field).to have_field_error(:street_blank).on :value end it "invalid when number is blank, but it is required " do @form_field.field_type = Admissions::FormField::RESIDENCY @form_field.configuration = '{"required": true, "number_required": true}' - filled_form.value = "Rua X <$> " - expect(filled_form).to have_field_error(:number_blank).on :value + filled_form_field.value = "Rua X <$> " + expect(filled_form_field).to have_field_error(:number_blank).on :value end end describe "number fields should be" do it "valid when they are integers" do @form_field.field_type = Admissions::FormField::NUMBER - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "valid when they are floats" do @form_field.field_type = Admissions::FormField::NUMBER - filled_form.value = "1.1" - expect(filled_form).to be_valid + filled_form_field.value = "1.1" + expect(filled_form_field).to be_valid end it "invalid when filled with elements that are not numbers" do @form_field.field_type = Admissions::FormField::NUMBER - filled_form.value = "aaa" - expect(filled_form).to have_field_error(:invalid_number).on :value + filled_form_field.value = "aaa" + expect(filled_form_field).to have_field_error(:invalid_number).on :value end end describe "date fields should be" do it "valid when they have date formats" do @form_field.field_type = Admissions::FormField::DATE - filled_form.value = "11/11/2024" - expect(filled_form).to be_valid + filled_form_field.value = "11/11/2024" + expect(filled_form_field).to be_valid end it "invalid when filled with elements that are not dates" do @form_field.field_type = Admissions::FormField::DATE - filled_form.value = "aaa" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "aaa" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end it "invalid when filled with dates that are not in the %d/%m/%Y format" do @form_field.field_type = Admissions::FormField::DATE - filled_form.value = "01/30/2024" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "01/30/2024" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end end describe "student fields" do @@ -315,180 +322,180 @@ it "valid when null and not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": false, "state_required": false, "country_required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when it only contains country and state, but city is not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": false, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when it only contains country, but city and state are not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": false, "state_required": false, "country_required": true}' - filled_form.value = " <$> <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "invalid when city is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to have_field_error(:city_blank).on :value + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to have_field_error(:city_blank).on :value end it "invalid when state is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> <$> Brasil" - expect(filled_form).to have_field_error(:state_blank).on :value + filled_form_field.value = "Niteroi <$> <$> Brasil" + expect(filled_form_field).to have_field_error(:state_blank).on :value end it "invalid when country is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> " - expect(filled_form).to have_field_error(:country_blank).on :value + filled_form_field.value = "Niteroi <$> RJ <$> " + expect(filled_form_field).to have_field_error(:country_blank).on :value end end describe "special_birth_city should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": false, "country_required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when it only contains country and state, but city is not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when it only contains country, but city and state are not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": false, "state_required": false, "country_required": true}' - filled_form.value = " <$> <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = " <$> <$> Brasil" + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> Brasil" - expect(filled_form).to be_valid + filled_form_field.value = "Niteroi <$> RJ <$> Brasil" + expect(filled_form_field).to be_valid end it "invalid when city is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = " <$> RJ <$> Brasil" - expect(filled_form).to have_field_error(:city_blank).on :value + filled_form_field.value = " <$> RJ <$> Brasil" + expect(filled_form_field).to have_field_error(:city_blank).on :value end it "invalid when state is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> <$> Brasil" - expect(filled_form).to have_field_error(:state_blank).on :value + filled_form_field.value = "Niteroi <$> <$> Brasil" + expect(filled_form_field).to have_field_error(:state_blank).on :value end it "invalid when country is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_birth_city", "required": true, "state_required": true, "country_required": true}' - filled_form.value = "Niteroi <$> RJ <$> " - expect(filled_form).to have_field_error(:country_blank).on :value + filled_form_field.value = "Niteroi <$> RJ <$> " + expect(filled_form_field).to have_field_error(:country_blank).on :value end end describe "special_address should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_address", "required": false, "number_required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when it only contains number, but street is not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_address", "required": false, "number_required": true}' - filled_form.value = " <$> 1" - expect(filled_form).to be_valid + filled_form_field.value = " <$> 1" + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' - filled_form.value = "Rua X <$> 1" - expect(filled_form).to be_valid + filled_form_field.value = "Rua X <$> 1" + expect(filled_form_field).to be_valid end it "invalid when street is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' - filled_form.value = " <$> 1" - expect(filled_form).to have_field_error(:street_blank).on :value + filled_form_field.value = " <$> 1" + expect(filled_form_field).to have_field_error(:street_blank).on :value end it "invalid when number is blank, but it is required " do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "special_address", "required": true, "number_required": true}' - filled_form.value = "Rua X <$> " - expect(filled_form).to have_field_error(:number_blank).on :value + filled_form_field.value = "Rua X <$> " + expect(filled_form_field).to have_field_error(:number_blank).on :value end end describe "birthdate should be" do it "valid when they have date formats" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "birthdate"}' - filled_form.value = "11/11/2024" - expect(filled_form).to be_valid + filled_form_field.value = "11/11/2024" + expect(filled_form_field).to be_valid end it "invalid when filled with elements that are not dates" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "birthdate"}' - filled_form.value = "aaa" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "aaa" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end it "invalid when filled with dates that are not in the %d/%m/%Y format" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "birthdate"}' - filled_form.value = "01/30/2024" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "01/30/2024" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end end describe "identity_expedition_date should be" do it "valid when they have date formats" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "identity_expedition_date"}' - filled_form.value = "11/11/2024" - expect(filled_form).to be_valid + filled_form_field.value = "11/11/2024" + expect(filled_form_field).to be_valid end it "invalid when filled with elements that are not dates" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "identity_expedition_date"}' - filled_form.value = "aaa" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "aaa" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end it "invalid when filled with dates that are not in the %d/%m/%Y format" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "identity_expedition_date"}' - filled_form.value = "01/30/2024" - expect(filled_form).to have_field_error(:invalid_date).on :value + filled_form_field.value = "01/30/2024" + expect(filled_form_field).to have_field_error(:invalid_date).on :value end end describe "other types of fields should be" do it "valid when null and not required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "name", "required": false}' - filled_form.value = nil - expect(filled_form).to be_valid + filled_form_field.value = nil + expect(filled_form_field).to be_valid end it "valid when filled" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "name", "required": true}' - filled_form.value = "1" - expect(filled_form).to be_valid + filled_form_field.value = "1" + expect(filled_form_field).to be_valid end it "invalid when null and required" do @form_field.field_type = Admissions::FormField::STUDENT_FIELD @form_field.configuration = '{"field": "name", "required": true}' - filled_form.value = nil - expect(filled_form).to have_field_error(:blank).on :value + filled_form_field.value = nil + expect(filled_form_field).to have_field_error(:blank).on :value end end end @@ -500,15 +507,297 @@ end describe "Methods" do - # ToDo: test set_default_values - # ToDo: test to_label - # ToDo: test to_text - # ToDo: test simple_value + describe "set_default_values" do + it "should set the value as default if current value is nil and type is STRING" do + @form_field.configuration = '{"default": "a"}' + @form_field.field_type = Admissions::FormField::STRING + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("a") + end + it "should set the value as default if current value is nil, type is SELECT, and the value exists in values" do + @form_field.configuration = '{"default": "a", "values": ["a", "b"]}' + @form_field.field_type = Admissions::FormField::SELECT + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("a") + end + it "should not set the value as default if current value is nil, type is SELECT, and the value does not exist in values" do + @form_field.configuration = '{"default": "a", "values": ["c", "b"]}' + @form_field.field_type = Admissions::FormField::SELECT + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq(nil) + end + it "should set the list as default if current list is nil, and type is COLLECTION_CHECKBOX" do + @form_field.configuration = '{"default_values": ["a", "b"]}' + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + filled_form_field.list = nil + filled_form_field.set_default_values + expect(filled_form_field.list).to eq(["a", "b"]) + end + it "should set the value as default if current value is nil and type is RADIO" do + @form_field.configuration = '{"default": "a", "values": {"a": "a"}}' + @form_field.field_type = Admissions::FormField::RADIO + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("a") + end + it "should set the value as 1 if default_check is true and current value is nil and type is SINGLE_CHECKBOX" do + @form_field.configuration = '{"default_check": true}' + @form_field.field_type = Admissions::FormField::SINGLE_CHECKBOX + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("1") + end + it "should set the value as 0 if default_check is true and current value is nil and type is SINGLE_CHECKBOX" do + @form_field.configuration = '{"default_check": false}' + @form_field.field_type = Admissions::FormField::SINGLE_CHECKBOX + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("0") + end + it "should set the value as default if current value is nil and type is TEXT" do + @form_field.configuration = '{"default": "a"}' + @form_field.field_type = Admissions::FormField::TEXT + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("a") + end + it "should set the value as default if current value is nil and type is NUMBER" do + @form_field.configuration = '{"default": "1"}' + @form_field.field_type = Admissions::FormField::NUMBER + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("1") + end + it "should set the value as default if current value is nil and type is DATE" do + @form_field.configuration = '{"default": "2024/01/01"}' + @form_field.field_type = Admissions::FormField::DATE + filled_form_field.value = nil + filled_form_field.set_default_values + expect(filled_form_field.value).to eq("2024/01/01") + end + end + describe "to_label" do + it "should return '-' if form_field is blank" do + filled_form_field.form_field = nil + expect(filled_form_field.to_label).to eq("-") + end + it "should return 'field: -' if form_field name is 'field' and all values are blank" do + filled_form_field.form_field.name = 'field' + filled_form_field.file = nil + filled_form_field.list = nil + filled_form_field.value = nil + expect(filled_form_field.to_label).to eq("field: -") + end + it "should return 'field: value' if form_field name is 'field' and it has a value" do + filled_form_field.form_field.name = 'field' + filled_form_field.file = nil + filled_form_field.list = nil + filled_form_field.value = "value" + expect(filled_form_field.to_label).to eq("field: value") + end + it "should return 'field: [1, 2]' if form_field name is 'field' and it has a list" do + filled_form_field.form_field.name = 'field' + filled_form_field.file = nil + filled_form_field.list = ["1", "2"] + filled_form_field.value = nil + expect(filled_form_field.to_label).to eq('field: ["1", "2"]') + end + # ToDo: filled file + end + describe "to_text" do + it "should return - when form_field is blank" do + filled_form_field.form_field = nil + expect(filled_form_field.to_text).to eq("-") + end + it "should invoke function when custom method is defined" do + @form_field.field_type = Admissions::FormField::NUMBER + filled_form_field.value = "2" + expect(filled_form_field.to_text( + custom: { + Admissions::FormField::NUMBER => -> (filled_fielf, form_field) { + "1" + } + } + )).to eq("1") + end + it "should override type when field_type is provided" do + @form_field.field_type = Admissions::FormField::STRING + filled_form_field.value = "2" + expect(filled_form_field.to_text( + field_type: Admissions::FormField::NUMBER, + custom: { + Admissions::FormField::NUMBER => -> (filled_fielf, form_field) { + "1" + } + } + )).to eq("1") + end + it "should show all checkbox values when type is COLLECTION_CHECKBOX" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.list = ["b", "c"] + expect(filled_form_field.to_text).to eq("b, c") + end + it "should return - when type is COLLECTION_CHECKBOX and list is blank" do + @form_field.field_type = Admissions::FormField::COLLECTION_CHECKBOX + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.list = [] + expect(filled_form_field.to_text).to eq("-") + end + it "should return - when type is SELECT and value is blank" do + @form_field.field_type = Admissions::FormField::SELECT + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.value = nil + expect(filled_form_field.to_text).to eq("-") + end + it "should return value when type is SELECT and value is filled" do + @form_field.field_type = Admissions::FormField::SELECT + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.value = "a" + expect(filled_form_field.to_text).to eq("a") + end + it "should return - when type is RADIO and value is blank" do + @form_field.field_type = Admissions::FormField::RADIO + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.value = nil + expect(filled_form_field.to_text).to eq("-") + end + it "should return value when type is RADIO and value is filled" do + @form_field.field_type = Admissions::FormField::RADIO + @form_field.configuration = '{"values": ["a", "b", "c"]}' + filled_form_field.value = "a" + expect(filled_form_field.to_text).to eq("a") + end + it "should return city when type is CITY and value is filled" do + @form_field.field_type = Admissions::FormField::CITY + filled_form_field.value = "Niterói <$> RJ <$> Brasil" + expect(filled_form_field.to_text).to eq("Niterói, RJ, Brasil") + end + it "should return city when type is STUDENT_FIELD and field is special_city" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_city"}' + filled_form_field.value = "Niterói <$> RJ <$> Brasil" + expect(filled_form_field.to_text).to eq("Niterói, RJ, Brasil") + end + it "should return city when type is STUDENT_FIELD and field is special_birth_city" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_birth_city"}' + filled_form_field.value = "Niterói <$> RJ <$> Brasil" + expect(filled_form_field.to_text).to eq("Niterói, RJ, Brasil") + end + it "should return residency when type is RESIDENCY and value is filled" do + @form_field.field_type = Admissions::FormField::RESIDENCY + filled_form_field.value = "Rua abc <$> 123" + expect(filled_form_field.to_text).to eq("Rua abc, 123") + end + it "should return residency when type is STUDENT_FIELD and field is special_address" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "special_address"}' + filled_form_field.value = "Rua abc <$> 123" + expect(filled_form_field.to_text).to eq("Rua abc, 123") + end + it "should return value when type is STUDENT_FIELD and field is not special" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "name"}' + filled_form_field.value = "Ana" + expect(filled_form_field.to_text).to eq("Ana") + end + it "should return value for other types" do + @form_field.field_type = Admissions::FormField::TEXT + filled_form_field.value = "Ana" + expect(filled_form_field.to_text).to eq("Ana") + end + # ToDo: Admissions::FormField::FILE + # ToDo: Admissions::FormField::STUDENT_FIELD, field=photo + # ToDo: Admissions::FormField::SCHOLARITY + # ToDo: Admissions::FormField::STUDENT_FIELD, field=special_majors + end + describe "simple_value" do + it "should return list if list is present" do + filled_form_field.file = nil + filled_form_field.list = ["1", "2"] + filled_form_field.value = nil + expect(filled_form_field.simple_value).to eq(["1", "2"]) + end + it "should return value if value is present" do + filled_form_field.file = nil + filled_form_field.list = nil + filled_form_field.value = "1" + expect(filled_form_field.simple_value).to eq("1") + end + # ToDo: File + end + describe "get_type" do + it "should return number when the form_type is NUMBER" do + @form_field.field_type = Admissions::FormField::NUMBER + expect(filled_form_field.get_type).to eq("number") + end + it "should return date when the form_type is DATE" do + @form_field.field_type = Admissions::FormField::DATE + expect(filled_form_field.get_type).to eq("date") + end + it "should return date when the form_type is STUDENT_FIELD and field is birthdate" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "birthdate"}' + expect(filled_form_field.get_type).to eq("date") + end + it "should return date when the form_type is STUDENT_FIELD and field is identity_expedition_date" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "identity_expedition_date"}' + expect(filled_form_field.get_type).to eq("date") + end + it "should return string when the form_type is STUDENT_FIELD and field is anything else" do + @form_field.field_type = Admissions::FormField::STUDENT_FIELD + @form_field.configuration = '{"field": "name"}' + expect(filled_form_field.get_type).to eq("string") + end + it "should return number when the form_type is CODE and code_type is not defined" do + @form_field.field_type = Admissions::FormField::CODE + @form_field.configuration = '{}' + expect(filled_form_field.get_type).to eq("number") + end + it "should return code_type when the form_type is CODE and code_type is defined" do + @form_field.field_type = Admissions::FormField::CODE + @form_field.configuration = '{"code_type": "string"}' + expect(filled_form_field.get_type).to eq("string") + end + it "should return string when the form_type is anything else" do + @form_field.field_type = Admissions::FormField::TEXT + expect(filled_form_field.get_type).to eq("string") + end + end + describe "convert_value" do + it "should convert a string" do + expect(Admissions::FilledFormField.convert_value(1, "string")).to eq("1") + end + it "should convert a number" do + expect(Admissions::FilledFormField.convert_value("10.3", "number")).to eq(10.3) + end + it "should convert a date" do + expect(Admissions::FilledFormField.convert_value("15/01/2024", "date")).to eq(Date.new(2024, 1, 15)) + end + it "should not convert unknown types" do + expect(Admissions::FilledFormField.convert_value("1", "other")).to eq("1") + end + end + describe "convert_string" do + it "should convert a string" do + expect(Admissions::FilledFormField.convert_string(1)).to eq("1") + end + end + describe "convert_number" do + it "should convert a number" do + expect(Admissions::FilledFormField.convert_number("10.3")).to eq(10.3) + end + end + describe "convert_date" do + it "should convert a date" do + expect(Admissions::FilledFormField.convert_date("15/01/2024")).to eq(Date.new(2024, 1, 15)) + end + end # ToDo: test set_model_field - # ToDo: test get_type - # ToDo: test convert_value - # ToDo: test convert_string - # ToDo: test convert_number - # ToDo: test convert_date end end diff --git a/spec/models/admissions/form_field_spec.rb b/spec/models/admissions/form_field_spec.rb index c78d2630..e0efa5a4 100644 --- a/spec/models/admissions/form_field_spec.rb +++ b/spec/models/admissions/form_field_spec.rb @@ -93,5 +93,6 @@ end describe "Methods" do + # ToDo end end