mirror of
https://github.com/Retrospring/retrospring.git
synced 2025-01-19 10:16:03 +01:00
0f9c6f1e07
i'm sure there are many more typos waiting to happen. one thing we can already catch though is the usage of invalid TLDs. this makes use of my new TLDv gem -- the data it uses can be updated independently from the main gem.
246 lines
8.2 KiB
Ruby
246 lines
8.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
RSpec.describe User, type: :model do
|
|
let!(:me) { FactoryBot.create :user }
|
|
|
|
describe "basic assigns" do
|
|
before :each do
|
|
@user = User.new(
|
|
screen_name: "FunnyMeme2004",
|
|
password: "y_u_no_secure_password?",
|
|
email: "nice.meme@nsa.gov"
|
|
)
|
|
Profile.new(user: @user)
|
|
end
|
|
|
|
subject { @user }
|
|
|
|
it { should respond_to(:email) }
|
|
|
|
it "#email returns a string" do
|
|
expect(@user.email).to match "nice.meme@nsa.gov"
|
|
end
|
|
|
|
it "#motivation_header has a default value" do
|
|
expect(@user.profile.motivation_header).to match ""
|
|
end
|
|
|
|
it "does not save an invalid screen name" do
|
|
@user.screen_name = "$Funny-Meme-%&2004"
|
|
expect { @user.save! }.to raise_error(ActiveRecord::RecordInvalid)
|
|
end
|
|
end
|
|
|
|
describe "email validation" do
|
|
subject do
|
|
FactoryBot.build(:user, email: email).tap(&:validate).errors[:email]
|
|
end
|
|
|
|
shared_examples_for "valid email" do |example_email|
|
|
context "when email is #{example_email}" do
|
|
let(:email) { example_email }
|
|
|
|
it "does not have validation errors" do
|
|
expect(subject).to be_empty
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples_for "invalid email" do |example_email|
|
|
context "when email is #{example_email}" do
|
|
let(:email) { example_email }
|
|
|
|
it "has validation errors" do
|
|
expect(subject).not_to be_empty
|
|
end
|
|
end
|
|
end
|
|
|
|
include_examples "valid email", "ifyouusethismailyouarebanned@nilsding.org"
|
|
include_examples "valid email", "fritz.fantom@gmail.com"
|
|
include_examples "valid email", "fritz.fantom@columbiamail.co"
|
|
include_examples "valid email", "fritz.fantom@protonmail.com"
|
|
include_examples "valid email", "fritz.fantom@example.email"
|
|
include_examples "valid email", "fritz.fantom@enterprise.k8s.420stripes.k8s.needs.more.k8s.jira.atlassian.k8s.eu-central-1.s3.amazonaws.com"
|
|
include_examples "valid email", "fritz.fantom@emacs.horse"
|
|
include_examples "invalid email", "@jack"
|
|
|
|
# examples from the real world:
|
|
|
|
# .carrd is not a valid TLD
|
|
include_examples "invalid email", "fritz.fantom@gmail.carrd"
|
|
# neither is .con
|
|
include_examples "invalid email", "fritz.fantom@gmail.con"
|
|
include_examples "invalid email", "fritz.fantom@protonmail.con"
|
|
# nor .coom
|
|
include_examples "invalid email", "fritz.fantom@gmail.coom"
|
|
# nor .cmo
|
|
include_examples "invalid email", "gustav.geldsack@gmail.cmo"
|
|
# nor .mail (.email is, however)
|
|
include_examples "invalid email", "fritz.fantom@proton.mail"
|
|
# common typos:
|
|
include_examples "invalid email", "fritz.fantom@fmail.com"
|
|
include_examples "invalid email", "fritz.fantom@gamil.com"
|
|
include_examples "invalid email", "fritz.fantom@gemail.com"
|
|
include_examples "invalid email", "fritz.fantom@gmaik.com"
|
|
include_examples "invalid email", "fritz.fantom@gmail.cm"
|
|
include_examples "invalid email", "fritz.fantom@gmail.co"
|
|
include_examples "invalid email", "fritz.fantom@gmail.co.uk"
|
|
include_examples "invalid email", "fritz.fantom@gmailcom"
|
|
include_examples "invalid email", "fritz.fantom@gmaile.com"
|
|
include_examples "invalid email", "fritz.fantom@gmaill.com"
|
|
include_examples "invalid email", "fritz.fantom@gmali.com"
|
|
include_examples "invalid email", "fritz.fantom@gnail.com"
|
|
include_examples "invalid email", "fritz.fantom@hotamil.com"
|
|
include_examples "invalid email", "fritz.fantom@hotmai.com"
|
|
include_examples "invalid email", "fritz.fantom@hotmailcom"
|
|
include_examples "invalid email", "fritz.fantom@hotmaill.com"
|
|
include_examples "invalid email", "fritz.fantom@iclooud.com"
|
|
include_examples "invalid email", "fritz.fantom@iclould.com"
|
|
include_examples "invalid email", "fritz.fantom@icluod.com"
|
|
include_examples "invalid email", "fritz.fantom@protonail.com"
|
|
include_examples "invalid email", "fritz.fantom@xn--gmail-xk1c.com"
|
|
include_examples "invalid email", "fritz.fantom@yahooo.com"
|
|
include_examples "invalid email", "fritz.fantom@☺gmail.com"
|
|
# gail.com would be a valid email address, but enough people typo it
|
|
#
|
|
# if you're the owner of that TLD and would like to use your email on
|
|
# retrospring, feel free to open a PR that removes this ;-)
|
|
include_examples "invalid email", "fritz.fantom@gail.com"
|
|
# no TLD
|
|
include_examples "invalid email", "fritz.fantom@gmail"
|
|
include_examples "invalid email", "fritz.fantom@protonmail"
|
|
end
|
|
|
|
describe "#to_param" do
|
|
subject { me.to_param }
|
|
|
|
it { is_expected.to eq me.screen_name }
|
|
end
|
|
|
|
# -- User::TimelineMethods --
|
|
|
|
shared_examples_for "result is blank" do
|
|
it "result is blank" do
|
|
expect(subject).to be_blank
|
|
end
|
|
end
|
|
|
|
describe "#timeline" do
|
|
subject { me.timeline }
|
|
|
|
context "user answered nothing and is not following anyone" do
|
|
include_examples "result is blank"
|
|
end
|
|
|
|
context "user answered something and is not following anyone" do
|
|
let(:answer) { FactoryBot.create(:answer, user: me) }
|
|
|
|
let(:expected) { [answer] }
|
|
|
|
it "includes the answer" do
|
|
expect(subject).to eq(expected)
|
|
end
|
|
end
|
|
|
|
context "user answered something and follows users with answers" do
|
|
let(:user1) { FactoryBot.create(:user) }
|
|
let(:user2) { FactoryBot.create(:user) }
|
|
let(:answer1) { FactoryBot.create(:answer, user: user1, created_at: 12.hours.ago) }
|
|
let(:answer2) { FactoryBot.create(:answer, user: me, created_at: 1.day.ago) }
|
|
let(:answer3) { FactoryBot.create(:answer, user: user2, created_at: 10.minutes.ago) }
|
|
let(:answer4) { FactoryBot.create(:answer, user: user1, created_at: Time.now.utc) }
|
|
|
|
let!(:expected) do
|
|
[answer4, answer3, answer1, answer2]
|
|
end
|
|
|
|
before(:each) do
|
|
me.follow(user1)
|
|
me.follow(user2)
|
|
end
|
|
|
|
it "includes all answers" do
|
|
expect(subject).to include(answer1)
|
|
expect(subject).to include(answer2)
|
|
expect(subject).to include(answer3)
|
|
expect(subject).to include(answer4)
|
|
end
|
|
|
|
it "result is ordered by created_at in reverse order" do
|
|
expect(subject).to eq(expected)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#cursored_timeline" do
|
|
let(:last_id) { nil }
|
|
|
|
subject { me.cursored_timeline(last_id: last_id, size: 3) }
|
|
|
|
context "user answered nothing and is not following anyone" do
|
|
include_examples "result is blank"
|
|
end
|
|
|
|
context "user answered something and is not following anyone" do
|
|
let(:answer) { FactoryBot.create(:answer, user: me) }
|
|
|
|
let(:expected) { [answer] }
|
|
|
|
it "includes the answer" do
|
|
expect(subject).to eq(expected)
|
|
end
|
|
end
|
|
|
|
context "user answered something and follows users with answers" do
|
|
let(:user1) { FactoryBot.create(:user) }
|
|
let(:user2) { FactoryBot.create(:user) }
|
|
let!(:answer1) { FactoryBot.create(:answer, user: me, created_at: 1.day.ago) }
|
|
let!(:answer2) { FactoryBot.create(:answer, user: user1, created_at: 12.hours.ago) }
|
|
let!(:answer3) { FactoryBot.create(:answer, user: user2, created_at: 10.minutes.ago) }
|
|
let!(:answer4) { FactoryBot.create(:answer, user: user1, created_at: Time.now.utc) }
|
|
|
|
before(:each) do
|
|
me.follow(user1)
|
|
me.follow(user2)
|
|
end
|
|
|
|
context "last_id is nil" do
|
|
let(:last_id) { nil }
|
|
let(:expected) do
|
|
[answer4, answer3, answer2]
|
|
end
|
|
|
|
it "includes three answers" do
|
|
expect(subject).not_to include(answer1)
|
|
expect(subject).to include(answer2)
|
|
expect(subject).to include(answer3)
|
|
expect(subject).to include(answer4)
|
|
end
|
|
|
|
it "result is ordered by created_at in reverse order" do
|
|
expect(subject).to eq(expected)
|
|
end
|
|
end
|
|
|
|
context "last_id is answer2.id" do
|
|
let(:last_id) { answer2.id }
|
|
|
|
it "includes answer1" do
|
|
expect(subject).to include(answer1)
|
|
expect(subject).not_to include(answer2)
|
|
expect(subject).not_to include(answer3)
|
|
expect(subject).not_to include(answer4)
|
|
end
|
|
end
|
|
|
|
context "last_id is answer1.id" do
|
|
let(:last_id) { answer1.id }
|
|
|
|
include_examples "result is blank"
|
|
end
|
|
end
|
|
end
|
|
end
|