Remove code for legacy mentoring feature (#3186)

This commit is contained in:
rhymes 2019-06-21 23:18:11 +02:00 committed by Ben Halpern
parent f79b3cb12a
commit 91de529705
30 changed files with 51 additions and 717 deletions

View file

@ -3,10 +3,6 @@ class Internal::UsersController < Internal::ApplicationController
def index
@users = case params[:state]
when "mentors"
User.where(offering_mentorship: true).page(params[:page]).per(50)
when "mentees"
User.where(seeking_mentorship: true).page(params[:page]).per(50)
when /role\-/
User.with_role(params[:state].split("-")[1], :any).page(params[:page]).per(50)
else
@ -26,27 +22,14 @@ class Internal::UsersController < Internal::ApplicationController
end
def show
@user = if params[:id] == "unmatched_mentee"
MentorRelationship.unmatched_mentees.order(Arel.sql("RANDOM()")).first
else
User.find(params[:id])
end
@user_mentee_relationships = MentorRelationship.where(mentor_id: @user.id)
@user_mentor_relationships = MentorRelationship.where(mentee_id: @user.id)
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
@new_mentee = user_params[:add_mentee]
@new_mentor = user_params[:add_mentor]
make_matches
manage_credits
add_note if user_params[:new_note]
if user_params[:quick_match]
redirect_to "/internal/users/unmatched_mentee"
else
redirect_to "/internal/users/#{params[:id]}"
end
redirect_to "/internal/users/#{params[:id]}"
end
def user_status
@ -132,24 +115,10 @@ class Internal::UsersController < Internal::ApplicationController
Credit.remove_from_org(org, amount)
end
def make_matches
return if @new_mentee.blank? && @new_mentor.blank?
if @new_mentee.present?
mentee = User.find(@new_mentee)
MentorRelationship.new(mentee_id: mentee.id, mentor_id: @user.id).save!
end
return if @new_mentor.blank?
mentor = User.find(@new_mentor)
MentorRelationship.new(mentee_id: @user.id, mentor_id: mentor.id).save!
end
def user_params
allowed_params = %i[
seeking_mentorship offering_mentorship quick_match new_note add_mentor
add_mentee note_for_current_role mentorship_note user_status
toggle_mentorship pro merge_user_id add_credits remove_credits
new_note note_for_current_role user_status
pro merge_user_id add_credits remove_credits
add_org_credits remove_org_credits ghostify
]
params.require(:user).permit(allowed_params)

View file

@ -1,8 +0,0 @@
module MentorshipMatcher
def self.match_mentees_and_mentors(mentee_ids, mentor_ids)
mentee_ids.each_with_index do |id, index|
mentor = User.find(mentor_ids[index])
MentorRelationship.create(mentee_id: id, mentor_id: mentor.id)
end
end
end

View file

@ -31,18 +31,14 @@ class UserSimilarity
].freeze
attr_accessor :first_user, :second_user
def initialize(first_user, second_user)
@first_user = first_user
@second_user = second_user
end
def score
mentorship_score + profile_score + tag_score
end
def mentorship_score
(first_user.mentee_description.to_s.tr("0-9", "").split(" ") & second_user.mentor_description.to_s.tr("0-9", "").split(" ") - STOP_WORDS).size +
(first_user.mentor_description.to_s.tr("0-9", "").split(" ") & second_user.mentee_description.to_s.tr("0-9", "").split(" ") - STOP_WORDS).size
profile_score + tag_score
end
def profile_score

View file

@ -74,20 +74,6 @@ class NotifyMailer < ApplicationMailer
mail(to: user.email, subject: subject)
end
def mentee_email(mentee, mentor)
@mentee = mentee
@mentor = mentor
subject = "You have been matched with a DEV mentor!"
mail(to: @mentee.email, subject: subject, from: "Liana (from dev.to) <liana@dev.to>")
end
def mentor_email(mentor, mentee)
@mentor = mentor
@mentee = mentee
subject = "You have been matched with a new DEV mentee!"
mail(to: @mentor.email, subject: subject, from: "Liana (from dev.to) <liana@dev.to>")
end
def export_email(user, attachment)
@user = user
export_filename = "devto-export-#{Date.current.iso8601}.zip"

View file

