docbrown/spec/models/organization_spec.rb
Ernesto Tagwerker 9ea3a8c67d
Upgrade to Rails 6.0 (#7658)
* Add dual booting logic to Gemfile

This might be helpful for the Rails 6.0 upgrade project.

* Add more than one gemfile to Travis' configuration

We want to see how the application behaves with more than one Rails versions:

- Gemfile -> Rails 5.2
- Gemfile.next -> Rails 6.0

This will help us figure out what needs to be addressed before migrating to Rails 6.0.

If you want to read more about this technique (dual booting) you can check out this page: https://www.fastruby.io/blog/upgrade-rails/dual-boot/dual-boot-with-rails-6-0-beta.html

* Fix joins

* Upgrade Gemfile.next.lock

* Make sure we're installing the correct versions of gems

* Add Rails 6 notes

* Update rubocop in Gemfile.next.lock

* Fix organization spec

* Fix page_views_spec

* Add Rails 6 and run rails app:update

* Remove some tricks

* Remove Gemfile.next for now

* Fix .content_type deprecation

* Fix deprecation of .where.not NAND/NOR behavior

* Fix deprecation of parameterized emails

* Fix specs

* Remove next flag for now

* Fix spec (hopefully)

* Add wait_for_javascript

* Fix spec, thanks @maestromac!

* Try without wait for javascript hack

* Remove unnecessary bin/update

* Remove file that snuck in the rebase

* Update the vendored gems

* Replace migrate+db:setup with db:prepare

* Update vendored gems

* Fix Gemfile.lock and update vendored stuff

* Fix Gemfile.lock to be the same as master's minus the changes

Co-authored-by: rhymes <rhymesete@gmail.com>
2020-06-04 11:54:25 +02:00

295 lines
11 KiB
Ruby

require "rails_helper"
RSpec.describe Organization, type: :model do
let(:organization) { create(:organization) }
describe "validations" do
describe "builtin validations" do
subject { organization }
it { is_expected.to have_many(:api_secrets).through(:users) }
it { is_expected.to have_many(:articles) }
it { is_expected.to have_many(:listings) }
it { is_expected.to have_many(:collections) }
it { is_expected.to have_many(:credits) }
it { is_expected.to have_many(:display_ads) }
it { is_expected.to have_many(:notifications) }
it { is_expected.to have_many(:organization_memberships).dependent(:delete_all) }
it { is_expected.to have_many(:profile_pins) }
it { is_expected.to have_many(:sponsorships) }
it { is_expected.to have_many(:unspent_credits).class_name("Credit") }
it { is_expected.to have_many(:users).through(:organization_memberships) }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_presence_of(:summary) }
it { is_expected.to validate_presence_of(:url) }
it { is_expected.to validate_presence_of(:profile_image) }
it { is_expected.to validate_presence_of(:slug) }
it { is_expected.to validate_length_of(:cta_body_markdown).is_at_most(256) }
it { is_expected.to validate_length_of(:cta_button_text).is_at_most(20) }
it { is_expected.to validate_length_of(:secret).is_equal_to(100) }
it { is_expected.to validate_length_of(:name).is_at_most(50) }
it { is_expected.to validate_length_of(:slug).is_at_least(2).is_at_most(18) }
it { is_expected.to validate_length_of(:twitter_username).is_at_most(15) }
it { is_expected.to validate_length_of(:github_username).is_at_most(50) }
it { is_expected.to validate_length_of(:url).is_at_most(200) }
it { is_expected.to validate_length_of(:tag_line).is_at_most(60) }
it { is_expected.to validate_length_of(:proof).is_at_most(1500) }
it { is_expected.to validate_length_of(:location).is_at_most(64) }
it { is_expected.to validate_length_of(:email).is_at_most(64) }
it { is_expected.to validate_length_of(:company_size).is_at_most(7) }
it { is_expected.to validate_length_of(:story).is_at_most(640) }
it { is_expected.to validate_length_of(:tech_stack).is_at_most(640) }
it { is_expected.to validate_uniqueness_of(:secret).allow_nil }
it { is_expected.to validate_uniqueness_of(:slug).case_insensitive }
it { is_expected.not_to allow_value("#xyz").for(:bg_color_hex) }
it { is_expected.not_to allow_value("#xyz").for(:text_color_hex) }
it { is_expected.to allow_value("#aabbcc").for(:bg_color_hex) }
it { is_expected.to allow_value("#aabbcc").for(:text_color_hex) }
it { is_expected.to allow_value("#abc").for(:bg_color_hex) }
it { is_expected.to allow_value("#abc").for(:text_color_hex) }
it { is_expected.not_to allow_value("3.0").for(:company_size) }
it { is_expected.to allow_value("3").for(:company_size) }
end
end
context "when callbacks are triggered before save" do
it "generates a secret if set to empty string" do
organization.secret = ""
organization.save
expect(organization.reload.secret).not_to eq("")
end
it "generates a secret if set to nil" do
organization.secret = nil
organization.save
expect(organization.reload.secret).not_to be(nil)
end
end
context "when callbacks are triggered after commit" do
it "on update syncs elasticsearch data" do
article = create(:article, organization: organization)
sidekiq_perform_enqueued_jobs
new_org_name = "#{organization.name}+NEW"
organization.update(name: new_org_name)
sidekiq_perform_enqueued_jobs
expect(article.elasticsearch_doc.dig("_source", "organization", "name")).to eq(new_org_name)
end
it "on destroy removes data from elasticsearch" do
article = create(:article, organization: organization)
sidekiq_perform_enqueued_jobs
expect(article.elasticsearch_doc.dig("_source", "organization", "id")).to eq(organization.id)
organization.destroy
sidekiq_perform_enqueued_jobs
expect(article.elasticsearch_doc.dig("_source", "organization")).to be_nil
end
end
describe "#name" do
it "rejects names with over 50 characters" do
organization.name = "x" * 51
expect(organization).not_to be_valid
end
it "accepts names with 50 or less characters" do
organization.name = "x" * 50
expect(organization).to be_valid
end
end
describe "#summary" do
it "rejects summaries with over 250 characters" do
organization.summary = "x" * 251
expect(organization).not_to be_valid
end
it "accepts summaries with 250 or less characters" do
organization.summary = "x" * 250
expect(organization).to be_valid
end
end
describe "#text_color_hex" do
it "accepts hex color codes" do
organization.text_color_hex = Faker::Color.hex_color
expect(organization).to be_valid
end
it "rejects color names" do
organization.text_color_hex = Faker::Color.color_name
expect(organization).not_to be_valid
end
it "rejects RGB colors" do
organization.text_color_hex = Faker::Color.rgb_color
expect(organization).not_to be_valid
end
it "rejects wrong color format" do
organization.text_color_hex = "#FOOBAR"
expect(organization).not_to be_valid
end
end
describe "#slug" do
it "accepts properly formatted slug" do
organization.slug = "heyho"
expect(organization).to be_valid
end
it "accepts properly formatted slug with numbers" do
organization.slug = "HeyHo2"
expect(organization).to be_valid
end
it "rejects slug with spaces" do
organization.slug = "hey ho"
expect(organization).not_to be_valid
end
it "rejects slug with unacceptable character" do
organization.slug = "Hey&Ho"
expect(organization).not_to be_valid
end
it "downcases slug" do
organization.slug = "HaHaHa"
organization.save
expect(organization.slug).to eq("hahaha")
end
it "rejects reserved slug" do
organization = build(:organization, slug: "settings")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("reserved")).to be true
end
it "takes organization slug into account " do
create(:user, username: "lightalloy")
organization = build(:organization, slug: "lightalloy")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
it "takes podcast slug into account" do
create(:podcast, slug: "devpodcast")
organization = build(:organization, slug: "devpodcast")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
it "takes page slug into account" do
create(:page, slug: "needed_info_for_site")
organization = build(:organization, slug: "needed_info_for_site")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
it "takes sitemap into account" do
organization = build(:organization, slug: "sitemap-yo")
expect(organization).not_to be_valid
expect(organization.errors[:slug].to_s.include?("taken")).to be true
end
context "when callbacks are triggered after save" do
let(:organization) { build(:organization) }
before do
allow(Organizations::BustCacheWorker).to receive(:perform_async)
end
it "triggers cache busting on save" do
organization.save
expect(Organizations::BustCacheWorker).to have_received(:perform_async).with(organization.id, organization.slug)
end
end
end
describe "#url" do
it "accepts valid http url" do
organization.url = "http://ben.com"
expect(organization).to be_valid
end
it "accepts valid secure http url" do
organization.url = "https://ben.com"
expect(organization).to be_valid
end
it "rejects invalid http url" do
organization.url = "ben.com"
expect(organization).not_to be_valid
end
end
describe "#check_for_slug_change" do
let(:user) { create(:user) }
it "properly updates the slug/username" do
random_new_slug = "slug_#{rand(10_000)}"
organization.update(slug: random_new_slug)
expect(organization.slug).to eq(random_new_slug)
end
it "updates old_slug to original slug if slug was changed" do
original_slug = organization.slug
organization.update(slug: "slug_#{rand(10_000)}")
expect(organization.old_slug).to eq(original_slug)
end
it "updates old_old_slug properly if slug was changed and there was an old_slug" do
original_slug = organization.slug
organization.update(slug: "something_else")
organization.update(slug: "another_slug")
expect(organization.old_old_slug).to eq(original_slug)
end
context "when dealing with organization articles" do
before do
create(:organization_membership, user: user, organization: organization, type_of_user: "admin")
create(:article, organization: organization, user: user)
end
it "updates the paths of the organization's articles" do
new_slug = "slug_#{rand(10_000)}"
sidekiq_perform_enqueued_jobs(only: Organizations::UpdateOrganizationArticlesPathsWorker) do
organization.update(slug: new_slug)
end
article = Article.find_by(organization_id: organization.id)
expect(article.path).to include(new_slug)
end
it "updates article cached_organizations" do
new_slug = "slug_#{rand(10_000)}"
sidekiq_perform_enqueued_jobs(only: Organizations::UpdateOrganizationArticlesPathsWorker) do
organization.update(slug: new_slug)
end
article = Article.find_by(organization_id: organization.id)
expect(article.cached_organization.slug).to eq(new_slug)
end
end
end
describe "#enough_credits?" do
it "returns false if the user has less unspent credits than neeed" do
expect(organization.enough_credits?(1)).to be(false)
end
it "returns true if the user has the exact amount of unspent credits" do
create(:credit, organization: organization, spent: false)
expect(organization.enough_credits?(1)).to be(true)
end
it "returns true if the user has more unspent credits than needed" do
create_list(:credit, 2, organization: organization, spent: false)
expect(organization.enough_credits?(1)).to be(true)
end
end
end