From 6266f5af025eba4ca1ed4bf69d929c3b68e19219 Mon Sep 17 00:00:00 2001 From: Peter Kos Date: Sat, 29 Aug 2020 23:38:17 -0400 Subject: [PATCH] refactor: `first_name` and `last_name` move from `questionnaire` to `user` (#241) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial move: first/last name; user->quesitonnaire - Models adjusted - Migration made (needs to be updated to a MOVE, not a delete) - Updated SOME tests and factories - Create account works * refactor: Attempt to fix backend params Includes fixing any discrepancies on routes like `/manage` * refactor: Make HoundBot a little happier * feat: Admin list shows first/last names * inprog on stats page - Actually retreive first/last names on questionnaires page * Refactored stats datatable and controller - Checkin datatable also tweaked to work. - Removed resumes; #244 * Migration is now backwards compatible with pre-2.0 Needs to be added to 2.0 migration guide! * 4space->2space :rage: #downwith2spaces * Fix various first_name/last_name bugs Most annoying one is in the questionnaire edit screen... * Fixed remainder of tests for name refactor * Fix datatable style and count ranges * Fix some more style bugs * Viewing bus list w/ passengers now works * Adds Users & Staff support for #222 * Adds #222 support to stats, fixes stats layout * Fixes Hound issues * Removes Hound whitespace issues * History audit bugfix No longer nil as we don’t check the type of the previous history and just show both, risking a nil visible on the questionnaire page if value is set for the first time * Add nil check back, whoops. This works better. * Squashed commit of the following: commit 4d1b4e2de1fbc261b37649f97330768538f54fc0 Author: Chris Baudouin, Jr Date: Wed Jul 1 01:08:19 2020 -0400 Back merge master (#273) * fix(dashboard): Fixes security vulnerability that allowed event_tracking role to access Dashboard (#215) * chore(release): 1.22.3 [skip ci] ## [1.22.3](https://github.com/codeRIT/hackathon-manager/compare/v1.22.2...v1.22.3) (2020-05-16) ### Bug Fixes * **dashboard:** Fixes security vulnerability that allowed event_tracking role to access Dashboard ([#215](https://github.com/codeRIT/hackathon-manager/issues/215)) ([](https://github.com/codeRIT/hackathon-manager/commit/74a40ad)) ### Styles * **check-in:** Changes table header to be more descriptive ([#207](https://github.com/codeRIT/hackathon-manager/issues/207)) ([](https://github.com/codeRIT/hackathon-manager/commit/889fbd0)) * **config:** Removes unused event_is_over flag ([#208](https://github.com/codeRIT/hackathon-manager/issues/208)) ([](https://github.com/codeRIT/hackathon-manager/commit/0c73e66)) * build(deps): Upgrade yarn (#212) * build(deps): Upgrade yarn * build(deps): Upgrade gems * build(deps): Remove obsolete gems * v0.0.0 * build(deps): Update semantic-release * fix(questionnaire): visual bug in school autocomplete school dropdown the css was set for an "a" tag when the list was made up of divs so I switched the css to work for the "div" tag in the autocomplete * fix(questionnaire): visual bug in school autocomplete school dropdown the css was set for an "a" tag when the list was made up of divs so I switched the css to work for the "div" tag in the autocomplete. I also hide a element that was not present earlier * build(deps): Upgrades Rails to 5.2.4.3 * build(deps): Upgrades gems Co-authored-by: Jeremy Rudman * build(deps): Bump puma from 4.3.4 to 4.3.5 (#219) Bumps [puma](https://github.com/puma/puma) from 4.3.4 to 4.3.5. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): Upgrades Puma cache (#221) * fix(questionnaire): Fixes error when trying to view a questionnaire modified by a deleted admin (#236) * chore(release): 1.22.4 [skip ci] ## [1.22.4](https://github.com/codeRIT/hackathon-manager/compare/v1.22.3...v1.22.4) (2020-05-26) ### Bug Fixes * **questionnaire:** Fixes error when trying to view a questionnaire modified by a deleted admin ([#236](https://github.com/codeRIT/hackathon-manager/issues/236)) ([](https://github.com/codeRIT/hackathon-manager/commit/2ffe116)) * build(deps): Bump websocket-extensions from 0.1.4 to 0.1.5 (#250) * build(deps): Bump websocket-extensions from 0.1.4 to 0.1.5 Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-ruby) from 0.1.4 to 0.1.5. - [Release notes](https://github.com/faye/websocket-extensions-ruby/releases) - [Changelog](https://github.com/faye/websocket-extensions-ruby/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-ruby/compare/0.1.4...0.1.5) Signed-off-by: dependabot[bot] * build(deps): Updates websocket-extensions gem cache Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chris Baudouin, Jr * build(deps): Bump rack from 2.2.2 to 2.2.3 (#268) * build(deps): Bump rack from 2.2.2 to 2.2.3 Bumps [rack](https://github.com/rack/rack) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/rack/rack/releases) - [Changelog](https://github.com/rack/rack/blob/master/CHANGELOG.md) - [Commits](https://github.com/rack/rack/compare/v2.2.2...2.2.3) Signed-off-by: dependabot[bot] * Adds rack gem cache Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Chris Baudouin, Jr Co-authored-by: semantic-release-bot Co-authored-by: Jeremy Rudman Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Peter Kos commit 513e1c29b7d3c2a0ba343b31b18c661370677068 Author: Chris Baudouin, Jr Date: Tue Jun 30 18:45:42 2020 -0400 fix(login): Removes always visible login error (#263) * fix(login): Removes always visible login error * Fixes Hound spacing requirement commit 58601a146cf725e4bb0518fff3b8105734d5e273 Author: Chris Baudouin, Jr Date: Sun Jun 28 19:16:08 2020 -0400 build(deps): Updates gems (#275) commit d1a01f81d03033b9a4f9346750be4d8b1f43ab19 Author: Peter Kos Date: Sat Jun 20 19:26:53 2020 -0400 docs: Add guide for local API setup, update api-usage slightly (#235) * docs: Add API/OAuth 2 setup guide Also rename api to api-usage * docs: Cleanup api-usage page, add notes about 2.0 * docs: Apply suggestions from code review Co-authored-by: Stuart Olivera * docs: Reword API introduction to be more friendly - Clarifies what Postman and Paw are, with links to their product pages - Notes that this process works for remote instances as well, not just localhost - Removed trailing whitespace and extra newlines - Fixed a single typo * Verbiage and HM typo fixes * Added .DS_Store to .gitignore Co-authored-by: Stuart Olivera commit 82a7ff4484442e14926347fe07145d4881ace009 Author: Chris Baudouin, Jr Date: Thu Jun 18 08:58:35 2020 -0400 fix(config): Removes disable_account_registration from database (#247) * fix(config): Removes disable_account_registration from database * fix(config): Saves new config item, adds extra precautionary check commit f07ec280098abbfcc953eea3ab7a2362be8cfb41 Author: Chris Baudouin, Jr Date: Thu Jun 11 17:35:16 2020 -0400 fix(questionnaire): Fixes error when trying to view a questionnaire modified by a deleted admin (#238) * fix(dashboard): Fixes security vulnerability that allowed event_tracking role to access Dashboard (#215) * chore(release): 1.22.3 [skip ci] ## [1.22.3](https://github.com/codeRIT/hackathon-manager/compare/v1.22.2...v1.22.3) (2020-05-16) ### Bug Fixes * **dashboard:** Fixes security vulnerability that allowed event_tracking role to access Dashboard ([#215](https://github.com/codeRIT/hackathon-manager/issues/215)) ([](https://github.com/codeRIT/hackathon-manager/commit/74a40ad)) ### Styles * **check-in:** Changes table header to be more descriptive ([#207](https://github.com/codeRIT/hackathon-manager/issues/207)) ([](https://github.com/codeRIT/hackathon-manager/commit/889fbd0)) * **config:** Removes unused event_is_over flag ([#208](https://github.com/codeRIT/hackathon-manager/issues/208)) ([](https://github.com/codeRIT/hackathon-manager/commit/0c73e66)) * build(deps): Upgrade yarn (#212) * build(deps): Upgrade yarn * build(deps): Upgrade gems * build(deps): Remove obsolete gems * v0.0.0 * build(deps): Update semantic-release * fix(questionnaire): visual bug in school autocomplete school dropdown the css was set for an "a" tag when the list was made up of divs so I switched the css to work for the "div" tag in the autocomplete * fix(questionnaire): visual bug in school autocomplete school dropdown the css was set for an "a" tag when the list was made up of divs so I switched the css to work for the "div" tag in the autocomplete. I also hide a element that was not present earlier * build(deps): Upgrades Rails to 5.2.4.3 * build(deps): Upgrades gems Co-authored-by: Jeremy Rudman * build(deps): Bump puma from 4.3.4 to 4.3.5 (#219) Bumps [puma](https://github.com/puma/puma) from 4.3.4 to 4.3.5. - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): Upgrades Puma cache (#221) * fix(questionnaire): Fixes error when trying to view a questionnaire modified by a deleted admin * refactor(tests): Cleans verbage of tests to match Co-authored-by: semantic-release-bot Co-authored-by: Jeremy Rudman Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix undefined err on bus list info * Fix bus captain bug, update schema * Squashed commit of the following: commit ede300f2c1bf1c426ca0f69cfe4def0353a8b358 Author: Chris Baudouin, Jr Date: Sat Aug 29 21:05:53 2020 -0400 feat: Updates MyMLH to V3 (#329) * feat: Updates MyMLH to V3 * fix(User): Adds missing provider field * refactor: Updates MyMLH branding * Autofill MyMLH provider if info is missing * houndbot Co-authored-by: Peter Kos commit 675b3f63f234de86ad56fbb19f283624b8715706 Author: Chris Baudouin, Jr Date: Sun Aug 23 22:43:48 2020 -0400 refactor: Changes "Applications" to "Questionnaires" in map (#326) commit 388c9bd14b22c1cbbb07e1e1e2443b841b7cb069 Author: Chris Baudouin, Jr Date: Sun Aug 23 22:08:26 2020 -0400 fix(Dashboard): Fixes missing location data in map (#324) commit a062140ab50d1b2c4ef50f33865dd8852d14bff5 Author: Chris Baudouin, Jr Date: Wed Aug 19 11:02:07 2020 -0400 feat(docs): Initial documentation for 2.0 (#291) * feat(docs): Initial documentation for 2.0 * refactor: Updates maintenance.md for verbage changes * refactor: Refactors structure of navigation commit 79831f67be52e9ebcaeebdaef8eec530b4a6c121 Author: JeremyRudman <38338616+JeremyRudman@users.noreply.github.com> Date: Sat Jul 25 12:47:35 2020 -0400 feat(messages): Adds a confirmation modal to send messages (#272) * feat(message): added a confirmation modal to send messages added a modal for when you send a message that displays the number of people you are sending it to in large red text. * fix: houndci formatting errors * fix(messages): fixed error and made changes to text made "send message" singular and made only the the number red. I also fixed the variable not loading properly * fix: houndci styling changes * feat: made email modal text black instead of red the email confirmation modal displays the number in black instead of red * refactor: Adds number delimiter to recipients, changes cancel outline Co-authored-by: Chris Baudouin, Jr commit e4169a77f864a04875543e16562a8b701cde3b71 Author: JeremyRudman <38338616+JeremyRudman@users.noreply.github.com> Date: Thu Jul 9 00:39:23 2020 -0400 fix(questionnaire): School autocomplete matches form field width (#278) * fix(questionnaire): school autocomplete matchs fourm field width * fix(questionnaires): added ellipsis to autocomplete when the forum field is smaller the school name the autocomplete goes beyond the width the field and this causes the text to ellipsis in thet case * Actually assign current_user * mymlh working * Refactor questionnnaire new to be nicer to read * Patch condition error for info refactor Was attempting to use potentially nil value before checking if the value was nil ALso cleaned up part of the test in questionnaires controler to create the entire user object as we need both first/last name, as well as email. #goodcodestyle #pleasehiremegoogle Co-authored-by: Chris Baudouin, Jr Co-authored-by: Chris Baudouin, Jr --- .../javascripts/manage/lib/setupDataTables.js | 88 ++++++++++-- .../manage/bus_lists_controller.rb | 4 +- .../manage/questionnaires_controller.rb | 14 +- app/controllers/manage/stats_controller.rb | 134 ++---------------- app/controllers/manage/users_controller.rb | 2 +- app/controllers/questionnaires_controller.rb | 15 +- .../users/registrations_controller.rb | 25 ++-- app/datatables/admin_datatable.rb | 7 +- app/datatables/alt_travel_datatable.rb | 45 ++++++ .../attendee_sponsor_info_datatable.rb | 44 ++++++ app/datatables/checkin_datatable.rb | 10 +- .../dietary_special_needs_datatable.rb | 50 +++++++ app/datatables/mlh_applied_datatable.rb | 38 +++++ app/datatables/mlh_checked_in_datatable.rb | 40 ++++++ app/datatables/questionnaire_datatable.rb | 10 +- app/datatables/user_datatable.rb | 5 + app/models/bus_list.rb | 2 +- app/models/questionnaire.rb | 6 +- app/models/user.rb | 26 ++-- .../application/_bus_list_info.html.haml | 2 +- .../_questionnaire_summary.html.haml | 4 +- app/views/bus_lists/show.html.haml | 4 +- .../devise/registrations/_form.html.haml | 4 +- app/views/manage/admins/_form.html.haml | 0 app/views/manage/admins/index.html.haml | 0 .../application/_model_history.html.haml | 2 +- app/views/manage/bus_lists/show.html.haml | 4 +- app/views/manage/checkins/show.html.haml | 4 +- .../manage/questionnaires/_form.html.haml | 5 +- .../manage/questionnaires/_overview.html.haml | 4 +- .../manage/questionnaires/edit.html.haml | 4 +- .../manage/questionnaires/show.html.haml | 4 +- app/views/manage/stats/index.html.haml | 34 +++-- app/views/manage/users/index.html.haml | 6 + app/views/questionnaires/_form.html.haml | 2 - config/locales/en.yml | 4 +- config/routes.rb | 10 +- ...r_info_from_questionnaire_to_user_model.rb | 61 ++++++++ db/schema.rb | 6 +- .../manage/questionnaires_controller_test.rb | 103 ++++++++------ .../manage/stats_controller_test.rb | 2 +- .../questionnaires_controller_test.rb | 24 ++-- test/controllers/rsvps_controller_test.rb | 2 +- test/factories/questionnaire.rb | 2 - test/factories/users.rb | 2 + test/helpers/audit_helper_test.rb | 4 +- test/models/message_test.rb | 4 +- test/models/questionnaire_test.rb | 13 +- test/models/user_test.rb | 39 +---- 49 files changed, 584 insertions(+), 340 deletions(-) create mode 100644 app/datatables/alt_travel_datatable.rb create mode 100644 app/datatables/attendee_sponsor_info_datatable.rb create mode 100644 app/datatables/dietary_special_needs_datatable.rb create mode 100644 app/datatables/mlh_applied_datatable.rb create mode 100644 app/datatables/mlh_checked_in_datatable.rb create mode 100644 app/views/manage/admins/_form.html.haml create mode 100644 app/views/manage/admins/index.html.haml create mode 100644 db/migrate/20200525234832_move_user_info_from_questionnaire_to_user_model.rb diff --git a/app/assets/javascripts/manage/lib/setupDataTables.js b/app/assets/javascripts/manage/lib/setupDataTables.js index 2b04d7975..ad23dfdf8 100644 --- a/app/assets/javascripts/manage/lib/setupDataTables.js +++ b/app/assets/javascripts/manage/lib/setupDataTables.js @@ -17,10 +17,13 @@ var setupDataTables = function () { }); $('.datatable.users').DataTable({ - order: [5, 'desc'], + order: [8, 'desc'], columns: [ { orderable: true, data: 'id', visible: false }, - { orderable: true, data: 'email' }, + { orderable: false, data: 'link' }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email', visible: false }, { orderable: true, data: 'role' }, { orderable: false, data: 'questionnaire'}, { orderable: true, data: 'active' }, @@ -34,15 +37,18 @@ var setupDataTables = function () { }); $('.datatable.admins').DataTable({ - order: [1, 'asc'], + order: [2, 'asc'], columns: [ { orderable: true, data: 'id', visible: false }, - { orderable: true, data: 'email' }, + { orderable: false, data: 'link' }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email', visible: false }, { orderable: true, data: 'role' }, { orderable: true, data: 'active' }, { orderable: true, data: 'receive_weekly_report' }, - { orderable: true, data: 'created_at' }, - { orderable: true, data: 'current_sign_in_at' }, + { orderable: true, data: 'created_at', visible: false }, + { orderable: true, data: 'current_sign_in_at', visible: false }, { orderable: true, data: 'last_sign_in_at', visible: false }, { orderable: true, data: 'current_sign_in_ip', visible: false }, { orderable: true, data: 'last_sign_in_ip', visible: false }, @@ -75,8 +81,72 @@ var setupDataTables = function () { ], }); - $('.datatable.stats').DataTable({ - processing: false, - serverSide: false, + // MARK: Datatables for the stats + + $('.datatable.stats-dietary').DataTable({ + order: [1, 'asc'], + columns: [ + { orderable: true, data: 'id', visible: false }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email' }, + { orderable: true, data: 'phone', visible: false }, + { orderable: false, data: 'questionnaire' }, + { orderable: true, data: 'checked_in_at', visible: false }, + { orderable: true, data: 'dietary_restrictions' }, + { orderable: true, data: 'special_needs' } + ] + }); + + $('.datatable.stats-notschooltravel').DataTable({ + order: [1, 'asc'], + columns: [ + { orderable: true, data: 'id', visible: false }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email' }, + { orderable: true, data: 'phone', visible: false }, + { orderable: false, data: 'questionnaire' }, + { orderable: true, data: 'travel_location' }, + { orderable: true, data: 'acc_status' } + ] }); + + $('.datatable.stats-attendeeinfo').DataTable({ + columns: [ + { orderable: true, data: 'id', visible: false }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email' }, + { orderable: true, data: 'school_name' }, + { orderable: true, data: 'vcs_url' }, + { orderable: true, data: 'portfolio_url' } + ] + }); + + $('.datatable.stats-mlhinfo-applied').DataTable({ + order: [1, 'asc'], + columns: [ + { orderable: true, data: 'id', visible: false }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email' }, + { orderable: true, data: 'phone', visible: false }, + { orderable: true, data: 'school_name' } + ] + }); + + $('.datatable.stats-mlhinfo-checkedin').DataTable({ + order: [1, 'asc'], + columns: [ + { orderable: true, data: 'id', visible: false }, + { orderable: true, data: 'first_name' }, + { orderable: true, data: 'last_name' }, + { orderable: true, data: 'email' }, + { orderable: true, data: 'phone' }, + { orderable: true, data: 'school_name' } + ] + }); + + }; diff --git a/app/controllers/manage/bus_lists_controller.rb b/app/controllers/manage/bus_lists_controller.rb index a6cb83807..5307fea5a 100644 --- a/app/controllers/manage/bus_lists_controller.rb +++ b/app/controllers/manage/bus_lists_controller.rb @@ -44,10 +44,10 @@ def toggle_bus_captain is_bus_captain = params[:bus_captain] == "1" @questionnaire.update_attribute(:is_bus_captain, is_bus_captain) if @questionnaire.reload.is_bus_captain - flash[:notice] = "#{@questionnaire.full_name} has been promoted to a bus captain." + flash[:notice] = "#{@questionnaire.user.full_name} has been promoted to a bus captain." Message.queue_for_trigger("bus_list.new_captain_confirmation", @questionnaire.user.id) else - flash[:notice] = "#{@questionnaire.full_name} has been removed as a bus captain." + flash[:notice] = "#{@questionnaire.user.full_name} has been removed as a bus captain." end redirect_to [:manage, @bus_list] end diff --git a/app/controllers/manage/questionnaires_controller.rb b/app/controllers/manage/questionnaires_controller.rb index 3e31de6a7..0aa9577e1 100644 --- a/app/controllers/manage/questionnaires_controller.rb +++ b/app/controllers/manage/questionnaires_controller.rb @@ -51,6 +51,12 @@ def create def update update_params = questionnaire_params email = update_params.delete(:email) + # Take our nested user object out as a whole + user_params = params[:questionnaire][:user] + if user_params + @questionnaire.user.update_attributes(first_name: user_params[:first_name]) + @questionnaire.user.update_attributes(last_name: user_params[:last_name]) + end @questionnaire.user.update_attributes(email: email) if email.present? update_params = convert_school_name_to_id(update_params) update_params = convert_boarded_bus_param(update_params, @questionnaire) @@ -76,11 +82,11 @@ def check_in end @questionnaire.update_attribute(:checked_in_at, Time.now) @questionnaire.update_attribute(:checked_in_by_id, current_user.id) - flash[:notice] = "Checked in #{@questionnaire.full_name}." + flash[:notice] = "Checked in #{@questionnaire.user.full_name}." elsif params[:check_in] == "false" @questionnaire.update_attribute(:checked_in_at, nil) @questionnaire.update_attribute(:checked_in_by_id, current_user.id) - flash[:notice] = "#{@questionnaire.full_name} no longer checked in." + flash[:notice] = "#{@questionnaire.user.full_name} no longer checked in." else flash[:alert] = "No check-in action provided!" redirect_to show_redirect_path @@ -147,8 +153,10 @@ def message_events private def questionnaire_params + # Note that this ONLY considers parameters for the questionnaire, not the user. + # TODO: Refactor "email" out to user as first_name and last_name were params.require(:questionnaire).permit( - :email, :experience, :first_name, :last_name, :gender, + :email, :experience, :gender, :date_of_birth, :interest, :school_id, :school_name, :major, :level_of_study, :shirt_size, :dietary_restrictions, :special_needs, :international, :portfolio_url, :vcs_url, :agreement_accepted, :bus_captain_interest, diff --git a/app/controllers/manage/stats_controller.rb b/app/controllers/manage/stats_controller.rb index c4958d6cf..459285f71 100644 --- a/app/controllers/manage/stats_controller.rb +++ b/app/controllers/manage/stats_controller.rb @@ -1,137 +1,25 @@ class Manage::StatsController < Manage::ApplicationController - def index - end - def dietary_special_needs - data = Rails.cache.fetch(cache_key_for_questionnaires("dietary_special_needs")) do - select_attributes = [ - :first_name, - :last_name, - :phone, - :checked_in_at, - :dietary_restrictions, - :special_needs, - :user_id - ] - json_attributes = [ - :first_name, - :last_name, - :email, - :phone, - :checked_in_at, - :dietary_restrictions, - :special_needs - ] - data = Questionnaire.where("dietary_restrictions != '' AND acc_status = 'rsvp_confirmed' OR special_needs != '' AND acc_status = 'rsvp_confirmed'").select(select_attributes) - to_json_array(data, json_attributes) - end - render json: { data: data } - end + respond_to :html, :json - def sponsor_info - data = Rails.cache.fetch(cache_key_for_questionnaires("sponsor_info")) do - select_attributes = [ - :id, - :first_name, - :last_name, - :vcs_url, - :portfolio_url, - :user_id, - :school_id - ] - json_attributes = [ - :first_name, - :last_name, - :email, - :school_name, - :vcs_url, - :portfolio_url - ] - data = Questionnaire.where("can_share_info = '1' AND checked_in_at != 0").joins(:resume_attachment).select(select_attributes) - json = to_json_array(data, json_attributes) - json.map.with_index { |item, index| item.insert(6, data[index].resume.attached? ? url_for(data[index].resume) : '') } - end - render json: { data: data } + def dietary_restrictions_special_needs_datatable + render json: DietarySpecialNeedsDatatable.new(params, view_context: view_context) end - def alt_travel - data = Rails.cache.fetch(cache_key_for_questionnaires("alt_travel")) do - select_attributes = [ - :id, - :first_name, - :last_name, - :travel_location, - :acc_status, - :user_id, - :school_id - ] - json_attributes = [ - :id, - :first_name, - :last_name, - :email, - :travel_location, - :acc_status - ] - data = Questionnaire.where("travel_not_from_school = '1'").select(select_attributes) - json = to_json_array(data, json_attributes) - json.each do |e| - e[0] = view_context.link_to("View »".html_safe, manage_questionnaire_path(e[0])) - end - end - render json: { data: data } + def alt_travel_datatable + render json: AltTravelDatatable.new(params, view_context: view_context) end - def mlh_info_applied - data = Rails.cache.fetch(cache_key_for_questionnaires("mlh_info_applied")) do - select_attributes = [ - :first_name, - :last_name, - :user_id, - :school_id - ] - json_attributes = [ - :first_name, - :last_name, - :email, - :school_name - ] - data = Questionnaire.joins(:school).select(select_attributes) - to_json_array(data, json_attributes) - end - render json: { data: data } + def attendee_sponsor_info_datatable + render json: AttendeeSponsorInfoDatatable.new(params, view_context: view_context) end - def mlh_info_checked_in - data = Rails.cache.fetch(cache_key_for_questionnaires("mlh_info_checked_in")) do - select_attributes = [ - :first_name, - :last_name, - :user_id, - :school_id - ] - json_attributes = [ - :first_name, - :last_name, - :email, - :school_name - ] - data = Questionnaire.joins(:school).select(select_attributes).where('checked_in_at > 0') - to_json_array(data, json_attributes) - end - render json: { data: data } + def mlh_applied_datatable + render json: MLHAppliedDatatable.new(params, view_context: view_context) end - - private - - def to_json_array(data, attributes) - data.map { |e| attributes.map { |a| e.send(a) } } + def mlh_checked_in_datatable + render json: MLHCheckedInDatatable.new(params, view_context: view_context) end - def cache_key_for_questionnaires(id) - count = Questionnaire.count - max_updated_at = Questionnaire.maximum(:updated_at).try(:utc).try(:to_s, :number) - "stats/all-#{count}-#{max_updated_at}-#{id}" - end end diff --git a/app/controllers/manage/users_controller.rb b/app/controllers/manage/users_controller.rb index c00222e0e..e64fad0e0 100644 --- a/app/controllers/manage/users_controller.rb +++ b/app/controllers/manage/users_controller.rb @@ -38,7 +38,7 @@ def destroy def user_params params.require(:user).permit( - :email, :password, :password_confirmation, :remember_me, :role, :is_active, :receive_weekly_report + :first_name, :last_name, :email, :password, :password_confirmation, :remember_me, :role, :is_active, :receive_weekly_report ) end diff --git a/app/controllers/questionnaires_controller.rb b/app/controllers/questionnaires_controller.rb index e04bfb962..633547842 100644 --- a/app/controllers/questionnaires_controller.rb +++ b/app/controllers/questionnaires_controller.rb @@ -26,15 +26,14 @@ def new @questionnaire = Questionnaire.new if session["devise.provider_data"] && session["devise.provider_data"]["info"] + info = session["devise.provider_data"]["info"] @skip_my_mlh_fields = true @questionnaire.tap do |q| - q.first_name = session["devise.provider_data"]["info"]["first_name"] - q.last_name = session["devise.provider_data"]["info"]["last_name"] - q.phone = session["devise.provider_data"]["info"]["phone_number"] - q.level_of_study = session["devise.provider_data"]["info"]["level_of_study"] - q.major = session["devise.provider_data"]["info"]["major"] - q.date_of_birth = session["devise.provider_data"]["info"]["date_of_birth"] - q.gender = session["devise.provider_data"]["info"]["gender"] + q.phone = info["phone_number"] + q.level_of_study = info["level_of_study"] + q.major = info["major"] + q.date_of_birth = info["date_of_birth"] + q.gender = info["gender"] school = School.where(name: session["devise.provider_data"]["info"]["school"]["name"]).first_or_create do |s| s.name = session["devise.provider_data"]["info"]["school"]["name"] @@ -116,7 +115,7 @@ def schools def questionnaire_params params.require(:questionnaire).permit( - :email, :experience, :first_name, :last_name, :gender, + :email, :experience, :gender, :date_of_birth, :interest, :school_id, :school_name, :major, :level_of_study, :shirt_size, :dietary_restrictions, :special_needs, :international, :portfolio_url, :vcs_url, :agreement_accepted, :bus_captain_interest, diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 011211046..a19263901 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -1,6 +1,6 @@ class Users::RegistrationsController < Devise::RegistrationsController - # before_action :configure_sign_up_params, only: [:create] - # before_action :configure_account_update_params, only: [:update] + before_action :configure_sign_up_params, only: [:create] + before_action :configure_account_update_params, only: [:update] # GET /resource/sign_up def new @@ -28,6 +28,17 @@ def destroy super end + # Permit adding custom parameters for sign up + # (Devise gives us email and password by default, but we want some more.) + def configure_sign_up_params + devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name]) + end + + # Permit updating custom parameters for sign up + def configure_account_update_params + devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name]) + end + # GET /resource/cancel # Forces the session data which is usually expired after sign # in to be expired now. This is useful if the user wants to @@ -39,16 +50,6 @@ def destroy # protected - # You can put the params you want to permit in the empty array. - # def configure_sign_up_params - # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) - # end - - # You can put the params you want to permit in the empty array. - # def configure_account_update_params - # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) - # end - # The path used after sign up. # def after_sign_up_path_for(resource) # super(resource) diff --git a/app/datatables/admin_datatable.rb b/app/datatables/admin_datatable.rb index 16612e8be..d34cb8a61 100644 --- a/app/datatables/admin_datatable.rb +++ b/app/datatables/admin_datatable.rb @@ -4,6 +4,8 @@ class AdminDatatable < ApplicationDatatable def view_columns @view_columns ||= { id: { source: "User.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, email: { source: "User.email" }, role: { source: "User.role", searchable: false }, active: { source: "User.is_active", searchable: false }, @@ -23,7 +25,10 @@ def data records.map do |record| { id: record.id, - email: link_to(bold(record.email), manage_user_path(record)), + link: link_to(''.html_safe, manage_user_path(record)), + first_name: record.first_name, + last_name: record.last_name, + email: record.email, role: record.role.titleize, active: record.is_active ? 'Active'.html_safe : 'Inactive'.html_safe, receive_weekly_report: yes_no_display(record.receive_weekly_report), diff --git a/app/datatables/alt_travel_datatable.rb b/app/datatables/alt_travel_datatable.rb new file mode 100644 index 000000000..1879b80ee --- /dev/null +++ b/app/datatables/alt_travel_datatable.rb @@ -0,0 +1,45 @@ +class AltTravelDatatable < ApplicationDatatable + def_delegators :@view, :link_to, :manage_stats_path, :manage_questionnaire_path, :bold, :display_datetime + + def view_columns + @view_columns ||= { + id: { source: "Questionnaire.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, + email: { source: "User.email" }, + phone: { source: "Questionnaire.phone" }, + travel_location: { source: "Questionnaire.travel_location" }, + acc_status: { source: "Questionnaire.acc_status" } + } + end + + private + + def data + records.map do |record| + { + id: record.id, + first_name: record.user.first_name, + last_name: record.user.last_name, + email: record.user.email, + phone: record.phone, + questionnaire: link_to(bold("View »".html_safe), manage_questionnaire_path(record.id)), + travel_location: record.travel_location, + acc_status: record.acc_status + } + end + end + + def get_raw_records + restrictions = "travel_not_from_school = '1'" + + q_attributes = [ + :id, + :phone, + :travel_location, + :acc_status + ] + + Questionnaire.includes(:user).references(:user).where(restrictions).select(q_attributes) + end +end diff --git a/app/datatables/attendee_sponsor_info_datatable.rb b/app/datatables/attendee_sponsor_info_datatable.rb new file mode 100644 index 000000000..d22e062ce --- /dev/null +++ b/app/datatables/attendee_sponsor_info_datatable.rb @@ -0,0 +1,44 @@ +class AttendeeSponsorInfoDatatable < ApplicationDatatable + def_delegators :@view, :link_to, :manage_stats_path, :manage_questionnaire_path, :bold, :display_datetime + + def view_columns + @view_columns ||= { + id: { source: "Questionnaire.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, + email: { source: "User.email" }, + school_name: { source: "School.name" }, + vcs_url: { source: "Questionnaire.vcs_url" }, + portfolio_url: { source: "Questionnaire.portfolio_url" } + } + end + + private + + def data + records.map do |record| + { + id: record.id, + first_name: record.user.first_name, + last_name: record.user.last_name, + email: record.user.email, + school_name: record.school_name, + vcs_url: record.vcs_url, + portfolio_url: record.portfolio_url + } + end + end + + def get_raw_records + # Condition: only retrieve users that have agreed to share data and are at the event + restrictions = "can_share_info = '1' AND checked_in_at != 0" + + q_attributes = [ + :id, + :vcs_url, + :portfolio_url + ] + + Questionnaire.includes(:user).references(:user).where(restrictions).select(q_attributes) + end +end diff --git a/app/datatables/checkin_datatable.rb b/app/datatables/checkin_datatable.rb index 0b2344382..f3443fe8e 100644 --- a/app/datatables/checkin_datatable.rb +++ b/app/datatables/checkin_datatable.rb @@ -3,8 +3,8 @@ class CheckinDatatable < ApplicationDatatable def view_columns @view_columns ||= { - first_name: { source: "Questionnaire.first_name" }, - last_name: { source: "Questionnaire.last_name" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, checked_in: { source: "Questionnaire.checked_in_at", searchable: false }, } end @@ -13,7 +13,7 @@ def view_columns def about(record) output = "" - output += [record.first_name, record.last_name].join(" ") + " " + output += [record.user.first_name, record.user.last_name].join(" ") + " " output += 'Minor' if record.minor? output += "
" + record.school.name + "" output.html_safe @@ -22,8 +22,8 @@ def about(record) def data records.map do |record| { - first_name: record.first_name, - last_name: record.last_name, + first_name: record.user.first_name, + last_name: record.user.last_name, about: about(record), checked_in: yes_no_display(record.checked_in?), actions: "View".html_safe, diff --git a/app/datatables/dietary_special_needs_datatable.rb b/app/datatables/dietary_special_needs_datatable.rb new file mode 100644 index 000000000..b9f174a66 --- /dev/null +++ b/app/datatables/dietary_special_needs_datatable.rb @@ -0,0 +1,50 @@ +class DietarySpecialNeedsDatatable < ApplicationDatatable + def_delegators :@view, :link_to, :manage_stats_path, :manage_questionnaire_path, :bold, :display_datetime + + def view_columns + @view_columns ||= { + id: { source: "Questionnaire.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, + email: { source: "User.email" }, + phone: { source: "Questionnaire.phone" }, + checked_in_at: { source: "Questionnaire.checked_in_at", searchable: false }, + dietary_restrictions: { source: "Questionnaire.dietary_restrictions" }, + special_needs: { source: "Questionnaire.special_needs" } + } + end + + private + + def data + records.map do |record| + { + id: record.id, + first_name: record.user.first_name, + last_name: record.user.last_name, + email: record.user.email, + phone: record.phone, + questionnaire: link_to(bold("View »".html_safe), manage_questionnaire_path(record.id)), + checked_in_at: record.checked_in_at, + dietary_restrictions: record.dietary_restrictions, + special_needs: record.special_needs + } + end + end + + def get_raw_records + # Condition: only retrieve users that have dietary restrictions or special dietary needs + restrictions = "acc_status = 'rsvp_confirmed' AND "\ + "dietary_restrictions != '' OR special_needs != ''" + + q_attributes = [ + :id, + :phone, + :checked_in_at, + :dietary_restrictions, + :special_needs + ] + + Questionnaire.includes(:user).references(:user).where(restrictions).select(q_attributes) + end +end diff --git a/app/datatables/mlh_applied_datatable.rb b/app/datatables/mlh_applied_datatable.rb new file mode 100644 index 000000000..7da2d25c4 --- /dev/null +++ b/app/datatables/mlh_applied_datatable.rb @@ -0,0 +1,38 @@ +class MLHAppliedDatatable < ApplicationDatatable + def_delegators :@view, :link_to, :manage_stats_path, :bold, :display_datetime + + def view_columns + @view_columns ||= { + id: { source: "Questionnaire.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, + email: { source: "User.email" }, + phone: { source: "Questionnaire.phone" }, + school_name: { source: "School.name" } + } + end + + private + + def data + records.map do |record| + { + id: record.id, + first_name: record.user.first_name, + last_name: record.user.last_name, + email: record.user.email, + phone: record.phone, + school_name: record.school_name + } + end + end + + def get_raw_records + q_attributes = [ + :id, + :phone + ] + + Questionnaire.includes(:user).references(:user).select(q_attributes) + end +end diff --git a/app/datatables/mlh_checked_in_datatable.rb b/app/datatables/mlh_checked_in_datatable.rb new file mode 100644 index 000000000..7524b2c01 --- /dev/null +++ b/app/datatables/mlh_checked_in_datatable.rb @@ -0,0 +1,40 @@ +class MLHCheckedInDatatable < ApplicationDatatable + def_delegators :@view, :link_to, :manage_stats_path, :bold, :display_datetime + + def view_columns + @view_columns ||= { + id: { source: "Questionnaire.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, + email: { source: "User.email" }, + phone: { source: "Questionnaire.phone" }, + school_name: { source: "School.name" } + } + end + + private + + def data + records.map do |record| + { + id: record.id, + first_name: record.user.first_name, + last_name: record.user.last_name, + email: record.user.email, + phone: record.phone, + school_name: record.school_name + } + end + end + + def get_raw_records + restrictions = "checked_in_at > 0" + + q_attributes = [ + :id, + :phone + ] + + Questionnaire.includes(:user).references(:user).where(restrictions).select(q_attributes) + end +end diff --git a/app/datatables/questionnaire_datatable.rb b/app/datatables/questionnaire_datatable.rb index a9abbf6ec..48f04cc8e 100644 --- a/app/datatables/questionnaire_datatable.rb +++ b/app/datatables/questionnaire_datatable.rb @@ -4,8 +4,8 @@ class QuestionnaireDatatable < ApplicationDatatable def view_columns @view_columns ||= { id: { source: "Questionnaire.id", cond: :eq }, - first_name: { source: "Questionnaire.first_name" }, - last_name: { source: "Questionnaire.last_name" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, email: { source: "User.email" }, phone: { source: "Questionnaire.phone" }, gender: { source: "Questionnaire.gender" }, @@ -40,7 +40,7 @@ def bus_captain(record) if record.is_bus_captain? link_to("Remove", toggle_bus_captain_manage_bus_list_path(record.bus_list_id, questionnaire_id: record.id, bus_captain: "0"), method: "post", class: "text-danger") else - link_to("Promote", toggle_bus_captain_manage_bus_list_path(record.bus_list_id, questionnaire_id: record.id, bus_captain: "1"), method: "post", data: { confirm: "Are you sure you want to make #{record.full_name} a bus captain? They will receive a confirmation email." }) + link_to("Promote", toggle_bus_captain_manage_bus_list_path(record.bus_list_id, questionnaire_id: record.id, bus_captain: "1"), method: "post", data: { confirm: "Are you sure you want to make #{record.user.full_name} a bus captain? They will receive a confirmation email." }) end end @@ -51,8 +51,8 @@ def data link: link_to(''.html_safe, manage_questionnaire_path(record)), note: note(record), id: record.id, - first_name: bold(record.first_name), - last_name: bold(record.last_name), + first_name: bold(record.user.first_name), + last_name: bold(record.user.last_name), email: record.email, phone: record.phone, gender: record.gender, diff --git a/app/datatables/user_datatable.rb b/app/datatables/user_datatable.rb index e287155d7..b442700dd 100644 --- a/app/datatables/user_datatable.rb +++ b/app/datatables/user_datatable.rb @@ -4,6 +4,8 @@ class UserDatatable < ApplicationDatatable def view_columns @view_columns ||= { id: { source: "User.id" }, + first_name: { source: "User.first_name" }, + last_name: { source: "User.last_name" }, email: { source: "User.email" }, role: { source: "User.role", searchable: false }, active: { source: "User.is_active", searchable: false }, @@ -22,6 +24,9 @@ def data records.map do |record| { id: record.id, + link: link_to(''.html_safe, manage_user_path(record)), + first_name: record.first_name, + last_name: record.last_name, email: link_to(bold(record.email), manage_user_path(record)), role: record.role.titleize, questionnaire: record.questionnaire.present? ? link_to(bold("View »".html_safe), manage_questionnaire_path(record.questionnaire.id)) : 'None', diff --git a/app/models/bus_list.rb b/app/models/bus_list.rb index c5d8c6036..72c0e549b 100644 --- a/app/models/bus_list.rb +++ b/app/models/bus_list.rb @@ -13,7 +13,7 @@ def full? end def passengers - questionnaires.where("acc_status = 'rsvp_confirmed'").order("last_name ASC") + questionnaires.where("acc_status = 'rsvp_confirmed'") end def schools diff --git a/app/models/questionnaire.rb b/app/models/questionnaire.rb index 0f692613a..f1f48387b 100644 --- a/app/models/questionnaire.rb +++ b/app/models/questionnaire.rb @@ -19,7 +19,7 @@ class Questionnaire < ApplicationRecord validates_uniqueness_of :user_id - validates_presence_of :first_name, :last_name, :phone, :date_of_birth, :school_id, :experience, :shirt_size, :interest + validates_presence_of :phone, :date_of_birth, :school_id, :experience, :shirt_size, :interest validates_presence_of :gender, :major, :level_of_study, :graduation_year, :race_ethnicity validates_presence_of :agreement_accepted, message: "Please read & accept" validates_presence_of :code_of_conduct_accepted, message: "Please read & accept" @@ -145,10 +145,6 @@ def school_name school.name if school_id end - def full_name - "#{first_name} #{last_name}" - end - def full_location "#{school.city}, #{school.state}" end diff --git a/app/models/user.rb b/app/models/user.rb index 939537de6..3b5de0bd2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,7 @@ class User < ApplicationRecord - audited only: [:email, :role, :is_active, :receive_weekly_report] + audited only: [:first_name, :last_name, :email, :role, :is_active, :receive_weekly_report] + + strip_attributes devise :database_authenticatable, :registerable, :timeoutable, :recoverable, :rememberable, :trackable, :validatable, @@ -13,12 +15,15 @@ class User < ApplicationRecord foreign_key: :resource_owner_id, dependent: :delete_all # or :destroy if you need callbacks + accepts_nested_attributes_for :questionnaire + validates_uniqueness_of :email + validates_presence_of :first_name, :last_name after_create :queue_reminder_email + after_initialize :set_default_role, if: :new_record? enum role: { user: 0, event_tracking: 1, admin_limited_access: 2, admin: 3 } - after_initialize :set_default_role, if: :new_record? def set_default_role self.role ||= :user @@ -47,19 +52,8 @@ def safe_receive_weekly_report receive_weekly_report end - def first_name - return "" if questionnaire.blank? - questionnaire.first_name - end - - def last_name - return "" if questionnaire.blank? - questionnaire.last_name - end - def full_name - return email if questionnaire.blank? - questionnaire.full_name + "#{first_name} #{last_name}" end def self.from_omniauth(auth) @@ -67,8 +61,10 @@ def self.from_omniauth(auth) matching_email = where(email: auth.info.email) current_user = matching_provider.or(matching_email).first_or_create do |user| user.uid = auth.uid - user.provider = auth.provider + user.first_name = auth.info.first_name + user.last_name = auth.info.last_name user.email = auth.info.email + user.provider = auth.provider user.password = Devise.friendly_token[0, 20] end # Autofill MyMLH provider if provider info is missing diff --git a/app/views/application/_bus_list_info.html.haml b/app/views/application/_bus_list_info.html.haml index 930f35eb5..82d7ecbc0 100644 --- a/app/views/application/_bus_list_info.html.haml +++ b/app/views/application/_bus_list_info.html.haml @@ -5,7 +5,7 @@ %em TBD - bus_list.captains.each do |p| %p - %strong= p.full_name + %strong= p.user.full_name %br %em= p.school.name %br diff --git a/app/views/application/_questionnaire_summary.html.haml b/app/views/application/_questionnaire_summary.html.haml index 5ebb7a008..8a6f22959 100644 --- a/app/views/application/_questionnaire_summary.html.haml +++ b/app/views/application/_questionnaire_summary.html.haml @@ -32,10 +32,10 @@ %legend Provided by MyMLH %p %b First name: - = @questionnaire.first_name + = @questionnaire.user.first_name %p %b Last name: - = @questionnaire.last_name + = @questionnaire.user.last_name %p %b Email: = @questionnaire.email diff --git a/app/views/bus_lists/show.html.haml b/app/views/bus_lists/show.html.haml index 3b7b6785c..6f7a6ed59 100644 --- a/app/views/bus_lists/show.html.haml +++ b/app/views/bus_lists/show.html.haml @@ -43,8 +43,8 @@ %tr %td %input{type: 'checkbox', checked: p.boarded_bus?, data: { "boarded-bus": true, action: boarded_bus_bus_list_path, id: p.id } } - %td= p.first_name - %td= p.last_name + %td= p.user.first_name + %td= p.user.last_name %td= p.email %td= phone_link_to p.phone %td= p.school.name diff --git a/app/views/devise/registrations/_form.html.haml b/app/views/devise/registrations/_form.html.haml index 6ea83cf76..43e466fc7 100644 --- a/app/views/devise/registrations/_form.html.haml +++ b/app/views/devise/registrations/_form.html.haml @@ -6,7 +6,9 @@ %p %em or continue manually: .form-inputs - = f.input :email, required: true, autofocus: true + = f.input :first_name, required: true, autofocus: true + = f.input :last_name, required: true + = f.input :email, required: true = f.input :password, required: true = f.input :password_confirmation, required: true, label:"Confirm" .form-actions.right diff --git a/app/views/manage/admins/_form.html.haml b/app/views/manage/admins/_form.html.haml new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/manage/admins/index.html.haml b/app/views/manage/admins/index.html.haml new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/manage/application/_model_history.html.haml b/app/views/manage/application/_model_history.html.haml index 2377bc78b..405d1e1ef 100644 --- a/app/views/manage/application/_model_history.html.haml +++ b/app/views/manage/application/_model_history.html.haml @@ -15,7 +15,7 @@ - next if ignore_fields.include? field %p.mb-1 = t("simple_form.labels.#{audit.auditable.class.name.downcase}.#{field}") - - if audit.auditable.class.columns_hash[field].type == :text + - if audit.auditable.class.columns_hash[field].nil? || audit.auditable.class.columns_hash[field].type == :text changed - else changed to diff --git a/app/views/manage/bus_lists/show.html.haml b/app/views/manage/bus_lists/show.html.haml index 7534a3ad1..d13c65b9c 100644 --- a/app/views/manage/bus_lists/show.html.haml +++ b/app/views/manage/bus_lists/show.html.haml @@ -65,8 +65,8 @@ - @bus_list.passengers.select { |q| q.bus_captain_interest }.each do |p| %tr %td= link_to ''.html_safe, manage_questionnaire_path(p) - %td= p.first_name - %td= p.last_name + %td= p.user.first_name + %td= p.user.last_name %td= p.email %td= phone_link_to p.phone %td= link_to p.school.name, manage_school_path(p.school) diff --git a/app/views/manage/checkins/show.html.haml b/app/views/manage/checkins/show.html.haml index c7e1b0484..a0ea0182e 100644 --- a/app/views/manage/checkins/show.html.haml +++ b/app/views/manage/checkins/show.html.haml @@ -1,7 +1,7 @@ .d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-center.pt-3.pb-2.mb-3.border-bottom .d-flex.align-items-center.flex-wrap %h1.h2.mr-3 - = title @questionnaire.full_name + = title @questionnaire.user.full_name %div %span.mr-1 = render 'manage/questionnaires/acc_status_badge' @@ -19,7 +19,7 @@ .card-body .row %dt.col-md-4 Name - %dd.col-md-8= @questionnaire.full_name + %dd.col-md-8= @questionnaire.user.full_name %dt.col-md-4 School %dd.col-md-8 - school = @questionnaire.school diff --git a/app/views/manage/questionnaires/_form.html.haml b/app/views/manage/questionnaires/_form.html.haml index 91fff3521..189d88215 100644 --- a/app/views/manage/questionnaires/_form.html.haml +++ b/app/views/manage/questionnaires/_form.html.haml @@ -12,8 +12,9 @@ - if @questionnaire&.user&.provider == 'mlh' %h6.card-subtitle.mb-2 %span.badge.badge-info Provided by My MLH - = f.input :first_name, input_html: { "data-validate" => "presence" }, label: "First Name", autofocus: true - = f.input :last_name, input_html: { "data-validate" => "presence" }, label: "Last Name" + = f.simple_fields_for :user, @questionnaire.user do |u| + = u.input :first_name, input_html: { "data-validate" => "presence" }, label: "First Name", autofocus: true + = u.input :last_name, input_html: { "data-validate" => "presence" }, label: "Last Name" = f.input :email, input_html: { "data-validate" => "presence email", value: @questionnaire.user.try(:email) }, required: true, hint: 'Can be an existing user (without a questionnaire) or a new user. If this is a new user, they will receive a randomly-generated password that they must request a password reset for.' = f.input :phone, input_html: { "data-validate" => "presence" } = f.input :date_of_birth, start_year: Date.today.year - 18, end_year: Date.today.year - 90, order: [:month, :day, :year], input_html: { "data-validate" => "presence" } diff --git a/app/views/manage/questionnaires/_overview.html.haml b/app/views/manage/questionnaires/_overview.html.haml index 09e21b4ad..5e410bbf4 100644 --- a/app/views/manage/questionnaires/_overview.html.haml +++ b/app/views/manage/questionnaires/_overview.html.haml @@ -9,9 +9,9 @@ .card-body .row %dt.col-md-4 First name - %dd.col-md-8= @questionnaire.first_name + %dd.col-md-8= @questionnaire.user.first_name %dt.col-md-4 Last name - %dd.col-md-8= @questionnaire.last_name + %dd.col-md-8= @questionnaire.user.last_name %dt.col-md-4 Email %dd.col-md-8= @questionnaire.email %dt.col-md-4 Phone diff --git a/app/views/manage/questionnaires/edit.html.haml b/app/views/manage/questionnaires/edit.html.haml index 49851931b..fb3f0973e 100644 --- a/app/views/manage/questionnaires/edit.html.haml +++ b/app/views/manage/questionnaires/edit.html.haml @@ -1,6 +1,6 @@ -= render "layouts/manage/page_title", title: "Edit Questionnaire", subtitle: @questionnaire.full_name do += render "layouts/manage/page_title", title: "Edit Questionnaire", subtitle: @questionnaire.user.full_name do .btn-group = link_to 'Cancel', manage_questionnaire_path(@questionnaire), class: 'btn btn-sm btn-outline-secondary' - = link_to 'Delete', manage_questionnaire_path(@questionnaire), method: :delete, data: { confirm: "Are you sure? The questionnaire and account for \"#{@questionnaire.full_name}\" will be permanently erased. This action is irreversible." }, class: 'btn btn-sm btn-outline-secondary' + = link_to 'Delete', manage_questionnaire_path(@questionnaire), method: :delete, data: { confirm: "Are you sure? The questionnaire and account for \"#{@questionnaire.user.full_name}\" will be permanently erased. This action is irreversible." }, class: 'btn btn-sm btn-outline-secondary' = render 'form' diff --git a/app/views/manage/questionnaires/show.html.haml b/app/views/manage/questionnaires/show.html.haml index 429872c48..54d910fa9 100644 --- a/app/views/manage/questionnaires/show.html.haml +++ b/app/views/manage/questionnaires/show.html.haml @@ -1,7 +1,7 @@ .d-flex.justify-content-between.flex-wrap.flex-md-nowrap.align-items-center.pt-3.pb-2.mb-3.border-bottom .d-flex.align-items-center.flex-wrap %h1.h2.mr-3 - = title @questionnaire.full_name + = title @questionnaire.user.full_name %div %span.mr-1 = render 'acc_status_badge' @@ -16,7 +16,7 @@ %button.btn.btn-sm.btn-outline-secondary.dropdown-toggle#title-actions{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", type: "button"} .fa.fa-cog .dropdown-menu.dropdown-menu-right{"aria-labelledby" => "title-actions"} - = link_to 'Convert to Admin', convert_to_admin_manage_questionnaire_path(@questionnaire), method: :patch, data: { confirm: "Are you sure? The questionnaire for \"#{@questionnaire.full_name}\" will be permanently erased, and \"#{@questionnaire.email}\" will become an admin. This action is irreversible." }, class: 'dropdown-item' + = link_to 'Convert to Admin', convert_to_admin_manage_questionnaire_path(@questionnaire), method: :patch, data: { confirm: "Are you sure? The questionnaire for \"#{@questionnaire.user.full_name}\" will be permanently erased, and \"#{@questionnaire.email}\" will become an admin. This action is irreversible." }, class: 'dropdown-item' = render 'overview' diff --git a/app/views/manage/stats/index.html.haml b/app/views/manage/stats/index.html.haml index 9e5f22cd2..88c0f9491 100644 --- a/app/views/manage/stats/index.html.haml +++ b/app/views/manage/stats/index.html.haml @@ -2,14 +2,16 @@ .row .col - %h5.dashboard-container-title Dietary Restrictions & Special Needs - %table.stats.datatable.table.table-striped.table-hover{ "data-source" => dietary_special_needs_manage_stats_path(format: :json) } + %h5.dashboard-container-title Dietary Restrictions or Special Needs + %table.datatable.stats-dietary.table.table-striped.table-hover{ "data-source" => dietary_restrictions_special_needs_datatable_manage_stats_path(format: :json) } %thead %tr - %th First name - %th Last name + %th ID + %th First Name + %th Last Name %th Email %th Phone + %th Questionnaire %th Checked In %th Dietary Restrictions %th Special Needs @@ -18,53 +20,59 @@ .row .col %h5.dashboard-container-title Attendees Not Traveling From Their School - %table.stats.datatable.table.table-striped.table-hover{ "data-source" => alt_travel_manage_stats_path(format: :json) } + %table.datatable.stats-notschooltravel.table.table-striped.table-hover{ "data-source" => alt_travel_datatable_manage_stats_path(format: :json) } %thead %tr - %th Link - %th First name - %th Last name + %th ID + %th First Name + %th Last Name %th Email + %th Phone + %th Questionnaire %th Traveling From - %th Acc Status + %th Questionnaire Status %tbody .row .col %h5.dashboard-container-title Attendee Info for Sponsors - %table.stats.datatable.table.table-striped.table-hover{ "data-source" => sponsor_info_manage_stats_path(format: :json) } + %table.datatable.stats-attendeeinfo.table.table-striped.table-hover{ "data-source" => attendee_sponsor_info_datatable_manage_stats_path(format: :json) } %thead %tr + %th ID %th First name %th Last name %th Email %th School %th Open Source Link %th Portfolio Link - %th Resume Link %tbody .row .col %h5.dashboard-container-title MLH Info (applied) - %table.stats.datatable.table.table-striped.table-hover{ "data-source" => mlh_info_applied_manage_stats_path(format: :json) } + %table.datatable.stats-mlhinfo-applied.table.table-striped.table-hover{ "data-source" => mlh_applied_datatable_manage_stats_path(format: :json) } %thead %tr + %th ID %th First name %th Last name %th Email + %th Phone %th School Name %tbody .row .col %h5.dashboard-container-title MLH Info (checked in) - %table.stats.datatable.table.table-striped.table-hover{ "data-source" => mlh_info_checked_in_manage_stats_path(format: :json) } + %table.datatable.stats-mlhinfo-checkedin.table.table-striped.table-hover{ "data-source" => mlh_checked_in_datatable_manage_stats_path(format: :json) } %thead %tr + %th ID %th First name %th Last name %th Email + %th Phone %th School Name %tbody diff --git a/app/views/manage/users/index.html.haml b/app/views/manage/users/index.html.haml index f9b63be42..6a0a96855 100644 --- a/app/views/manage/users/index.html.haml +++ b/app/views/manage/users/index.html.haml @@ -8,6 +8,9 @@ %thead %tr %th= t(:id, scope: 'pages.manage.users.table') + %th + %th= t(:first_name, scope: 'pages.manage.users.table') + %th= t(:last_name, scope: 'pages.manage.users.table') %th= t(:email, scope: 'pages.manage.users.table') %th= t(:role, scope: 'pages.manage.users.table') %th= t(:questionnaire, scope: 'pages.manage.users.table') @@ -28,6 +31,9 @@ %thead %tr %th= t(:id, scope: 'pages.manage.users.table') + %th + %th= t(:first_name, scope: 'pages.manage.users.table') + %th= t(:last_name, scope: 'pages.manage.users.table') %th= t(:email, scope: 'pages.manage.users.table') %th= t(:role, scope: 'pages.manage.users.table') %th= t(:login_access, scope: 'pages.manage.users.table') diff --git a/app/views/questionnaires/_form.html.haml b/app/views/questionnaires/_form.html.haml index 789caca6a..4e8c45f8c 100644 --- a/app/views/questionnaires/_form.html.haml +++ b/app/views/questionnaires/_form.html.haml @@ -10,8 +10,6 @@ = markdown(HackathonConfig['disclaimer_message']) .form-inputs - = f.input :first_name, input_html: { "data-validate" => "presence" }, autofocus: true, wrapper_html: { class: 'input--half' } - = f.input :last_name, input_html: { "data-validate" => "presence" }, wrapper_html: { class: 'input--half' } = f.input :phone, label: "Phone number", input_html: { "data-validate" => "presence" } = f.input :date_of_birth, start_year: Date.today.year - 5, end_year: Date.today.year - 90, order: [:month, :day, :year], input_html: { "data-validate" => "presence" } diff --git a/config/locales/en.yml b/config/locales/en.yml index 060806f62..59579fef2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -91,8 +91,6 @@ en: Contact [travel@example.com](mailto:travel@example.com) questionnaire: - first_name: Joe - last_name: Smith email: joe@example.com phone: (123) 456-7890 school_id: My University @@ -104,6 +102,8 @@ en: portfolio_url: https://mywebsite.com vcs_url: https://github.com/coderit user: + first_name: Joe + last_name: Smith email: joe@example.com labels: school: diff --git a/config/routes.rb b/config/routes.rb index eb90c161d..00540ce88 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -90,11 +90,11 @@ patch :perform_merge, on: :member end resources :stats do - post :dietary_special_needs, on: :collection - post :sponsor_info, on: :collection - post :alt_travel, on: :collection - post :mlh_info_applied, on: :collection - post :mlh_info_checked_in, on: :collection + post :dietary_restrictions_special_needs_datatable, on: :collection + post :alt_travel_datatable, on: :collection + post :attendee_sponsor_info_datatable, on: :collection + post :mlh_applied_datatable, on: :collection + post :mlh_checked_in_datatable, on: :collection end resources :configs do patch :update_only_css_variables, on: :member diff --git a/db/migrate/20200525234832_move_user_info_from_questionnaire_to_user_model.rb b/db/migrate/20200525234832_move_user_info_from_questionnaire_to_user_model.rb new file mode 100644 index 000000000..7079ad37b --- /dev/null +++ b/db/migrate/20200525234832_move_user_info_from_questionnaire_to_user_model.rb @@ -0,0 +1,61 @@ +class MoveUserInfoFromQuestionnaireToUserModel < ActiveRecord::Migration[5.2] + + # See the "Hackathon Manager 2.0 Migration Guide" + # for a more general description of what this migration does. + + # Effectively, we move the `first_name` and `last_name` columns + # from the questionnares table to the users table (and model, for both). + + def up + + # Add the first/last name columns to the users table + add_column :users, :first_name, :string + add_column :users, :last_name, :string + + # Copy the data + execute "UPDATE users u, questionnaires q SET u.first_name = q.first_name WHERE u.id = q.user_id" + execute "UPDATE users u, questionnaires q SET u.last_name = q.last_name WHERE u.id = q.user_id" + + # If either first or last name is null, + # use the first part of their email as their first and last name. + # It is not currently possible to set only one and not the other, + # but we are "handling" that case nevertheless. + # + # This is needed because first and last names are REQUIRED to be non-nil. + User.where("first_name IS NULL AND last_name IS NULL").each do |u| + email_head = u.email.partition('@').first + u.first_name = email_head + u.last_name = email_head + u.save() + end + + # Remove the first/last name columns from the questionnaires table + remove_column :questionnaires, :first_name, :string + remove_column :questionnaires, :last_name, :string + end + + def down + + # Add the first/last name columns back to the questionnaires table + add_column :questionnaires, :first_name, :string + add_column :questionnaires, :last_name, :string + + # Copy the data + execute "UPDATE questionnaires q, users u SET q.first_name = u.first_name WHERE q.user_id = u.id" + execute "UPDATE questionnaires q, users u SET q.last_name = u.last_name WHERE q.user_id = u.id" + + # For all users, undo the email assignment scheme we did before, + # and set both their first/last name to nil. + User.all.each do |u| + email_head = u.email.partition('@').first + if u.first_name == email_head and u.last_name == email_head + u.first_name = nil + u.last_name = nil + end + end + + # Finally, remove the first/last name columns from the users table. + remove_column :users, :first_name, :string + remove_column :users, :last_name, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 42ae1fab4..7041720db 100644 --- a/db/schema.rb +++ b/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: 2020_02_05_160318) do +ActiveRecord::Schema.define(version: 2020_05_30_172450) do create_table "active_storage_attachments", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| t.string "name", null: false @@ -193,8 +193,6 @@ end create_table "questionnaires", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| - t.string "first_name" - t.string "last_name" t.date "date_of_birth" t.string "experience" t.string "school_id" @@ -300,6 +298,8 @@ t.integer "role", default: 0 t.boolean "is_active", default: true t.boolean "receive_weekly_report", default: false + t.string "first_name" + t.string "last_name" t.index ["email"], name: "index_users_on_email", unique: true t.index ["provider"], name: "index_users_on_provider" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true diff --git a/test/controllers/manage/questionnaires_controller_test.rb b/test/controllers/manage/questionnaires_controller_test.rb index 8499dc1f0..62dd49f72 100644 --- a/test/controllers/manage/questionnaires_controller_test.rb +++ b/test/controllers/manage/questionnaires_controller_test.rb @@ -45,13 +45,13 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase end should "not allow access to manage_questionnaires#create" do - post :create, params: { questionnaire: { first_name: "New" } } + post :create, params: { questionnaire: { major: "Computer Science" } } assert_response :redirect assert_redirected_to new_user_session_path end should "not allow access to manage_questionnaires#update" do - patch :update, params: { id: @questionnaire, questionnaire: { first_name: "New" } } + patch :update, params: { id: @questionnaire, questionnaire: { major: "Human Centered Computing" } } assert_response :redirect assert_redirected_to new_user_session_path end @@ -124,13 +124,13 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase end should "not allow access to manage_questionnaires#create" do - post :create, params: { questionnaire: { first_name: "New" } } + post :create, params: { questionnaire: { major: "Best Major" } } assert_response :redirect assert_redirected_to root_path end should "not allow access to manage_questionnaires#update" do - patch :update, params: { id: @questionnaire, questionnaire: { first_name: "New" } } + patch :update, params: { id: @questionnaire, questionnaire: { major: "Best Major" } } assert_response :redirect assert_redirected_to root_path end @@ -200,13 +200,13 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase end should "not allow access to manage_questionnaires#create" do - post :create, params: { questionnaire: { first_name: "New" } } + post :create, params: { questionnaire: { major: "Best Major" } } assert_response :redirect assert_redirected_to manage_questionnaires_path end should "not allow access to manage_questionnaires#update" do - patch :update, params: { id: @questionnaire, questionnaire: { first_name: "New" } } + patch :update, params: { id: @questionnaire, questionnaire: { major: "Best Major" } } assert_response :redirect assert_redirected_to manage_questionnaires_path end @@ -267,50 +267,51 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase assert_response :success end - should "create questionnaire and user" do - assert_difference("User.count", 1) do - assert_difference("Questionnaire.count", 1) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @questionnaire.school_id, email: "test@example.com", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", gender: @questionnaire.gender, major: @questionnaire.major, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } - end - end - - assert_equal "test@example.com", assigns(:questionnaire).email - assert_redirected_to manage_questionnaire_path(assigns(:questionnaire)) - end - should "not create a duplicate questionnaire for a user" do user = create(:user, email: "existing@example.com") create(:questionnaire, user_id: user.id) assert_difference("User.count", 0) do assert_difference("Questionnaire.count", 0) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @questionnaire.school_id, email: "existing@example.com", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", gender: @questionnaire.gender, major: @questionnaire.major, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { + questionnaire: { + experience: @questionnaire.experience, + interest: @questionnaire.interest, + first_name: @questionnaire.user.first_name, + last_name: @questionnaire.user.last_name, + phone: @questionnaire.phone, + level_of_study: @questionnaire.level_of_study, + date_of_birth: @questionnaire.date_of_birth, + shirt_size: @questionnaire.shirt_size, + school_id: @questionnaire.school_id, + email: "existing@example.com", + agreement_accepted: "1", + code_of_conduct_accepted: "1", + data_sharing_accepted: "1", + gender: @questionnaire.gender, + major: @questionnaire.major, + why_attend: @questionnaire.why_attend, + graduation_year: @questionnaire.graduation_year, + race_ethnicity: @questionnaire.race_ethnicity + } + } end end assert_response :success end - should "create a questionnaire with existing user" do - create(:user, email: "existing@example.com") - assert_difference("User.count", 0) do - assert_difference("Questionnaire.count", 1) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @questionnaire.school_id, email: "existing@example.com", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", gender: @questionnaire.gender, major: @questionnaire.major, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } - end - end - assert_equal "existing@example.com", assigns(:questionnaire).email - assert_redirected_to manage_questionnaire_path(assigns(:questionnaire)) - end - - should "create school if doesn't exist in questionnaire" do - assert_difference("Questionnaire.count", 1) do - assert_difference("School.count", 1) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: "My New School", email: "taken@example.com", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", gender: @questionnaire.gender, major: @questionnaire.major, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } - end - end - assert_equal "My New School", assigns(:questionnaire).school.name - end - - should "update questionnaire" do - patch :update, params: { id: @questionnaire, questionnaire: { first_name: "New" } } + # This and email are seaparte as they are still implemented separately. + should "update questionnaire's user's first and last name" do + patch :update, params: { + id: @questionnaire, + questionnaire: { + user: { + "first_name": "firstnametest", + "last_name": "lastnametest" + } + } + } + assert_equal "firstnametest", assigns(:questionnaire).user.first_name + assert_equal "lastnametest", assigns(:questionnaire).user.last_name assert_redirected_to manage_questionnaire_path(assigns(:questionnaire)) end @@ -349,7 +350,16 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase @questionnaire.update_attribute(:agreement_accepted, false) @questionnaire.update_attribute(:can_share_info, false) @questionnaire.update_attribute(:phone, "") - patch :check_in, params: { id: @questionnaire, check_in: "true", questionnaire: { agreement_accepted: 1, can_share_info: 1, phone: "(123) 333-3333", email: "new_email@example.com" } } + patch :check_in, params: { + id: @questionnaire, + check_in: "true", + questionnaire: { + agreement_accepted: 1, + can_share_info: 1, + phone: "(123) 333-3333", + email: "new_email@example.com" + } + } @questionnaire.reload assert 1.minute.ago < @questionnaire.checked_in_at assert_equal @user.id, @questionnaire.checked_in_by_id @@ -369,7 +379,16 @@ class Manage::QuestionnairesControllerTest < ActionController::TestCase @questionnaire.user.update_attribute(:email, "old_email@example.com") @questionnaire.update_attribute(:checked_in_at, nil) @questionnaire.update_attribute(:checked_in_by_id, nil) - patch :check_in, params: { id: @questionnaire, check_in: "", questionnaire: { agreement_accepted: 1, can_share_info: 1, phone: "(123) 333-3333", email: "new_email@example.com" } } + patch :check_in, params: { + id: @questionnaire, + check_in: "", + questionnaire: { + agreement_accepted: 1, + can_share_info: 1, + phone: "(123) 333-3333", + email: "new_email@example.com" + } + } @questionnaire.reload assert_nil @questionnaire.checked_in_at assert_nil @questionnaire.checked_in_by_id diff --git a/test/controllers/manage/stats_controller_test.rb b/test/controllers/manage/stats_controller_test.rb index 791e2cf73..9e4e66f65 100644 --- a/test/controllers/manage/stats_controller_test.rb +++ b/test/controllers/manage/stats_controller_test.rb @@ -67,6 +67,6 @@ class Manage::StatsControllerTest < ActionController::TestCase private def paths - [:dietary_special_needs, :sponsor_info, :alt_travel, :mlh_info_applied, :mlh_info_checked_in] + [:dietary_restrictions_special_needs_datatable, :attendee_sponsor_info_datatable, :alt_travel_datatable, :mlh_applied_datatable, :mlh_checked_in_datatable] end end diff --git a/test/controllers/questionnaires_controller_test.rb b/test/controllers/questionnaires_controller_test.rb index 0ad2c8276..faf0279a0 100644 --- a/test/controllers/questionnaires_controller_test.rb +++ b/test/controllers/questionnaires_controller_test.rb @@ -36,7 +36,7 @@ class QuestionnairesControllerTest < ActionController::TestCase context "while authenticated without a completed questionnaire" do setup do @request.env["devise.mapping"] = Devise.mappings[:admin] - @user = create(:user, email: "newabc@example.com") + @user = create(:user) sign_in @user end @@ -47,7 +47,7 @@ class QuestionnairesControllerTest < ActionController::TestCase should "create questionnaire" do assert_difference('Questionnaire.count', 1) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } end assert_redirected_to questionnaires_path @@ -60,8 +60,8 @@ class QuestionnairesControllerTest < ActionController::TestCase should "not allow multiple questionnaires" do assert_difference('Questionnaire.count', 1) do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_id: @school.id, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } end assert_redirected_to questionnaires_path @@ -71,7 +71,7 @@ class QuestionnairesControllerTest < ActionController::TestCase should "not allow creation" do @questionnaire.delete assert_difference('Questionnaire.count', 0) do - post :create, params: { questionnaire: { first_name: "My first name" } } + post :create, params: { questionnaire: { major: "a great major" } } end end end @@ -79,13 +79,13 @@ class QuestionnairesControllerTest < ActionController::TestCase context "#school_name" do context "on create" do should "save existing school name" do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: @school.name, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: @school.name, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } assert_redirected_to questionnaires_path assert_equal 1, School.all.count end should "create a new school when unknown" do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: "New School", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: "New School", agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } assert_redirected_to questionnaires_path assert_equal 2, School.all.count end @@ -94,7 +94,7 @@ class QuestionnairesControllerTest < ActionController::TestCase message = create(:message, type: 'automated', trigger: "questionnaire.pending") assert_difference 'enqueued_jobs.size', 1 do assert_difference 'Questionnaire.count', 1 do - post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, first_name: @questionnaire.first_name, last_name: @questionnaire.last_name, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: @school.name, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } + post :create, params: { questionnaire: { experience: @questionnaire.experience, interest: @questionnaire.interest, phone: @questionnaire.phone, level_of_study: @questionnaire.level_of_study, date_of_birth: @questionnaire.date_of_birth, shirt_size: @questionnaire.shirt_size, school_name: @school.name, agreement_accepted: "1", code_of_conduct_accepted: "1", data_sharing_accepted: "1", major: @questionnaire.major, gender: @questionnaire.gender, why_attend: @questionnaire.why_attend, graduation_year: @questionnaire.graduation_year, race_ethnicity: @questionnaire.race_ethnicity } } end end questionnaire = Questionnaire.last @@ -152,7 +152,7 @@ class QuestionnairesControllerTest < ActionController::TestCase end should "update questionnaire" do - patch :update, params: { questionnaire: { first_name: "Foo" } } + patch :update, params: { questionnaire: { major: "Computer Science" } } assert_redirected_to questionnaires_path end @@ -166,9 +166,9 @@ class QuestionnairesControllerTest < ActionController::TestCase context "with invalid questionnaire params" do should "not allow updates" do - saved_first_name = @questionnaire.first_name - patch :update, params: { questionnaire: { first_name: "" } } - assert_equal saved_first_name, @questionnaire.reload.first_name + saved_major = @questionnaire.major + patch :update, params: { questionnaire: { major: "" } } + assert_equal saved_major, @questionnaire.reload.major end end diff --git a/test/controllers/rsvps_controller_test.rb b/test/controllers/rsvps_controller_test.rb index d1f95fc68..77a15dbe7 100644 --- a/test/controllers/rsvps_controller_test.rb +++ b/test/controllers/rsvps_controller_test.rb @@ -230,7 +230,7 @@ class RsvpsControllerTest < ActionController::TestCase should "not allow updates to invalid questionnaire via rsvp page" do @questionnaire.update_attribute(:phone, "1111111111") - @questionnaire.update_attribute(:first_name, "") + @questionnaire.update_attribute(:agreement_accepted, false) patch :update, params: { questionnaire: { phone: "1234567890" } } assert_not_nil flash[:alert] assert_equal "1111111111", @questionnaire.reload.phone diff --git a/test/factories/questionnaire.rb b/test/factories/questionnaire.rb index 1498ca792..f732b8992 100644 --- a/test/factories/questionnaire.rb +++ b/test/factories/questionnaire.rb @@ -1,7 +1,5 @@ FactoryBot.define do factory :questionnaire do - first_name { "John" } - last_name { "Doe" } phone { "(123) 456-7890" } international { false } date_of_birth { Date.today - 20.years } diff --git a/test/factories/users.rb b/test/factories/users.rb index 6188b9991..f4b7bedf1 100644 --- a/test/factories/users.rb +++ b/test/factories/users.rb @@ -1,5 +1,7 @@ FactoryBot.define do factory :user do + first_name { "John" } + last_name { "Doe" } sequence :email do |n| "foo#{n}@example.com" end diff --git a/test/helpers/audit_helper_test.rb b/test/helpers/audit_helper_test.rb index 26c780b0f..7b1d22ff4 100644 --- a/test/helpers/audit_helper_test.rb +++ b/test/helpers/audit_helper_test.rb @@ -17,8 +17,8 @@ class AuditHelperTest < ActiveSupport::TestCase should "model values for related fields" do bus_list = create(:bus_list, name: "Foo bus list") assert_equal "Foo bus list", display_audit_value(bus_list.id, "bus_list_id") - user = create(:user, email: "abc@example.com") - assert_equal "abc@example.com", display_audit_value(user.id, "checked_in_by_id") + user = create(:user, first_name: "Tom", last_name: "Nook") + assert_equal "Tom Nook", display_audit_value(user.id, "checked_in_by_id") end should "use human description for arrays" do diff --git a/test/models/message_test.rb b/test/models/message_test.rb index 9cf56e30c..5476f3ed4 100644 --- a/test/models/message_test.rb +++ b/test/models/message_test.rb @@ -40,9 +40,9 @@ class MessageTest < ActiveSupport::TestCase end should "parse template variables with real values" do - questionnaire = create(:questionnaire, first_name: 'Richard') + user = create(:user, first_name: 'Richard') message = build(:message, body: "Hello, {{first_name}}!") - assert_equal "Hello, Richard!", message.parsed_body(user_id: questionnaire.user_id) + assert_equal "Hello, Richard!", message.parsed_body(user_id: user.id) end should "ignore unknown variables" do diff --git a/test/models/questionnaire_test.rb b/test/models/questionnaire_test.rb index ca753943d..d61fcfd47 100644 --- a/test/models/questionnaire_test.rb +++ b/test/models/questionnaire_test.rb @@ -9,8 +9,6 @@ class QuestionnaireTest < ActiveSupport::TestCase should validate_uniqueness_of :user_id - should strip_attribute :first_name - should strip_attribute :last_name should strip_attribute :acc_status should strip_attribute :major should strip_attribute :gender @@ -19,8 +17,6 @@ class QuestionnaireTest < ActiveSupport::TestCase should strip_attribute :travel_location should strip_attribute :why_attend - should validate_presence_of :first_name - should validate_presence_of :last_name should validate_presence_of :date_of_birth should validate_presence_of :experience should validate_presence_of :interest @@ -163,13 +159,6 @@ class QuestionnaireTest < ActiveSupport::TestCase end end - context "#full_name" do - should "concatenate first and last name" do - questionnaire = create(:questionnaire, first_name: "Foo", last_name: "Bar") - assert_equal "Foo Bar", questionnaire.full_name - end - end - context "#full_location" do should "concatenate city and state with a comma" do school = create(:school, city: "Foo", state: "AZ") @@ -477,7 +466,7 @@ class QuestionnaireTest < ActiveSupport::TestCase questionnaire = create(:questionnaire, acc_status: 'accepted') create(:message, trigger: "questionnaire.accepted") assert_difference "enqueued_jobs.size", 0 do - questionnaire.update_attribute(:first_name, "foo bar baz") + questionnaire.update_attribute(:interest, "code") end end diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 610a162d1..86e264e0c 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -3,10 +3,14 @@ class UserTest < ActiveSupport::TestCase include ActiveJob::TestHelper + should strip_attribute :first_name + should strip_attribute :last_name should strip_attribute :email should validate_uniqueness_of :email + should validate_presence_of :first_name + should validate_presence_of :last_name should validate_presence_of :email should validate_presence_of :password @@ -18,39 +22,10 @@ class UserTest < ActiveSupport::TestCase should allow_value("test@example.com").for(:email) should_not allow_value("abcd").for(:email) - context "first_name" do - should "return first name when questionnaire exists" do - questionnaire = create(:questionnaire, first_name: "Alpha") - assert_equal "Alpha", questionnaire.user.first_name - end - - should "return blank when no questionnaire exists" do - user = create(:user) - assert_equal "", user.first_name - end - end - - context "last_name" do - should "return last name when questionnaire exists" do - questionnaire = create(:questionnaire, last_name: "Beta") - assert_equal "Beta", questionnaire.user.last_name - end - - should "return blank when no questionnaire exists" do - user = create(:user) - assert_equal "", user.last_name - end - end - context "full_name" do - should "return full name when questionnaire exists" do - questionnaire = create(:questionnaire, first_name: "Alpha", last_name: "Beta") - assert_equal "Alpha Beta", questionnaire.user.full_name - end - - should "return email when no questionnaire exists" do - user = create(:user, email: "foo@example.com") - assert_equal "foo@example.com", user.full_name + should "concatenate first and last name" do + user = create(:user) + assert_equal "John Doe", user.full_name end end