@ -1,53 +0,0 @@
class MentorRelationship < ApplicationRecord
belongs_to :mentor, class_name: "User"
belongs_to :mentee, class_name: "User"
validates :mentor, presence: true
validates :mentee, presence: true
validate :check_for_same_user
validates :mentor_id, uniqueness: { scope: :mentee_id }
after_create :mutual_follow
after_create :send_emails
def check_for_same_user
errors.add(:mentor_relationship, "Mentor and Mentee cannot be the same person") if mentor_id == mentee_id
end
def self.unmatched_mentees
sql = "SELECT mentee_form_updated_at,
users.id,
mentor_relationships.mentor_id
FROM users
LEFT JOIN notes ON users.id = notes.noteable_id
LEFT JOIN mentor_relationships ON users.id = mentor_relationships.mentee_id
WHERE seeking_mentorship IS TRUE
AND mentor_relationships.mentor_id IS null"
record_ids = ActiveRecord::Base.connection.execute(sql).pluck("id")
User.where(id: record_ids).where.not(mentee_description: nil)
end
def self.unmatched_mentors
sql = "SELECT mentor_form_updated_at,
users.id,
mentor_relationships.mentor_id
FROM users
LEFT JOIN notes ON users.id = notes.noteable_id
LEFT JOIN mentor_relationships ON users.id = mentor_relationships.mentor_id
WHERE offering_mentorship IS TRUE
AND mentor_relationships.mentee_id IS null"
record_ids = ActiveRecord::Base.connection.execute(sql).pluck("id")
User.where(id: record_ids)
end
private
def mutual_follow
mentor.follow(mentee)
mentee.follow(mentor)
end
def send_emails
NotifyMailer.mentee_email(mentee, mentor).deliver
NotifyMailer.mentor_email(mentor, mentee).deliver
end
end

View file

@ -25,7 +25,6 @@ class Role < ApplicationRecord
level_1_member
workshop_pass
chatroom_beta_tester
banned_from_mentorship
comment_banned
pro
]

View file

@ -1,7 +1,10 @@
class User < ApplicationRecord
include CloudinaryHelper
attr_accessor :scholar_email, :new_note, :quick_match, :mentorship_note, :note_for_current_role, :add_mentor, :add_mentee, :user_status, :toggle_mentorship, :pro, :merge_user_id, :add_credits, :remove_credits, :add_org_credits, :remove_org_credits, :ghostify
attr_accessor(
:scholar_email, :new_note, :note_for_current_role, :user_status, :pro, :merge_user_id,
:add_credits, :remove_credits, :add_org_credits, :remove_org_credits, :ghostify
)
rolify
include AlgoliaSearch
@ -40,16 +43,6 @@ class User < ApplicationRecord
has_many :classified_listings
has_many :poll_votes
has_many :poll_skips
has_many :mentor_relationships_as_mentee,
class_name: "MentorRelationship", foreign_key: "mentee_id", inverse_of: :mentee
has_many :mentor_relationships_as_mentor,
class_name: "MentorRelationship", foreign_key: "mentor_id", inverse_of: :mentor
has_many :mentors,
through: :mentor_relationships_as_mentee,
source: :mentor
has_many :mentees,
through: :mentor_relationships_as_mentor,
source: :mentee
mount_uploader :profile_image, ProfileImageUploader
@ -132,8 +125,6 @@ class User < ApplicationRecord
validates :mostly_work_with, :currently_learning,
:currently_hacking_on, :available_for,
length: { maximum: 500 }
validates :mentee_description, :mentor_description,
length: { maximum: 1000 }
validates :inbox_type, inclusion: { in: %w[open private] }
validates :currently_streaming_on, inclusion: { in: %w[twitch] }, allow_nil: true
validate :conditionally_validate_summary
@ -149,7 +140,6 @@ class User < ApplicationRecord
after_save :conditionally_resave_articles
after_create :estimate_default_language!
before_create :set_default_language
before_update :mentorship_status_update
before_validation :set_username
# make sure usernames are not empty, to be able to use the database unique index
before_validation :verify_twitter_username, :verify_github_username, :verify_email, :verify_twitch_username
@ -320,10 +310,6 @@ class User < ApplicationRecord
user.notes.where(reason: "banned", content: "spam account").any? && user.banned && user.comments.none? && user.articles.none?
end
def banned_from_mentorship
has_role? :banned_from_mentorship
end
def admin?
has_role?(:super_admin)
end
@ -643,10 +629,4 @@ class User < ApplicationRecord
follower_relationships.destroy_all
follows.destroy_all
end
def mentorship_status_update
self.mentor_form_updated_at = Time.current if mentor_description_changed? || offering_mentorship_changed?
self.mentee_form_updated_at = Time.current if mentee_description_changed? || seeking_mentorship_changed?
end
end

View file

@ -90,19 +90,13 @@ class UserPolicy < ApplicationPolicy
looking_for_work_publicly
mastodon_url
medium_url
mentee_description
mentee_form_updated_at
mentor_description
mentor_form_updated_at
mostly_work_with
name
offering_mentorship
inbox_type
permit_adjacent_sponsors
password
password_confirmation
profile_image
seeking_mentorship
stackoverflow_url
summary
text_color_hex

View file

