diff --git a/api/.rubocop.yml b/api/.rubocop.yml index 4be5490c4..9812609b0 100644 --- a/api/.rubocop.yml +++ b/api/.rubocop.yml @@ -53,7 +53,7 @@ Documentation: # # Example: the following test would be invalid with this check enabled. # -# expect { Applicant.create }.to change { Applicant.count }.by 1 +# expect { User.create }.to change { User.count }.by 1 # Lint/AmbiguousBlockAssociation: Exclude: diff --git a/api/app/controllers/v1/applicant_profiles_controller.rb b/api/app/controllers/v1/applicant_profiles_controller.rb index c78f6ac13..cb69e0d81 100644 --- a/api/app/controllers/v1/applicant_profiles_controller.rb +++ b/api/app/controllers/v1/applicant_profiles_controller.rb @@ -2,13 +2,13 @@ module V1 class ApplicantProfilesController < ApiController - include ApplicantAuth + include UserAuth def show profile = ApplicantProfile.find_by(id: params[:id]) return render_not_found unless profile - return render_access_denied if profile.applicant != @applicant + return render_access_denied if profile.user != @user render_success(profile) end @@ -17,7 +17,7 @@ def update profile = ApplicantProfile.find_by(id: params[:id]) return render_not_found unless profile - return render_access_denied if profile.applicant != @applicant + return render_access_denied if profile.user != @user if profile.submitted_at.present? return render_field_error(:base, diff --git a/api/app/controllers/v1/concerns/applicant_auth.rb b/api/app/controllers/v1/concerns/user_auth.rb similarity index 74% rename from api/app/controllers/v1/concerns/applicant_auth.rb rename to api/app/controllers/v1/concerns/user_auth.rb index 6855f272d..f0f70a9eb 100644 --- a/api/app/controllers/v1/concerns/applicant_auth.rb +++ b/api/app/controllers/v1/concerns/user_auth.rb @@ -1,24 +1,24 @@ # frozen_string_literal: true # this is tested in spec/controllers/v1/concerns/ -module ApplicantAuth +module UserAuth extend ActiveSupport::Concern included do - before_action :authenticate_applicant + before_action :authenticate_user end - def authenticate_applicant + def authenticate_user auth_header = request.headers['Authorization'] return render_unauthenticated unless auth_header _auth_type, auth_token = auth_header.split(' ') return render_invalid_authorization unless auth_token - @applicant = Applicant.find_by(auth_token: auth_token) + @user = User.find_by(auth_token: auth_token) - if @applicant - unless @applicant.auth_token_generation > (Time.current - 1.day) + if @user + unless @user.auth_token_generation > (Time.current - 1.day) return render_error('auth token expired', 401) end diff --git a/api/app/controllers/v1/new_club_applications_controller.rb b/api/app/controllers/v1/new_club_applications_controller.rb index 6852559da..f2d81986a 100644 --- a/api/app/controllers/v1/new_club_applications_controller.rb +++ b/api/app/controllers/v1/new_club_applications_controller.rb @@ -2,11 +2,11 @@ module V1 class NewClubApplicationsController < ApiController - include ApplicantAuth + include UserAuth def index - if params[:applicant_id] == @applicant.id.to_s - render_success(@applicant.new_club_applications) + if params[:user_id] == @user.id.to_s + render_success(@user.new_club_applications) else render_access_denied end @@ -17,7 +17,7 @@ def show return render_not_found unless application - if application.applicants.include? @applicant + if application.users.include? @user render_success(application) else render_access_denied @@ -25,8 +25,8 @@ def show end def create - c = NewClubApplication.create(applicants: [@applicant], - point_of_contact: @applicant) + c = NewClubApplication.create(users: [@user], + point_of_contact: @user) render_success(c, 201) end @@ -34,7 +34,7 @@ def create def update c = NewClubApplication.find(params[:id]) - return render_access_denied unless c.applicants.include? @applicant + return render_access_denied unless c.users.include? @user if c.update_attributes(club_application_params) render_success(c) @@ -47,26 +47,26 @@ def add_applicant app = NewClubApplication.find_by(id: params[:new_club_application_id]) return render_not_found unless app - return render_access_denied unless app.applicants.include? @applicant + return render_access_denied unless app.users.include? @user if app.submitted_at.present? return render_field_error(:base, 'cannot edit application after submit') end - to_add = Applicant.find_or_create_by(email: params[:email]) + to_add = User.find_or_create_by(email: params[:email]) - if app.applicants.include? to_add + if app.users.include? to_add return render_field_error(:email, 'already added') end profile = ApplicantProfile.with_deleted.find_or_create_by( - applicant: to_add, + user: to_add, new_club_application: app ) profile.restore if profile.deleted? - ApplicantMailer.added_to_application(app, to_add, @applicant) + ApplicantMailer.added_to_application(app, to_add, @user) .deliver_later render_success @@ -74,27 +74,27 @@ def add_applicant def remove_applicant app = NewClubApplication.find_by(id: params[:new_club_application_id]) - to_remove = Applicant.find_by(id: params[:applicant_id]) + to_remove = User.find_by(id: params[:user_id]) return render_not_found unless app && to_remove - return render_access_denied unless app.applicants.include? @applicant + return render_access_denied unless app.users.include? @user - return render_access_denied unless app.point_of_contact == @applicant + return render_access_denied unless app.point_of_contact == @user if app.submitted_at.present? return render_field_error(:base, 'cannot edit application after submit') end - if to_remove == @applicant - return render_field_error(:applicant_id, 'cannot remove self') + if to_remove == @user + return render_field_error(:user_id, 'cannot remove self') end - unless app.applicants.include? to_remove - return render_field_error(:applicant_id, 'not added to application') + unless app.users.include? to_remove + return render_field_error(:user_id, 'not added to application') end - app.applicants.delete(to_remove) + app.users.delete(to_remove) render_success end @@ -102,7 +102,7 @@ def submit app = NewClubApplication.find_by(id: params[:new_club_application_id]) return render_not_found unless app - return render_access_denied unless app.applicants.include? @applicant + return render_access_denied unless app.users.include? @user if app.submit! render_success(app) diff --git a/api/app/controllers/v1/applicants_controller.rb b/api/app/controllers/v1/users_controller.rb similarity index 82% rename from api/app/controllers/v1/applicants_controller.rb rename to api/app/controllers/v1/users_controller.rb index 59cb9ecd4..3974a3f55 100644 --- a/api/app/controllers/v1/applicants_controller.rb +++ b/api/app/controllers/v1/users_controller.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true module V1 - class ApplicantsController < ApiController + class UsersController < ApiController def auth - applicant = Applicant.find_or_initialize_by(email: params[:email]) + applicant = User.find_or_initialize_by(email: params[:email]) applicant.generate_login_code! @@ -17,7 +17,7 @@ def auth end def exchange_login_code - applicant = Applicant.find_by(id: params[:applicant_id]) + applicant = User.find_by(id: params[:user_id]) login_code = params[:login_code] return render_not_found unless applicant diff --git a/api/app/mailers/applicant_mailer.rb b/api/app/mailers/applicant_mailer.rb index 067f92474..84f898637 100644 --- a/api/app/mailers/applicant_mailer.rb +++ b/api/app/mailers/applicant_mailer.rb @@ -1,30 +1,30 @@ # frozen_string_literal: true class ApplicantMailer < ApplicationMailer - def login_code(applicant) - @login_code = applicant.pretty_login_code + def login_code(user) + @login_code = user.pretty_login_code - mail(to: applicant.email, subject: "Hack Club Login Code (#{@login_code})") + mail(to: user.email, subject: "Hack Club Login Code (#{@login_code})") end - def added_to_application(application, applicant, adder) + def added_to_application(application, user, adder) @high_school = application.high_school_name - @applicant_email = applicant.email + @user_email = user.email @adder_email = adder.email - mail(to: applicant.email, + mail(to: user.email, subject: "You've been added to a Hack Club application") end - def application_submission(application, applicant) + def application_submission(application, user) @application = application @profile = ApplicantProfile.find_by(new_club_application: application, - applicant: applicant) + user: user) @application_fields = application_fields(@application) @profile_fields = profile_fields(@profile) - mail(to: applicant.email, subject: 'Hack Club Application Submitted') + mail(to: user.email, subject: 'Hack Club Application Submitted') end def application_submission_staff(application) diff --git a/api/app/models/applicant_profile.rb b/api/app/models/applicant_profile.rb index 1c12a43bd..56742f5d1 100644 --- a/api/app/models/applicant_profile.rb +++ b/api/app/models/applicant_profile.rb @@ -6,10 +6,10 @@ class ApplicantProfile < ApplicationRecord # preserve information from record deletions acts_as_paranoid - belongs_to :applicant + belongs_to :user belongs_to :new_club_application - validates :applicant, :new_club_application, presence: true + validates :user, :new_club_application, presence: true validates :leader_email, email: true, if: -> { leader_email.present? } enum leader_year_in_school: %i[ @@ -60,7 +60,7 @@ class ApplicantProfile < ApplicationRecord before_save :update_completion_status def prefill_leader_email - self.leader_email = applicant.email + self.leader_email = user.email end # automatically set or unset completed_at if all REQUIRED_FOR_COMPLETION diff --git a/api/app/models/new_club_application.rb b/api/app/models/new_club_application.rb index 560280495..43385361b 100644 --- a/api/app/models/new_club_application.rb +++ b/api/app/models/new_club_application.rb @@ -6,8 +6,8 @@ class NewClubApplication < ApplicationRecord validate :point_of_contact_is_associated has_many :applicant_profiles - has_many :applicants, through: :applicant_profiles - belongs_to :point_of_contact, class_name: 'Applicant' + has_many :users, through: :applicant_profiles + belongs_to :point_of_contact, class_name: 'User' geocode_attrs address: :high_school_address, latitude: :high_school_latitude, @@ -68,7 +68,7 @@ def submit! if valid? if save - applicants.each do |applicant| + users.each do |applicant| ApplicantMailer.application_submission(self, applicant).deliver_later end @@ -87,7 +87,7 @@ def submit! # ensure that the point of contact is an associated applicant def point_of_contact_is_associated return unless point_of_contact - return if applicants.include? point_of_contact + return if users.include? point_of_contact errors.add(:point_of_contact, 'must be an associated applicant') end diff --git a/api/app/models/applicant.rb b/api/app/models/user.rb similarity index 85% rename from api/app/models/applicant.rb rename to api/app/models/user.rb index bac914c00..ba5a86594 100644 --- a/api/app/models/applicant.rb +++ b/api/app/models/user.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Applicant < ApplicationRecord +class User < ApplicationRecord validates :email, presence: true, uniqueness: true, email: true validates :login_code, uniqueness: { if: -> { login_code.present? } } validates :auth_token, uniqueness: { if: -> { auth_token.present? } } @@ -16,7 +16,7 @@ def generate_login_code! self.login_code_generation = Time.current # repeat until code is unique - break unless Applicant.find_by(login_code: login_code) + break unless User.find_by(login_code: login_code) end end @@ -31,7 +31,7 @@ def generate_auth_token! self.auth_token_generation = Time.current # repeat until token is unique - break unless Applicant.find_by(auth_token: auth_token) + break unless User.find_by(auth_token: auth_token) end end end diff --git a/api/app/serializers/new_club_application_serializer.rb b/api/app/serializers/new_club_application_serializer.rb index a4d76da95..ce97777da 100644 --- a/api/app/serializers/new_club_application_serializer.rb +++ b/api/app/serializers/new_club_application_serializer.rb @@ -34,9 +34,9 @@ class NewClubApplicationSerializer < ActiveModel::Serializer class ApplicantProfileSerializer < ActiveModel::Serializer attributes :id, :completed_at - has_one :applicant + has_one :user - class ApplicantSerializer < ActiveModel::Serializer + class UserSerializer < ActiveModel::Serializer attributes :id, :email end end diff --git a/api/app/serializers/applicant_serializer.rb b/api/app/serializers/user_serializer.rb similarity index 53% rename from api/app/serializers/applicant_serializer.rb rename to api/app/serializers/user_serializer.rb index 00955a4d0..11268ab57 100644 --- a/api/app/serializers/applicant_serializer.rb +++ b/api/app/serializers/user_serializer.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -class ApplicantSerializer < ActiveModel::Serializer +class UserSerializer < ActiveModel::Serializer attributes :id, :email end diff --git a/api/app/views/applicant_mailer/added_to_application.html.erb b/api/app/views/applicant_mailer/added_to_application.html.erb index aec2b9063..ac49180f3 100644 --- a/api/app/views/applicant_mailer/added_to_application.html.erb +++ b/api/app/views/applicant_mailer/added_to_application.html.erb @@ -8,7 +8,7 @@ by <%= mail_to @adder_email %>.

