diff --git a/.rubocop.yml b/.rubocop.yml index 1ec2cd62..5f454123 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -95,6 +95,10 @@ Layout/EmptyLinesAroundModuleBody: # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }. Style/HashSyntax: Enabled: true + # TODO: This is not preferred, but was followed and undoing it is more annoying... + EnforcedShorthandSyntax: always + # TODO: Enable this after upgrading rubocop, consistent would be preferred over never + # EnforcedShorthandSyntax: consistent # Method definitions after `private` or `protected` isolated calls need one # extra level of indentation. diff --git a/Gemfile b/Gemfile index 8a6fa608..91e80229 100644 --- a/Gemfile +++ b/Gemfile @@ -100,3 +100,7 @@ group :test do # Test suite speedup gem "rails-controller-testing" end + +group :development, :test do + gem "faker" +end diff --git a/Gemfile.lock b/Gemfile.lock index 20110be5..c7650204 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -577,6 +577,7 @@ DEPENDENCIES database_cleaner debug factory_bot_rails + faker haml-lint httparty (~> 0.21.0) image_processing (>= 1.2) diff --git a/lib/school_creator.rb b/lib/school_creator.rb new file mode 100644 index 00000000..3af215df --- /dev/null +++ b/lib/school_creator.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module SchoolCreator + def self.create_schools(number_of_schools, international: false) + grade_levels = School.grade_levels.keys + school_types = School.school_types.keys + available_countries = ISO3166::Country.all + + school_ids = [] + number_of_schools.times do + country = international ? available_countries.sample : ISO3166::Country["US"] + state = country.states.keys.sample + school = School.create!( + name: Faker::Educator.university, + city: Faker::Address.city, + state:, + country: country.alpha2, + website: Faker::Internet.url, + grade_level: grade_levels.sample, + school_type: school_types.sample + ) + school_ids.push(school.id) + end + school_ids + end +end diff --git a/lib/tasks/populate_teachers.rake b/lib/tasks/populate_teachers.rake new file mode 100644 index 00000000..e2355889 --- /dev/null +++ b/lib/tasks/populate_teachers.rake @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "school_creator" +require "teacher_creator" + +namespace :db do + desc "Populate the database with fake teacher data" + task populate_teachers: :environment do + number_of_US_schools = 5 + number_of_international_schools = 5 + school_ids = [] + + # Create US schools + school_ids << SchoolCreator.create_schools(number_of_US_schools) + + # Create International schools + school_ids << SchoolCreator.create_schools(number_of_international_schools, international: true) + + if school_ids.empty? + puts "No schools available to assign. Please create schools first." + exit + end + + number_of_teachers = 30 + TeacherCreator.create_teachers(number_of_teachers, school_ids) + + puts "#{number_of_US_schools} US schools created. \n#{number_of_US_schools} international schools created. \n#{number_of_teachers} teachers created." + end +end diff --git a/lib/teacher_creator.rb b/lib/teacher_creator.rb new file mode 100644 index 00000000..c2b40b5b --- /dev/null +++ b/lib/teacher_creator.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module TeacherCreator + def self.create_teachers(number_of_teachers, school_ids) + statuses = Teacher.statuses.keys + education_levels = Teacher.education_levels.keys + teachers = [] + + number_of_teachers.times do + teacher = Teacher.create!( + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + snap: Faker::Internet.username, + school_id: school_ids.sample, + personal_website: Faker::Internet.domain_name, + status: statuses.sample, + more_info: Faker::Lorem.sentence(word_count: 20), + education_level: education_levels.sample, + languages: Teacher::WORLD_LANGUAGES.sample(rand(1..3)) + ) + if teacher.persisted? + # Generate an email using the first_name and last_name from the teacher instance + email = Faker::Internet.email(name: "#{teacher.first_name} #{teacher.last_name}", separators: ["."]) + EmailAddress.create!( + teacher_id: teacher.id, + email:, + primary: true + ) + end + teachers.push(teacher) + end + teachers + end +end diff --git a/spec/lib/school_creator_spec.rb b/spec/lib/school_creator_spec.rb new file mode 100644 index 00000000..5a944b1f --- /dev/null +++ b/spec/lib/school_creator_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require "rails_helper" +require "./lib/school_creator" + +RSpec.describe SchoolCreator do + describe "#create_schools" do + let(:valid_states) { School::VALID_STATES } + let(:grade_levels) { ["elementary", "middle_school", "high_school"] } + let(:school_types) { ["public", "private"] } + + before do + allow(School).to receive_message_chain(:grade_levels, :keys).and_return(grade_levels) + allow(School).to receive_message_chain(:school_types, :keys).and_return(school_types) + end + + it "creates the specified number of US schools" do + schools = SchoolCreator.create_schools(5) + expect(schools.length).to eq(5) + end + + it "creates schools with appropriate attributes for US schools" do + SchoolCreator.create_schools(1) + school = School.last + + expect(school.country).to eq("US") + expect(valid_states).to include(school.state) + expect(grade_levels).to include(school.grade_level) + expect(school_types).to include(school.school_type) + end + + it "creates schools with no state for international schools" do + SchoolCreator.create_schools(1, international: true) + school = School.last + + expect(school.state).to be_nil + end + end +end diff --git a/spec/lib/teacher_creator_spec.rb b/spec/lib/teacher_creator_spec.rb new file mode 100644 index 00000000..0d965b12 --- /dev/null +++ b/spec/lib/teacher_creator_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "rails_helper" +require "./lib/teacher_creator" + +RSpec.describe TeacherCreator do + describe "#create_teachers" do + let(:school_ids) { [] } + let(:statuses) { ["csp_teacher", "non_csp_teacher", "mixed_class"] } + let(:education_levels) { ["middle_school", "high_school", "college"] } + let(:languages) { ["English", "Romanian", "German"] } + let(:valid_states) { ["CA", "NY", "TX"] } + + before do + # Create schools directly and push their IDs to the school_ids array + 3.times do |i| + school = School.create!( + name: "School #{i}", + city: Faker::Address.city, + country: "US", + website: Faker::Internet.url, + state: valid_states.sample + ) + school_ids << school.id + end + + allow(Teacher).to receive_message_chain(:statuses, :keys).and_return(statuses) + allow(Teacher).to receive_message_chain(:education_levels, :keys).and_return(education_levels) + Teacher::WORLD_LANGUAGES = languages + end + + it "creates the specified number of teachers" do + expect { + TeacherCreator.create_teachers(10, school_ids) + }.to change(Teacher, :count).by(10) + end + + it "assigns valid school_ids to each teacher" do + TeacherCreator.create_teachers(5, school_ids) + Teacher.last(5).each do |teacher| + expect(school_ids).to include(teacher.school_id) + end + end + end + end