@ -141,44 +141,14 @@ module Moderator
user.remove_role :comment_banned if user.comment_banned
end
def deactivate_mentorship(relationships)
relationships.each do |relationship|
relationship.update(active: false)
end
end
def inactive_mentorship(mentor, mentee)
relationship = MentorRelationship.where(mentor_id: mentor.id, mentee_id: mentee.id)
relationship.update(active: false)
end
def update_mentorship_status
if user_params[:toggle_mentorship] == "1"
@user.add_role :banned_from_mentorship
mentee_relationships = MentorRelationship.where(mentor_id: @user.id)
mentor_relationships = MentorRelationship.where(mentee_id: @user.id)
deactivate_mentorship(mentee_relationships)
deactivate_mentorship(mentor_relationships)
@user.update(offering_mentorship: false, seeking_mentorship: false)
create_note("banned_from_mentorship", user_params[:mentorship_note])
else
@user.remove_role :banned_from_mentorship
create_note("reinstate_mentorship_privileges", user_params[:mentorship_note])
end
end
def update_trusted_cache
Rails.cache.delete("user-#{@user.id}/has_trusted_role")
@user.trusted
end
def update_roles
if user_params[:toggle_mentorship]
update_mentorship_status
else
handle_user_status(user_params[:user_status], user_params[:note_for_current_role])
update_trusted_cache
end
handle_user_status(user_params[:user_status], user_params[:note_for_current_role])
update_trusted_cache
end
end
end

View file