Please log in at <%= link_to 'https://hackclub.com/apply', - "https://hackclub.com/apply?email=#{@applicant_email}" %> + "https://hackclub.com/apply?email=#{@user_email}" %> to view the application and make edits.

- Hack Club

diff --git a/api/app/views/applicant_mailer/added_to_application.text.erb b/api/app/views/applicant_mailer/added_to_application.text.erb index fa74b3b95..109f43bae 100644 --- a/api/app/views/applicant_mailer/added_to_application.text.erb +++ b/api/app/views/applicant_mailer/added_to_application.text.erb @@ -2,6 +2,6 @@ Hi, You've been added to an application to start a Hack Club (https://hackclub.com) <%= "at #{@high_school} " if @high_school.present? %>by <%= @adder_email %>. -Please log in at https://hackclub.com/apply with <%= @applicant_email %> to view the application and make edits. +Please log in at https://hackclub.com/apply with <%= @user_email %> to view the application and make edits. - Hack Club diff --git a/api/config/routes.rb b/api/config/routes.rb index 2e29a1793..0db6adc4f 100644 --- a/api/config/routes.rb +++ b/api/config/routes.rb @@ -26,7 +26,7 @@ resources :applicant_profiles, only: %i[show update] - resources :applicants, except: :all do + resources :users, except: :all do collection do post 'auth' end diff --git a/api/db/migrate/20180127073628_rename_applicants_to_users.rb b/api/db/migrate/20180127073628_rename_applicants_to_users.rb new file mode 100644 index 000000000..a3ce3b569 --- /dev/null +++ b/api/db/migrate/20180127073628_rename_applicants_to_users.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class RenameApplicantsToUsers < ActiveRecord::Migration[5.1] + def change + rename_table :applicants, :users + rename_column :applicant_profiles, :applicant_id, :user_id + end +end diff --git a/api/db/schema.rb b/api/db/schema.rb index 5986e9952..d26493339 100644 --- a/api/db/schema.rb +++ b/api/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180127051157) do +ActiveRecord::Schema.define(version: 20180127073628) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -24,7 +24,7 @@ end create_table "applicant_profiles", id: :serial, force: :cascade do |t| - t.integer "applicant_id" + t.integer "user_id" t.integer "new_club_application_id" t.text "leader_name" t.text "leader_email" @@ -55,19 +55,9 @@ t.datetime "updated_at", null: false t.date "leader_birthday" t.datetime "deleted_at" - t.index ["applicant_id"], name: "index_applicant_profiles_on_applicant_id" t.index ["deleted_at"], name: "index_applicant_profiles_on_deleted_at" t.index ["new_club_application_id"], name: "index_applicant_profiles_on_new_club_application_id" - end - - create_table "applicants", id: :serial, force: :cascade do |t| - t.text "email" - t.text "login_code" - t.datetime "login_code_generation" - t.text "auth_token" - t.datetime "auth_token_generation" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_applicant_profiles_on_user_id" end create_table "athul_clubs", id: :serial, force: :cascade do |t| @@ -343,6 +333,16 @@ t.datetime "updated_at", null: false end + create_table "users", id: :serial, force: :cascade do |t| + t.text "email" + t.text "login_code" + t.datetime "login_code_generation" + t.text "auth_token" + t.datetime "auth_token_generation" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + add_foreign_key "athul_clubs", "clubs" add_foreign_key "athul_clubs", "leaders" add_foreign_key "athul_clubs", "letters" @@ -350,7 +350,7 @@ add_foreign_key "check_ins", "leaders" add_foreign_key "clubs", "leaders", column: "point_of_contact_id" add_foreign_key "net_promoter_score_surveys", "leaders" - add_foreign_key "new_club_applications", "applicants", column: "point_of_contact_id" + add_foreign_key "new_club_applications", "users", column: "point_of_contact_id" add_foreign_key "slack_invite_strategies", "hackbot_teams" add_foreign_key "slack_invites", "hackbot_teams" add_foreign_key "slack_invites", "slack_invite_strategies" diff --git a/api/spec/controllers/v1/concerns/applicant_auth_spec.rb b/api/spec/controllers/v1/concerns/applicant_auth_spec.rb index 33738bb6e..8ca2cdbdd 100644 --- a/api/spec/controllers/v1/concerns/applicant_auth_spec.rb +++ b/api/spec/controllers/v1/concerns/applicant_auth_spec.rb @@ -2,10 +2,10 @@ require 'rails_helper' -RSpec.describe ApplicantAuth, type: :controller do +RSpec.describe UserAuth, type: :controller do # make fake controller for testing controller(V1::ApiController) do - include ApplicantAuth + include UserAuth def fake_action render_success @@ -18,8 +18,8 @@ def fake_action end end - let(:applicant) do - a = create(:applicant) + let(:user) do + a = create(:user) a.generate_auth_token! a.save @@ -35,7 +35,7 @@ def fake_action it 'errors when auth token is nil' do # create applicant with nil auth token to try and trick it - create(:applicant, auth_token: nil) + create(:user, auth_token: nil) request.headers['Authorization'] = 'Bearer' @@ -55,7 +55,7 @@ def fake_action end it 'succeeds with valid auth token' do - request.headers['Authorization'] = "Bearer #{applicant.auth_token}" + request.headers['Authorization'] = "Bearer #{user.auth_token}" get :fake_action @@ -64,10 +64,10 @@ def fake_action end it 'errors when auth token is older than 24 hours' do - applicant.auth_token_generation -= 1.day - applicant.save + user.auth_token_generation -= 1.day + user.save - request.headers['Authorization'] = "Bearer #{applicant.auth_token}" + request.headers['Authorization'] = "Bearer #{user.auth_token}" get :fake_action diff --git a/api/spec/factories/applicant_profiles.rb b/api/spec/factories/applicant_profiles.rb index 38abf6adf..5c8489cf2 100644 --- a/api/spec/factories/applicant_profiles.rb +++ b/api/spec/factories/applicant_profiles.rb @@ -2,7 +2,7 @@ FactoryBot.define do factory :applicant_profile do - association :applicant + association :user association :new_club_application # applicant profile ready for submission. only includes required fields + diff --git a/api/spec/factories/applicants.rb b/api/spec/factories/applicants.rb deleted file mode 100644 index e397347ef..000000000 --- a/api/spec/factories/applicants.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :applicant do - email { Faker::Internet.email } - - factory :applicant_authed do - after(:build) do |applicant| - applicant.generate_login_code! - - # make it look like the login code was generated a minute ago - applicant.login_code_generation -= 1.minute - - applicant.generate_auth_token! - end - end - end -end diff --git a/api/spec/factories/new_club_applications.rb b/api/spec/factories/new_club_applications.rb index 718d8d222..7125c4fb6 100644 --- a/api/spec/factories/new_club_applications.rb +++ b/api/spec/factories/new_club_applications.rb @@ -6,7 +6,7 @@ # relationships. factory :completed_new_club_application do transient do - applicant_count 3 + profile_count 3 end # high school @@ -42,10 +42,10 @@ # relationships after(:create) do |application, evaluator| # will also create applicants - create_list(:completed_applicant_profile, evaluator.applicant_count, + create_list(:completed_applicant_profile, evaluator.profile_count, new_club_application: application) - application.point_of_contact = application.applicants.first + application.point_of_contact = application.users.first end end end diff --git a/api/spec/factories/users.rb b/api/spec/factories/users.rb new file mode 100644 index 000000000..27a6312f3 --- /dev/null +++ b/api/spec/factories/users.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :user do + email { Faker::Internet.email } + + factory :user_authed do + after(:build) do |user| + user.generate_login_code! + + # make it look like the login code was generated a minute ago + user.login_code_generation -= 1.minute + + user.generate_auth_token! + end + end + end +end diff --git a/api/spec/mailers/applicant_spec.rb b/api/spec/mailers/applicant_spec.rb index ee6086cde..edc85c67b 100644 --- a/api/spec/mailers/applicant_spec.rb +++ b/api/spec/mailers/applicant_spec.rb @@ -4,15 +4,15 @@ RSpec.describe ApplicantMailer, type: :mailer do describe 'login_code' do - let(:applicant) do - applicant = create(:applicant) - applicant.generate_login_code! - applicant.save + let(:user) do + user = create(:user) + user.generate_login_code! + user.save - applicant + user end - let(:mail) { ApplicantMailer.login_code(applicant) } + let(:mail) { ApplicantMailer.login_code(user) } it 'is from team@mail.hackclub.com' do expect(mail).to deliver_from('Hack Club Team ') @@ -22,31 +22,31 @@ expect(mail).to reply_to('team@hackclub.com') end - it 'is sent to the applicant' do - expect(mail).to deliver_to(applicant.email) + it 'is sent to the user' do + expect(mail).to deliver_to(user.email) end it 'contains the given prettified login code' do - expect(mail).to have_body_text(applicant.pretty_login_code) + expect(mail).to have_body_text(user.pretty_login_code) end end describe 'added_to_application' do - let(:adder) { create(:applicant) } - let(:applicant) { create(:applicant) } + let(:adder) { create(:user) } + let(:user) { create(:user) } let(:club_application) { create(:new_club_application) } before do - club_application.applicants << adder - club_application.applicants << applicant + club_application.users << adder + club_application.users << user end let(:mail) do - ApplicantMailer.added_to_application(club_application, applicant, adder) + ApplicantMailer.added_to_application(club_application, user, adder) end - it 'is sent to the given applicant' do - expect(mail).to deliver_to(applicant.email) + it 'is sent to the given user' do + expect(mail).to deliver_to(user.email) end it 'includes the high school name when set' do @@ -59,31 +59,31 @@ expect(mail).to have_body_text(adder.email) end - it "includes the given applicant's email" do - expect(mail).to have_body_text(applicant.email) + it "includes the given user's email" do + expect(mail).to have_body_text(user.email) end end describe 'application_submission' do let(:application) { create(:completed_new_club_application) } - let(:applicant) { application.applicants.first } + let(:user) { application.users.first } before { application.submit! } let(:mail) do - ApplicantMailer.application_submission(application, applicant) + ApplicantMailer.application_submission(application, user) end - it 'is sent to the given applicant' do - expect(mail).to deliver_to(applicant.email) + it 'is sent to the given user' do + expect(mail).to deliver_to(user.email) end it 'includes fields from the application' do expect(mail).to have_body_text(application.progress_general) end - it "includes fields from the applicant's profile" do - profile = ApplicantProfile.find_by(applicant: applicant, + it "includes fields from the user's applicant profile" do + profile = ApplicantProfile.find_by(user: user, new_club_application: application) expect(mail).to have_body_text(profile.skills_system_hacked) end diff --git a/api/spec/models/applicant_profile_spec.rb b/api/spec/models/applicant_profile_spec.rb index 70e45a1b5..9b899a0c5 100644 --- a/api/spec/models/applicant_profile_spec.rb +++ b/api/spec/models/applicant_profile_spec.rb @@ -10,7 +10,7 @@ it { should have_db_column :updated_at } # relations - it { should have_db_column :applicant_id } + it { should have_db_column :user_id } it { should have_db_column :new_club_application_id } # leader @@ -56,7 +56,7 @@ ## validations ## - it { should validate_presence_of :applicant } + it { should validate_presence_of :user } it { should validate_presence_of :new_club_application } it { should validate_email_format_of :leader_email } @@ -64,13 +64,13 @@ ## relationships ## - it { should belong_to :applicant } + it { should belong_to :user } it { should belong_to :new_club_application } it 'should prefill email with applicant info' do # when email is not set, prefill profile = create(:applicant_profile) - expect(profile.leader_email).to eq(profile.applicant.email) + expect(profile.leader_email).to eq(profile.user.email) # when email is set, do not overwrite it profile = create(:applicant_profile, leader_email: 'foo@bar.com') diff --git a/api/spec/models/new_club_application_spec.rb b/api/spec/models/new_club_application_spec.rb index 7b4bc7fb9..806e5a3b8 100644 --- a/api/spec/models/new_club_application_spec.rb +++ b/api/spec/models/new_club_application_spec.rb @@ -62,11 +62,11 @@ ## relationships ## it { should have_many(:applicant_profiles) } - it { should have_many(:applicants).through(:applicant_profiles) } + it { should have_many(:users).through(:applicant_profiles) } it { should belong_to(:point_of_contact) } - it 'requires points of contact to be associated applicants' do - bad_poc = create(:applicant) + it 'requires points of contact to be associated users' do + bad_poc = create(:user) subject.update_attributes(point_of_contact: bad_poc) @@ -75,10 +75,10 @@ end describe ':submit!' do - subject { create(:completed_new_club_application, applicant_count: 3) } - let(:applicant) { subject.point_of_contact } + subject { create(:completed_new_club_application, profile_count: 3) } + let(:user) { subject.point_of_contact } let(:profile) do - ApplicantProfile.find_by(applicant: applicant, + ApplicantProfile.find_by(user: user, new_club_application: subject) end diff --git a/api/spec/models/applicant_spec.rb b/api/spec/models/user_spec.rb similarity index 95% rename from api/spec/models/applicant_spec.rb rename to api/spec/models/user_spec.rb index 4d2531559..4e32aab52 100644 --- a/api/spec/models/applicant_spec.rb +++ b/api/spec/models/user_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' -RSpec.describe Applicant, type: :model do - subject { build(:applicant) } +RSpec.describe User, type: :model do + subject { build(:user) } it { should have_db_column :email } it { should have_db_column :login_code } diff --git a/api/spec/requests/v1/applicant_profiles_spec.rb b/api/spec/requests/v1/applicant_profiles_spec.rb index 6c4639e98..2127325eb 100644 --- a/api/spec/requests/v1/applicant_profiles_spec.rb +++ b/api/spec/requests/v1/applicant_profiles_spec.rb @@ -4,10 +4,9 @@ RSpec.describe 'V1::ApplicantProfiles', type: :request do let(:profile) do - create(:completed_applicant_profile, - applicant: create(:applicant_authed)) + create(:completed_applicant_profile, user: create(:user_authed)) end - let(:applicant) { profile.applicant } + let(:applicant) { profile.user } let(:application) { profile.new_club_application } let(:auth_headers) { { 'Authorization': "Bearer #{applicant.auth_token}" } } diff --git a/api/spec/requests/v1/new_club_applications_spec.rb b/api/spec/requests/v1/new_club_applications_spec.rb index 51dc9e2e1..8707986c2 100644 --- a/api/spec/requests/v1/new_club_applications_spec.rb +++ b/api/spec/requests/v1/new_club_applications_spec.rb @@ -3,32 +3,32 @@ require 'rails_helper' RSpec.describe 'V1::NewClubApplications', type: :request do - let(:applicant) { create(:applicant_authed) } - let(:auth_headers) { { 'Authorization': "Bearer #{applicant.auth_token}" } } + let(:user) { create(:user_authed) } + let(:auth_headers) { { 'Authorization': "Bearer #{user.auth_token}" } } - describe 'GET /v1/applicants/:id/new_club_applications' do + describe 'GET /v1/users/:id/new_club_applications' do it 'requires authentication' do - get "/v1/applicants/#{applicant.id}/new_club_applications" + get "/v1/users/#{user.id}/new_club_applications" expect(response.status).to eq(401) end it 'lists club applications with valid auth token' do 5.times do - applicant.new_club_applications << NewClubApplication.create + user.new_club_applications << NewClubApplication.create end - get "/v1/applicants/#{applicant.id}/new_club_applications", + get "/v1/users/#{user.id}/new_club_applications", headers: auth_headers expect(response.status).to eq(200) expect(json.length).to eq(5) end - it 'refuses to list applications for other applicants' do - other_applicant = create(:applicant) - other_applicant.new_club_applications << create(:new_club_application) + it 'refuses to list applications for other users' do + other_user = create(:user) + other_user.new_club_applications << create(:new_club_application) - get "/v1/applicants/#{other_applicant.id}/new_club_applications", + get "/v1/users/#{other_user.id}/new_club_applications", headers: auth_headers expect(response.status).to eq(403) @@ -36,41 +36,41 @@ end end - describe 'POST /v1/applicants/:id/new_club_applications' do + describe 'POST /v1/users/:id/new_club_applications' do it 'requires authentication' do - post "/v1/applicants/#{applicant.id}/new_club_applications" + post "/v1/users/#{user.id}/new_club_applications" expect(response.status).to eq(401) end it 'creates a new club application with valid auth token' do - post "/v1/applicants/#{applicant.id}/new_club_applications", + post "/v1/users/#{user.id}/new_club_applications", headers: auth_headers expect(response.status).to eq(201) expect(json).to include('id', 'created_at', 'updated_at') end - it 'sets the point of contact to the applicant' do - post "/v1/applicants/#{applicant.id}/new_club_applications", + it 'sets the point of contact to the user' do + post "/v1/users/#{user.id}/new_club_applications", headers: auth_headers expect(response.status).to eq(201) - expect(json).to include('point_of_contact_id' => applicant.id) + expect(json).to include('point_of_contact_id' => user.id) end end describe 'GET /v1/new_club_applications/:id' do let(:club_application) { create(:new_club_application) } - before { applicant.new_club_applications << club_application } + before { user.new_club_applications << club_application } it 'requires authentication' do get "/v1/new_club_applications/#{club_application.id}" expect(response.status).to eq(401) end - it 'errors when authed applicant does not own application' do + it 'errors when authed user does not own application' do other_application = create(:new_club_application) get "/v1/new_club_applications/#{other_application.id}", @@ -91,17 +91,17 @@ expect(response.status).to eq(200) expect(json).to include('high_school_name' => 'Superhero High School') - # includes list of applicant profile ids, status, and applicant info + # includes list of applicant profile ids, status, and user info profile = ApplicantProfile.find_by( - applicant: applicant, + user: user, new_club_application: club_application ) expect(json['applicant_profiles'].first).to eq( 'id' => profile.id, 'completed_at' => profile.completed_at, - 'applicant' => { - 'id' => profile.applicant.id, - 'email' => profile.applicant.email + 'user' => { + 'id' => profile.user.id, + 'email' => profile.user.email } ) end @@ -118,7 +118,7 @@ describe 'PATCH /v1/new_club_applications/:id' do let(:club_application) { create(:new_club_application) } - before { applicant.new_club_applications << club_application } + before { user.new_club_applications << club_application } it 'requires_authentication' do patch "/v1/new_club_applications/#{club_application.id}", params: { @@ -128,14 +128,14 @@ expect(response.status).to eq(401) end - it 'errors when auth token is for the wrong applicant' do - other_applicant = create(:applicant) - other_applicant.generate_auth_token! - other_applicant.save + it 'errors when auth token is for the wrong user' do + other_user = create(:user) + other_user.generate_auth_token! + other_user.save patch "/v1/new_club_applications/#{club_application.id}", headers: { - 'Authorization': "Bearer #{other_applicant.auth_token}" + 'Authorization': "Bearer #{other_user.auth_token}" }, params: { high_school_name: 'Superhero High School' @@ -161,8 +161,8 @@ end it 'sets point of contact with valid auth token' do - poc = create(:applicant) - club_application.applicants << poc + poc = create(:user) + club_application.users << poc patch "/v1/new_club_applications/#{club_application.id}", headers: auth_headers, @@ -175,7 +175,7 @@ end it 'fails to set point of contact when not associated' do - bad_poc = create(:applicant) + bad_poc = create(:user) patch "/v1/new_club_applications/#{club_application.id}", headers: auth_headers, @@ -226,8 +226,8 @@ it 'fails to update fields when application has been submitted' do application = create(:completed_new_club_application) create(:completed_applicant_profile, - new_club_application: application, applicant: applicant) - application.update_attributes(point_of_contact: applicant) + new_club_application: application, user: user) + application.update_attributes(point_of_contact: user) post "/v1/new_club_applications/#{application.id}/submit", headers: auth_headers @@ -246,7 +246,7 @@ describe 'POST /v1/new_club_applications/:id/add_applicant' do let(:club_application) { create(:new_club_application) } - before { applicant.new_club_applications << club_application } + before { user.new_club_applications << club_application } it 'requires authentication' do post "/v1/new_club_applications/#{club_application.id}/add_applicant", @@ -275,8 +275,8 @@ expect(json).to include('error' => 'not found') end - it 'creates new applicant and sends email when given email is new' do - starting_applicant_count = Applicant.count + it 'creates new user and sends email when given email is new' do + starting_profile_count = User.count post "/v1/new_club_applications/#{club_application.id}/add_applicant", headers: auth_headers, @@ -285,41 +285,41 @@ expect(response.status).to eq(200) expect(json).to include('success' => true) - # new applicant created and added to application - expect(Applicant.count).to eq(starting_applicant_count + 1) + # new user created and added to application + expect(User.count).to eq(starting_profile_count + 1) expect( - club_application.applicants.find_by(email: 'john@johnsmith.com') + club_application.users.find_by(email: 'john@johnsmith.com') ).to_not be_nil # email sent expect(ApplicantMailer.deliveries.length).to be(1) end - it 'adds existing applicant and sends email when given email is not new' do - new_applicant = create(:applicant) - starting_applicant_count = Applicant.count + it 'adds existing user and sends email when given email is not new' do + new_user = create(:user) + starting_profile_count = User.count post "/v1/new_club_applications/#{club_application.id}/add_applicant", headers: auth_headers, - params: { email: new_applicant.email } + params: { email: new_user.email } expect(response.status).to eq(200) expect(json).to include('success' => true) - # no new applicants created - expect(starting_applicant_count).to eq(Applicant.count) + # no new users created + expect(starting_profile_count).to eq(User.count) - # applicant successfully added to application - expect(club_application.applicants).to include(new_applicant) + # user successfully added to application + expect(club_application.users).to include(new_user) # email sent expect(ApplicantMailer.deliveries.length).to be(1) end it 'rehydrates applicant profile when one was previously deleted' do - to_readd = create(:applicant) + to_readd = create(:user) to_rehydrate = create(:applicant_profile, - applicant: to_readd, + user: to_readd, new_club_application: club_application) to_rehydrate.update_attributes(leader_name: 'Jerry') to_rehydrate.destroy @@ -333,18 +333,18 @@ # successfully rehydrated expect(ApplicantProfile.find_by( - applicant: to_readd, + user: to_readd, new_club_application: club_application ).leader_name).to eq('Jerry') end - it 'fails when applicant has already been added' do - new_applicant = create(:applicant) - club_application.applicants << new_applicant + it 'fails when user has already been added' do + new_user = create(:user) + club_application.users << new_user post "/v1/new_club_applications/#{club_application.id}/add_applicant", headers: auth_headers, - params: { email: new_applicant.email } + params: { email: new_user.email } expect(response.status).to eq(422) expect(json['errors']['email']).to include('already added') @@ -353,8 +353,8 @@ it 'fails when application has been submitted' do application = create(:completed_new_club_application) create(:completed_applicant_profile, - new_club_application: application, applicant: applicant) - application.update_attributes(point_of_contact: applicant) + new_club_application: application, user: user) + application.update_attributes(point_of_contact: user) post "/v1/new_club_applications/#{application.id}/submit", headers: auth_headers @@ -374,14 +374,14 @@ let(:application) { create(:completed_new_club_application) } before do - create(:completed_applicant_profile, applicant: applicant, + create(:completed_applicant_profile, user: user, new_club_application: application) - application.update_attributes(point_of_contact: applicant) + application.update_attributes(point_of_contact: user) end it 'requires authentication' do delete "/v1/new_club_applications/#{application.id}/remove_applicant", - params: { applicant_id: applicant.id } + params: { user_id: user.id } expect(response.status).to eq(401) end @@ -389,21 +389,21 @@ it '404s when application does not exist' do delete "/v1/new_club_applications/#{application.id + 1}/remove_applicant", headers: auth_headers, - params: { applicant_id: applicant.id } + params: { user_id: user.id } expect(response.status).to eq(404) expect(json['error']).to eq('not found') end - it 'fails to delete from club applications of other applicants' do + it 'fails to delete from club applications of other users' do other_app = create(:new_club_application) - other_applicant = create(:applicant) + other_user = create(:user) - other_app.applicants << other_applicant + other_app.users << other_user delete "/v1/new_club_applications/#{other_app.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: other_applicant.id } + params: { user_id: other_user.id } expect(response.status).to eq(403) expect(json['error']).to eq('access denied') @@ -411,11 +411,11 @@ it 'fails to delete if not point of contact' do application.update_attributes(point_of_contact: nil) - other_applicant = create(:applicant, new_club_applications: [application]) + other_user = create(:user, new_club_applications: [application]) delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: other_applicant.id } + params: { user_id: other_user.id } expect(response.status).to eq(403) expect(json['error']).to eq('access denied') @@ -424,42 +424,42 @@ it 'fails to delete self' do delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: applicant.id } + params: { user_id: user.id } expect(response.status).to eq(422) - expect(json['errors']['applicant_id']).to include('cannot remove self') + expect(json['errors']['user_id']).to include('cannot remove self') end - it '404s when applicant does not exist' do + it '404s when user does not exist' do delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: applicant.id + 100 } + params: { user_id: user.id + 100 } expect(response.status).to eq(404) expect(json['error']).to eq('not found') end - it 'fails to delete applicants already deleted' do - other_applicant = create(:applicant, new_club_applications: [application]) + it 'fails to delete users already deleted' do + other_user = create(:user, new_club_applications: [application]) 2.times do delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: other_applicant.id } + params: { user_id: other_user.id } end expect(response.status).to eq(422) expect( - json['errors']['applicant_id'] + json['errors']['user_id'] ).to include('not added to application') end - it 'fails to delete applicant when application is submitted' do + it 'fails to delete user when application is submitted' do application.submit! delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: application.applicants.last.id } + params: { user_id: application.users.last.id } expect(response.status).to eq(422) expect( @@ -470,21 +470,21 @@ it 'successfully deletes if point of contact' do delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: application.applicants.last.id } + params: { user_id: application.users.last.id } expect(response.status).to eq(200) expect(json).to include('success' => true) end it 'preserves profile data on deletion' do - to_delete = application.applicants.last + to_delete = application.users.last delete "/v1/new_club_applications/#{application.id}/remove_applicant", headers: auth_headers, - params: { applicant_id: to_delete.id } + params: { user_id: to_delete.id } deleted_profile = ApplicantProfile.with_deleted.find_by( - applicant: applicant, + user: user, new_club_application: application ) @@ -495,23 +495,23 @@ describe 'POST /v1/new_club_applications/:id/submit' do let(:application) do create(:completed_new_club_application, - applicant_count: 0) + profile_count: 0) end - # add our applicant w/ a completed profile + # add our user w/ a completed profile let!(:profile) do create( :completed_applicant_profile, - applicant: applicant, new_club_application: application + user: user, new_club_application: application ) end # and make them the point of contact - before { application.update_attributes(point_of_contact: applicant) } + before { application.update_attributes(point_of_contact: user) } let(:application) do create(:completed_new_club_application, - applicant_count: 0) + profile_count: 0) end it 'requires authentication' do diff --git a/api/spec/requests/v1/applicants_spec.rb b/api/spec/requests/v1/users_spec.rb similarity index 52% rename from api/spec/requests/v1/applicants_spec.rb rename to api/spec/requests/v1/users_spec.rb index 51582effd..b2a7a8799 100644 --- a/api/spec/requests/v1/applicants_spec.rb +++ b/api/spec/requests/v1/users_spec.rb @@ -2,17 +2,17 @@ require 'rails_helper' -RSpec.describe 'V1::Applicants', type: :request do - describe 'POST /v1/applicants/auth' do +RSpec.describe 'V1::Users', type: :request do + describe 'POST /v1/users/auth' do it 'fails with an invalid email' do - post '/v1/applicants/auth', params: { email: 'bad_email' } + post '/v1/users/auth', params: { email: 'bad_email' } expect(response.status).to eq(422) expect(json['errors']).to include('email') end it 'creates new object and sends email with new and valid email' do - post '/v1/applicants/auth', params: { email: 'foo@bar.com' } + post '/v1/users/auth', params: { email: 'foo@bar.com' } expect(response.status).to eq(200) @@ -27,40 +27,40 @@ # but not secret fields expect(json).to_not include('auth_token') - # creates applicant object w/ generated login code - applicant = Applicant.last - expect(applicant.email).to eq('foo@bar.com') - expect(applicant.login_code).to match(/\d{6}/) + # creates user object w/ generated login code + user = User.last + expect(user.email).to eq('foo@bar.com') + expect(user.login_code).to match(/\d{6}/) # email queued to be sent expect(ApplicantMailer.deliveries.length).to be(1) end it 'does not create object but sends login code with existing email' do - # init applicant - applicant = create(:applicant) - applicant.generate_login_code! - applicant.save + # init user + user = create(:user) + user.generate_login_code! + user.save - post '/v1/applicants/auth', params: { email: applicant.email } + post '/v1/users/auth', params: { email: user.email } expect(response.status).to eq(200) # returns existing object - expect(json).to include('email' => applicant.email) - expect(json).to include('id' => applicant.id) + expect(json).to include('email' => user.email) + expect(json).to include('id' => user.id) # generates new login code - expect(applicant.login_code).to_not eq(applicant.reload.login_code) + expect(user.login_code).to_not eq(user.reload.login_code) # queued email expect(ApplicantMailer.deliveries.length).to be(1) end end - describe 'POST /v1/applicants/:id/exchange_login_code' do - let(:applicant) do - a = create(:applicant) + describe 'POST /v1/users/:id/exchange_login_code' do + let(:user) do + a = create(:user) a.generate_login_code! a.save @@ -68,8 +68,8 @@ end it 'returns auth token with valid login code' do - post "/v1/applicants/#{applicant.id}/exchange_login_code", - params: { login_code: applicant.login_code } + post "/v1/users/#{user.id}/exchange_login_code", + params: { login_code: user.login_code } expect(response.status).to eq(200) @@ -77,14 +77,14 @@ end it 'return error with no login code' do - post "/v1/applicants/#{applicant.id}/exchange_login_code" + post "/v1/users/#{user.id}/exchange_login_code" expect(response.status).to eq(401) expect(json['errors']).to include('login_code') end it 'returns error with invalid login code' do - post "/v1/applicants/#{applicant.id}/exchange_login_code", + post "/v1/users/#{user.id}/exchange_login_code", params: { login_code: '000111' } expect(response.status).to eq(401) @@ -93,43 +93,43 @@ it 'fails when valid login code is used twice' do # 1st time.. - post "/v1/applicants/#{applicant.id}/exchange_login_code", - params: { login_code: applicant.login_code } + post "/v1/users/#{user.id}/exchange_login_code", + params: { login_code: user.login_code } # 2nd time... - post "/v1/applicants/#{applicant.id}/exchange_login_code", - params: { login_code: applicant.login_code } + post "/v1/users/#{user.id}/exchange_login_code", + params: { login_code: user.login_code } expect(response.status).to eq(401) expect(json['errors']).to include('login_code') end it 'does not allow login codes older than 15 minutes' do - applicant.login_code_generation -= 15.minutes - applicant.save + user.login_code_generation -= 15.minutes + user.save - post "/v1/applicants/#{applicant.id}/exchange_login_code", - params: { login_code: applicant.login_code } + post "/v1/users/#{user.id}/exchange_login_code", + params: { login_code: user.login_code } expect(response.status).to eq(401) expect(json['errors']).to include('login_code') end it 'does not allow login codes for other users' do - other_applicant = create(:applicant) - other_applicant.generate_login_code! - other_applicant.save + other_user = create(:user) + other_user.generate_login_code! + other_user.save - post "/v1/applicants/#{applicant.id}/exchange_login_code", - params: { login_code: other_applicant.login_code } + post "/v1/users/#{user.id}/exchange_login_code", + params: { login_code: other_user.login_code } expect(response.status).to eq(401) expect(json['errors']).to include('login_code') end - it '404s when applicant id does not exist' do - post "/v1/applicants/#{applicant.id + 1}/exchange_login_code", - params: { login_code: applicant.login_code } + it '404s when user id does not exist' do + post "/v1/users/#{user.id + 1}/exchange_login_code", + params: { login_code: user.login_code } expect(response.status).to eq(404) expect(json).to include('error' => 'not found')