@ -1,66 +0,0 @@
<% if @user.seeking_mentorship && @user.mentee_description.present? && !@user.banned_from_mentorship %>
<h2> Mentee Description </h2>
<div class="row" style="font-size:0.85em;position:sticky;top:50px;background:white;z-index:1000;border:2px solid black">
<div class="col-md-2">
<img src="<%= @user.profile_image_90 %>" style="border-radius:100px;width:50px;height:50px;" alt="<%= @user.username %> profile image">
<br />
<a href="/<%= @user.username %>" target="_blank">@<%= @user.username %></a>
<br />
</div>
<div class="col-md-3" style="border-left:1px solid black">
<h4>Tags</h4>
<%= @user.cached_followed_tag_names.join(", ") %>
</div>
<div class="col-md-3" style="max-height: 22vh;overflow:auto">
<h4>Mentee description</h4>
<%= @user.mentee_description %>
</div>
<div class="col-md-3">
<h4>Skills/Languages</h4>
<%= @user.mostly_work_with %>
</div>
<div class="col-md-1">
</div>
</div>
<h2> Possible Mentors </h2>
<% count = 0 %>
<% MentorRelationship.
unmatched_mentors.where.not(mentor_form_updated_at: nil, id: @user.id, mentor_description: [nil, ""]).
order("mentor_form_updated_at DESC").limit(175).
sort_by {|possible_mentor| UserSimilarity.new(@user, possible_mentor).score}.reverse.
first(40).each do |possible_mentor| %>
<% if !possible_mentor.banned_from_mentorship %>
<div class="row" style="font-size:0.9em">
<div class="col-md-2">
<img src="<%= possible_mentor.profile_image_90 %>" style="border-radius:100px;width:50px;height:50px;" alt="<%= possible_mentor.username %> profile image">
<br />
<a href="/<%= possible_mentor.username %>" target="_blank">@<%= possible_mentor.username %></a>
<br />
<a href="/internal/users/<%= possible_mentor.id %>" target="_blank">Internal Profile (id #<%= possible_mentor.id %>)</a>
</div>
<div class="col-md-3" style="border-left:1px solid black">
<h4>Tag Intersection</h4>
<%= UserSimilarity.new(@user, possible_mentor).tag_intersection.join(", ") %>
</div>
<div class="col-md-3">
<h4>Mentor description</h4>
<%= possible_mentor.mentor_description %>
</div>
<div class="col-md-3">
<h4>Skills/Languages</h4>
<%= possible_mentor.mostly_work_with %>
</div>
<div class="col-md-1">
<h4>Action</h4>
<%= form_for ([:internal, @user]) do |f| %>
<%= f.hidden_field :quick_match, value: true %>
<%= f.hidden_field :add_mentor, value: possible_mentor.id %>
<%= f.submit "Match!" %>
<% end %>
</div>
</div>
<% end %>
<% end %>
<% end %>

View file

@ -5,8 +5,6 @@
</style>
<h3 class="top-nav" style="font-weight:400;font-size:0.9em;">
<a href="/internal/users" style="<%= "font-weight:bold" if params[:state].blank? %>">All</a> |
<a href="/internal/users?state=mentors" style="<%= "font-weight:bold" if params[:state] == "mentors" %>">Mentors </a> |
<a href="/internal/users?state=mentees" style="<%= "font-weight:bold" if params[:state] == "mentees" %>">Mentees</a> |
<a href="/internal/users?state=role-admin" style="<%= "font-weight:bold" if params[:state] == "role-admin" %>">Admins</a> |
<a href="/internal/users?state=role-super_admin" style="<%= "font-weight:bold" if params[:state] == "role-super_admin" %>">Super Admins</a> |
<a href="/internal/users?state=role-trusted" style="<%= "font-weight:bold" if params[:state] == "role-trusted" %>">Trusted</a> |

View file

@ -43,49 +43,7 @@
</div>
<%= render "activity" %>
<%= render "credits" %>
<div class="row">
<h3><u>Mentorship</u></h3>
<% if @user.mentors.count > 0 %>
<h4> Mentor(s):</h4>
<ul>
<% @user_mentor_relationships.each do |relationship| %>
<li>
<a href="https://dev.to/<%= User.find(relationship.mentor_id).username %>" target=">blank">@<%= User.find(relationship.mentor_id).username %></a>
<% if relationship.active %>
<span style="color:green"><em> (active)</em></span>
<% else %>
<span style="color:red"><em> (inactive)</em></span>
<% end %>
</li>
<% end %>
</ul>
<% elsif @user.mentees.count > 0 %>
<h4>Mentee(s):</h4>
<ul>
<% @user_mentee_relationships.each do |relationship| %>
<li>
<a href="https://dev.to/<%= User.find(relationship.mentee_id).username %>" target=">blank">@<%= User.find(relationship.mentee_id).username %></a>
<% if relationship.active %>
<span style="color:green"><em> (active)</em></span>
<% else %>
<span style="color:red"><em> (inactive)</em></span>
<% end %>
</li>
<% end %>
</ul>
<% elsif @user.has_role? :banned_from_mentorship %>
<p style="background-color: red;">User is banned from the mentorship program.</p>
<% else %>
<p>Currently not in a mentorship relationship.</p>
<% end %>
<%= form_for(@user, url: user_status_internal_user_path(@user)) do |f| %>
<p>Ban from mentorship: <%= f.check_box :toggle_mentorship, checked: @user.has_role?(:banned_from_mentorship) %></p>
<p>Reason for action: <%= f.text_area :mentorship_note %></p>
<%= f.submit %>
<% end %>
</div>
<%= render "notes" %>
<%= render "mentee_match" %>
<div class="row">
<h2><u>Recent Emails</u></h2>
<ul>

View file

@ -1,39 +0,0 @@
<p>
Hey <b>@<%= @mentee.username %></b>!
</p>
<p>
Let me get straight to the point: your mentor is
<b><a href="https://dev.to/<%= @mentor.username %>">@<%= @mentor.username %></a></b>. We have had you two automatically follow each other, so you can find them on DEV Connect, and introduce yourself!
</p>
<p>
A few notes:
</p>
<ul>
<li>
Every person is different so every mentor/mentee relationship is unique. We expect some mentorships to last longer than others and hope that at the very least, youll have made a solid new connection.
</li>
<li>
We expect everyone to abide by our
<a href="https://dev.to/code-of-conduct">Code of Conduct</a>, especially in this setting. Should your mentor demonstrate inappropriate behavior, please contact us immediately.
</li>
<li>
If you feel like this was a mismatch, or if your mentor is unresponsive after several days, let us know.
</li>
<li>
We highly recommend setting goals and expectations with your mentor from Day 1.
</li>
<li>
To help you all get started, weve put together some
<a href="https://dev.to/jess/mentorship-resources-19p0">resources</a>.
</li>
</ul>
<p>
Thanks again for participating in our program.
</p>
<p>
Good luck!
</p>
<p>
Liana
</p>

View file

@ -1,16 +0,0 @@
Hey!
Let me get straight to the point: your mentor is: https://dev.to/<%= @mentor.username %>. We have had you two automatically follow each other, so you can find them on DEV Connect, and introduce yourself!
A few notes:
- Every person is different so every mentor/mentee relationship is unique. We expect some mentorships to last longer than others and hope that at the very least, youll have made a solid new connection.
- We expect everyone to abide by our Code of Conduct: https://dev.to/code-of-conduct, especially in this setting. Should your mentor demonstrate inappropriate behavior, please contact us immediately.
- If you feel like this was a mismatch, or if your mentor is unresponsive after several days, let us know.
- We highly recommend setting goals and expectations with your mentor from Day 1.
- To help you all get started, weve put together some resources: https://dev.to/jess/mentorship-resources-19p0
Thanks again for participating in our program.
Good luck!
Liana

View file

@ -1,37 +0,0 @@
<p>
Hey!
</p>
<p>
Let me get straight to the point: your mentee is
<b><a href="https://dev.to/<%= @mentee.username %>">@<%= @mentee.username %></a></b>. We had you two automatically follow each other, so you can find them
<b><a href="https://dev.to/connect">DEV Connect</a></b>, and introduce yourself!
</p>
<p>
A few notes:
</p>
<ul>
<li>
Every person is different so every mentor/mentee relationship is unique. We expect some mentorships to last longer than others and hope that at the very least, youll have made a solid new connection.
</li>
<li>
We expect everyone to abide by our
<b><a href="https://dev.to/code-of-conduct">Code of Conduct</a></b>, especially in this setting. Should your mentee demonstrate inappropriate behavior, please contact us immediately.
</li>
<li>
If you feel like this was a mismatch, or if your mentee is unresponsive after several days, let us know.
</li>
<li>
We highly recommend setting goals and expectations with your mentee from Day 1.
</li>
<li>
To help you all get started, weve put together some
<b><a href="https://dev.to/jess/mentorship-resources-19p0">Mentorship Resources</a></b>
</li>
</ul>
<p>
Thank you for volunteering your time to help someone along in their career. As this is the very first iteration of DEV Mentorships, please let us know if theres anything we can do to better support you and your mentee.
</p>
<p>
Thanks again. You are awesome.
</p>
Liana

View file

@ -1,18 +0,0 @@
Hey!
Let me get straight to the point: your mentee is: https://dev.to/<%= @mentee.username %> . We had you two automatically follow each other, so you can find them DEV Connect: https://dev.to/connect, and introduce yourself!
A few notes:
- Every person is different so every mentor/mentee relationship is unique.
- We expect some mentorships to last longer than others and hope that at the very least, youll have made a solid new connection.
- We expect everyone to abide by our Code of Conduct: https://dev.to/code-of-conduct, especially in this setting. Should your mentee demonstrate inappropriate behavior, please contact us immediately.
- If you feel like this was a mismatch, or if your mentee is unresponsive after several days, let us know.
- We highly recommend setting goals and expectations with your mentee from Day 1.
- To help you all get started, weve put together some resources: https://dev.to/jess/mentorship-resources-19p0
Thank you for volunteering your time to help someone along in their career. As this is the very first iteration of DEV Mentorships, please let us know if theres anything we can do to better support you and your mentee.
Thanks again. You are awesome.
Liana

View file

@ -1,45 +0,0 @@
<h2>This is currently a <strong>*beta program*</strong> for community members to help one another.</h2>
<p>If you're interested in participating as a mentor, mentee, or both, please indicate below and we will be in contact via email.</p>
<%= form_for(@user) do |f| %>
<h3>Offering Help</h3>
<p><em>
<% if @user.mentor_form_updated_at? %>
Last Updated: <%= @user.mentor_form_updated_at.strftime("%b %d, %Y") %>
<% end %>
</em></p>
<div class="field checkbox-label-first">
<%= f.label :offering_mentorship, "I'd like to be a mentor!" %>
<%= f.check_box :offering_mentorship %>
</div>
<div class="field">
<p>Please share the top 3 technologies/concepts you'd be comfortable working on with your mentee, how much experience you currently have (0-10, 10 being super duper expert), and anything else you'd like us to know.</p>
<%= f.text_area :mentor_description, placeholder: "For example:\n\n1. Vim - 6, I love teaching people how to use vim because I really believe it increases productivity.\n\nI don't think I'd be comfortable teaching a total beginner. ", maxlength: 750 %>
</div>
<h3>Seeking Help</h3>
<p><em>
<% if @user.mentee_form_updated_at? %>
Last Updated:
<%= @user.mentee_form_updated_at.strftime("%b %d, %Y") %>
<% end %>
</em></p>
<div class="field checkbox-label-first">
<%= f.label :seeking_mentorship, "I'm looking for a mentor!" %>
<%= f.check_box :seeking_mentorship %>
</div>
<div class="field">
<%= f.label :mentee_description, "How can we help?" %>
<p>Please share the top 3 technologies/concepts you'd like to work on with your mentor, how much experience you currently have (0-10, 0 being no experience at all), and why you're interested in learning more. Please also share your general technical background and career goals.</p>
<%= f.text_area(
:mentee_description,
placeholder: "For example:\n\n1. React - 1, I walked through the tutorial on the React website, but I'm feeling lost. I see React listed in lots of job descriptions so I'd like to learn how to utilize the framework.\n\n"\
"I graduated from a coding bootcamp 3 months ago and my goal is to land my first developer role. I learned jQuery in the program.",
maxlength: 750,
) %>
</div>
<div class="field">
<label></label>
<%= f.hidden_field :tab, value: @tab %>
<%= f.submit "SUBMIT", class: "cta" %>
</div>
<% end %>

View file

@ -0,0 +1,10 @@
class RemoveMentorshipColumnsFromUser < ActiveRecord::Migration[5.2]
def change
remove_column :users, :mentee_description, :text
remove_column :users, :mentee_form_updated_at, :datetime
remove_column :users, :mentor_description, :text
remove_column :users, :mentor_form_updated_at, :datetime
remove_column :users, :offering_mentorship, :boolean
remove_column :users, :seeking_mentorship, :boolean
end
end

View file

@ -0,0 +1,13 @@
class DropMentorRelationships < ActiveRecord::Migration[5.2]
def change
drop_table :mentor_relationships do |t|
t.integer :mentor_id, null: false
t.integer :mentee_id, null: false
t.boolean :active, default: true
t.timestamps
t.index :mentee_id
t.index :mentor_id
t.index %i[mentee_id mentor_id], unique: true
end
end
end

View file

@ -481,17 +481,6 @@ ActiveRecord::Schema.define(version: 2019_06_19_153428) do
t.integer "user_id"
end
create_table "mentor_relationships", force: :cascade do |t|
t.boolean "active", default: true
t.datetime "created_at", null: false
t.integer "mentee_id", null: false
t.integer "mentor_id", null: false
t.datetime "updated_at", null: false
t.index ["mentee_id", "mentor_id"], name: "index_mentor_relationships_on_mentee_id_and_mentor_id", unique: true
t.index ["mentee_id"], name: "index_mentor_relationships_on_mentee_id"
t.index ["mentor_id"], name: "index_mentor_relationships_on_mentor_id"
end
create_table "messages", force: :cascade do |t|
t.bigint "chat_channel_id", null: false
t.datetime "created_at", null: false
@ -895,7 +884,6 @@ ActiveRecord::Schema.define(version: 2019_06_19_153428) do
t.text "base_cover_letter"
t.string "behance_url"
t.string "bg_color_hex"
t.text "cached_chat_channel_memberships"
t.boolean "checked_code_of_conduct", default: false
t.integer "comments_count", default: 0, null: false
t.string "config_font", default: "default"
@ -964,15 +952,10 @@ ActiveRecord::Schema.define(version: 2019_06_19_153428) do
t.string "mastodon_url"
t.string "medium_url"
t.datetime "membership_started_at"
t.text "mentee_description"
t.datetime "mentee_form_updated_at"
t.text "mentor_description"
t.datetime "mentor_form_updated_at"
t.boolean "mobile_comment_notifications", default: true
t.integer "monthly_dues", default: 0
t.string "mostly_work_with"
t.string "name"
t.boolean "offering_mentorship"
t.string "old_old_username"
t.string "old_username"
t.datetime "onboarding_package_form_submmitted_at"
@ -996,7 +979,6 @@ ActiveRecord::Schema.define(version: 2019_06_19_153428) do
t.boolean "saw_onboarding", default: true
t.integer "score", default: 0
t.string "secret"
t.boolean "seeking_mentorship"
t.string "shipping_address"
t.string "shipping_address_line_2"
t.string "shipping_city"
@ -1018,7 +1000,6 @@ ActiveRecord::Schema.define(version: 2019_06_19_153428) do
t.string "stackoverflow_url"
t.string "stripe_id_code"
t.text "summary"
t.text "summary_html"
t.string "tabs_or_spaces"
t.string "text_color_hex"
t.string "text_only_name"

View file

@ -1,16 +0,0 @@
require "rails_helper"
RSpec.describe MentorshipMatcher do
let(:user_one) { create(:user) }
let(:user_two) { create(:user) }
let(:user_three) { create(:user) }
let(:user_four) { create(:user) }
let(:user_five) { create(:user) }
it "matches the correct pair of users" do
mentor_ids = [user_one.id, user_two.id, user_three.id]
mentee_ids = [user_three.id, user_four.id, user_five.id]
described_class.match_mentees_and_mentors(mentee_ids, mentor_ids)
expect(MentorRelationship.last.mentee_id).to eq(user_five.id)
end
end

View file

@ -20,8 +20,8 @@ RSpec.describe UserSimilarity, vcr: {} do
end
it "Is affected by non-stop words" do
user.mentee_description = "Hot dogs languages punk rock hello"
dissimilar_user.mentor_description = "Hot dogs languages punk rock hello "
user.summary = "Hot dogs languages punk rock hello"
dissimilar_user.summary = "Hot dogs languages punk rock hello "
similar_score = UserSimilarity.new(user, similar_user).score
dissimilar_score = UserSimilarity.new(user, dissimilar_user).score
expect(similar_score).to be < dissimilar_score

View file

@ -271,70 +271,6 @@ RSpec.describe NotifyMailer, type: :mailer do
end
end
describe "#mentee_email" do
let(:mentee) { user }
let(:mentor) { user2 }
it "renders proper subject" do
email = described_class.mentee_email(mentee, mentor)
expect(email.subject).to eq("You have been matched with a DEV mentor!")
end
it "renders proper from" do
email = described_class.mentee_email(mentee, mentor)
expect(email.from).to eq(["liana@dev.to"])
end
it "renders proper receiver" do
email = described_class.mentee_email(mentee, mentor)
expect(email.to).to eq([mentee.email])
end
it "includes the tracking pixel" do
email = described_class.mentee_email(mentee, mentor)
expect(email.html_part.body).to include("open.gif")
end
it "includes UTM params" do
email = described_class.mentee_email(mentee, mentor)
expect(email.html_part.body).to include(CGI.escape("utm_medium=email"))
expect(email.html_part.body).to include(CGI.escape("utm_source=notify_mailer"))
expect(email.html_part.body).to include(CGI.escape("utm_campaign=mentee_email"))
end
end
describe "#mentor_email" do
let(:mentee) { user }
let(:mentor) { user2 }
it "renders proper subject" do
email = described_class.mentor_email(mentor, mentee)
expect(email.subject).to eq("You have been matched with a new DEV mentee!")
end
it "renders proper from" do
email = described_class.mentor_email(mentor, mentee)
expect(email.from).to eq(["liana@dev.to"])
end
it "renders proper receiver" do
email = described_class.mentor_email(mentor, mentee)
expect(email.to).to eq([mentor.email])
end
it "includes the tracking pixel" do
email = described_class.mentor_email(mentor, mentee)
expect(email.html_part.body).to include("open.gif")
end
it "includes UTM params" do
email = described_class.mentor_email(mentor, mentee)
expect(email.html_part.body).to include(CGI.escape("utm_medium=email"))
expect(email.html_part.body).to include(CGI.escape("utm_source=notify_mailer"))
expect(email.html_part.body).to include(CGI.escape("utm_campaign=mentor_email"))
end
end
describe "#export_email" do
it "renders proper subject" do
email = described_class.export_email(user, "attachment")

View file

@ -31,14 +31,6 @@ class NotifyMailerPreview < ActionMailer::Preview
NotifyMailer.new_badge_email(badge_achievement)
end
def mentee_email
NotifyMailer.mentee_email(User.first, User.second)
end
def mentor_email
NotifyMailer.mentor_email(User.first, User.second)
end
def tag_moderator_confirmation_email
NotifyMailer.tag_moderator_confirmation_email(User.first, "discuss")
end

View file

@ -1,54 +0,0 @@
require "rails_helper"
RSpec.describe MentorRelationship, type: :model do
let(:mentor) { create(:user) }
let(:mentee) { create(:user) }
let(:relationship) { MentorRelationship.new(mentor_id: mentor.id, mentee_id: mentee.id) }
describe "validations" do
subject { MentorRelationship.new(mentor: mentor, mentee: mentee) }
it { is_expected.to belong_to(:mentor) }
it { is_expected.to belong_to(:mentee) }
it { is_expected.to validate_uniqueness_of(:mentor_id).scoped_to(:mentee_id) }
end
it "is active" do
expect(relationship.active).to eq(true)
end
it "is not the same user" do
expect(MentorRelationship.new(mentor_id: mentor.id, mentee_id: mentor.id)).to be_invalid
end
it "makes the users follow one another" do
relationship.save!
expect(mentor.reload.following?(mentee)).to eq(true)
expect(mentee.reload.following?(mentor)).to eq(true)
end
it "sends an email to both users" do
relationship.save!
%w[mentor_email mentee_email].each do |campaign|
expect(EmailMessage.where(utm_campaign: campaign).count).to eq(1)
end
end
it "finds unmatched mentors" do
expect(MentorRelationship.unmatched_mentors.size).to eq(0)
new_mentor = create(:user, mentor_form_updated_at: Time.current, offering_mentorship: true)
expect(MentorRelationship.unmatched_mentors.size).to eq(1)
MentorRelationship.create(mentor_id: new_mentor.id, mentee_id: mentee.id)
expect(MentorRelationship.unmatched_mentors.size).to eq(0)
end
it "finds unmatched mentees" do
expect(MentorRelationship.unmatched_mentees.size).to eq(0)
new_mentee = create(:user, mentee_form_updated_at: Time.current, seeking_mentorship: true)
expect(MentorRelationship.unmatched_mentees.size).to eq(0)
new_mentee.update(mentee_description: "MENTEE")
expect(MentorRelationship.unmatched_mentees.size).to eq(1)
MentorRelationship.create(mentor_id: mentor.id, mentee_id: new_mentee.id)
expect(MentorRelationship.unmatched_mentors.size).to eq(0)
end
end

View file

@ -281,42 +281,6 @@ RSpec.describe User, type: :model do
expect(user.old_old_username).to eq(old_username)
end
it "updates mentor_form_updated_at at appropriate time" do
user.mentor_description = "hello"
user.save
expect(user.mentor_form_updated_at).not_to eq(nil)
end
it "updates mentee_form_updated_at at appropriate time" do
user.mentee_description = "hello"
user.save
expect(user.mentee_form_updated_at).not_to eq(nil)
end
it "does not allow mentee description to be too long" do
user.mentee_description = Faker::Lorem.paragraph_by_chars(1001)
user.save
expect(user.mentee_form_updated_at).to eq(nil)
end
it "does not allow mentor description to be too long" do
user.mentor_description = Faker::Lorem.paragraph_by_chars(1001)
user.save
expect(user.mentor_form_updated_at).to eq(nil)
end
it "allow mentee description to be the max length" do
user.mentee_description = Faker::Lorem.paragraph_by_chars(1000)
user.save
expect(user.mentee_form_updated_at).not_to eq(nil)
end
it "allow mentor description to be the max length" do
user.mentor_description = Faker::Lorem.paragraph_by_chars(1000)
user.save
expect(user.mentor_form_updated_at).not_to eq(nil)
end
it "does not allow too short or too long name" do
user.name = ""
expect(user).not_to be_valid

View file

@ -10,18 +10,16 @@ RSpec.describe "Following/Unfollowing", type: :request do
end
describe "PUT follows/:id" do
it "updates user to offer mentorship" do
it "updates follow points" do
user.follow(tag)
put "/follows/#{Follow.last.id}",
params: { follow: { points: 3.0 } }
put "/follows/#{Follow.last.id}", params: { follow: { points: 3.0 } }
expect(Follow.last.points).to eq(3.0)
end
it "does not update if follow does not belong to user" do
user_2.follow(tag)
expect do
put "/follows/#{Follow.last.id}",
params: { follow: { points: 3.0 } }
put "/follows/#{Follow.last.id}", params: { follow: { points: 3.0 } }
end.to raise_error(Pundit::NotAuthorizedError)
end
end

View file

@ -196,22 +196,6 @@ RSpec.describe "Internal::Users", type: :request do
end
end
context "when banning from mentorship" do
before do
user.update(offering_mentorship: true, mentor_description: "I want to be a mentor")
end
it "adds banned from mentorship role" do
patch "/internal/users/#{user.id}/user_status", params: { user: { toggle_mentorship: "1", mentorship_note: "banned" } }
expect(user.roles.first.name).to eq("banned_from_mentorship")
end
it "returns user to good standing if unbanned" do
put "/internal/users/#{user.id}", params: { user: { good_standing_user: "1" } }
expect(user.roles.count).to eq(0)
end
end
context "when banishing user" do
def banish_user
post "/internal/users/#{user.id}/banish"

View file

@ -1,80 +1,48 @@
require "rails_helper"
RSpec.describe "internal/users", type: :request do
let(:mentor) { create(:user) }
let(:mentee) { create(:user) }
let(:admin) { create(:user, :super_admin) }
let!(:user) { create(:user) }
let(:admin) { create(:user, :super_admin) }
before do
sign_in(admin)
mentor
mentee
end
describe "GETS /internal/users" do
it "renders to appropriate page" do
get "/internal/users"
expect(response.body).to include(mentor.username)
end
it "only displays mentors on ?state=mentors" do
get "/internal/users?state=mentors"
expect(response.body).not_to include(mentee.username)
end
it "only displays mentees on ?state=mentees" do
get "/internal/users?state=mentees"
expect(response.body).not_to include(mentor.username)
expect(response.body).to include(user.username)
end
end
describe "GET /internal/users/:id" do
it "renders to appropriate page" do
get "/internal/users/#{mentor.id}"
expect(response.body).to include(mentor.username)
end
end
describe "PUT internal/users/:id" do
it "pairs mentor with a mentee" do
put "/internal/users/#{mentor.id}", params: { user: { add_mentee: mentee.id } }
expect(mentee.mentors[0].id).to eq(mentor.id)
end
it "pairs mentee with a mentor" do
put "/internal/users/#{mentee.id}", params: { user: { add_mentor: mentor.id } }
expect(mentor.mentees[0].id).to eq(mentee.id)
end
it "deactivates existing mentorships when user is banned" do
put "/internal/users/#{mentor.id}", params: { user: { add_mentee: mentee.id } }
patch "/internal/users/#{mentor.id}/user_status", params: { user: { toggle_mentorship: "1", mentorship_note: "banned from mentorship" } }
expect(MentorRelationship.where(mentor_id: mentor.id)[0].active).to eq(false)
expect(mentor.notes[0].reason).to eq("banned_from_mentorship")
get "/internal/users/#{user.id}"
expect(response.body).to include(user.username)
end
end
describe "GET internal/users/:id/edit" do
it "redirects from /username/moderate" do
get "/#{mentor.username}/moderate"
expect(response).to redirect_to("/internal/users/#{mentor.id}")
get "/#{user.username}/moderate"
expect(response).to redirect_to("/internal/users/#{user.id}")
end
it "shows banish button for new users" do
get "/internal/users/#{mentor.id}/edit"
get "/internal/users/#{user.id}/edit"
expect(response.body).to include("Banish User for Spam!")
end
it "does not show banish button for non-admins" do
sign_out(admin)
expect { get "/internal/users/#{mentor.id}/edit" }.to raise_error(Pundit::NotAuthorizedError)
expect { get "/internal/users/#{user.id}/edit" }.to raise_error(Pundit::NotAuthorizedError)
end
end
describe "PUT internal/users/:id/edit" do
it "bans user for spam" do
post "/internal/users/#{mentor.id}/banish"
expect(mentor.reload.username).to include("spam")
post "/internal/users/#{user.id}/banish"
expect(user.reload.username).to include("spam")
end
end
end

View file

@ -26,14 +26,4 @@ RSpec.describe Moderator::ManageActivityAndRoles, type: :service do
expect(user.banned).to be false
expect(user.roles.count).to eq(0)
end
it "removes mentorship ban" do
user.add_role :banned_from_mentorship
described_class.handle_user_roles(
admin: admin,
user: user,
user_params: { toggle_mentorship: "0", mentorship_note: "Add to mentorship program" },
)
expect(user.banned_from_mentorship).to be false
end
end