# frozen_string_literal: true require 'rails_helper' RSpec.describe User, type: :model do context "validations" do it { is_expected.to validate_presence_of(:email) } it "should validate that email addres is unqique" do subject.email = "text-email@example.com" is_expected.to validate_uniqueness_of(:email) .case_insensitive .with_message("has already been taken") end it { is_expected.to allow_values("one@example.com", "foo-bar@ed.ac.uk") .for(:email) } it { is_expected.not_to allow_values("example.com", "foo bar@ed.ac.uk") .for(:email) } it { is_expected.to allow_values(true, false).for(:active) } it { is_expected.not_to allow_value(nil).for(:active) } it { is_expected.to validate_presence_of(:firstname) } it { is_expected.to validate_presence_of(:surname) } it { is_expected.to validate_presence_of(:org) } end context "associations" do it { is_expected.to have_and_belong_to_many(:perms) } it { is_expected.to belong_to(:language) } it { is_expected.to belong_to(:org) } it { is_expected.to have_one(:pref) } it { is_expected.to have_many(:answers) } it { is_expected.to have_many(:notes) } it { is_expected.to have_many(:exported_plans) } it { is_expected.to have_many(:roles).dependent(:destroy) } it { is_expected.to have_many(:plans).through(:roles) } it { is_expected.to have_many(:user_identifiers) } it { is_expected.to have_many(:identifier_schemes).through(:user_identifiers) } it { is_expected.to have_and_belong_to_many(:notifications).dependent(:destroy) } it { is_expected.to have_and_belong_to_many(:notifications) .join_table("notification_acknowledgements") } end describe "#active_for_authentication?" do let!(:user) { build(:user) } subject { user.active_for_authentication? } context "when user is active" do before do user.active = true end it { is_expected.to eql(true) } end context "when user is not active" do before do user.active = false end it { is_expected.to eql(false) } end end describe "#save" do context "when org has changed and can change org" do let!(:user) do create(:user, other_organisation: "Foo bar", api_token: "barfoo") end let!(:org) { create(:org, is_other: true) } subject { user.save } before do user.perms << create(:perm, :change_org_affiliation) user.perms << create(:perm, :use_api) user.perms << create(:perm, :modify_guidance) user.perms << create(:perm, :modify_templates) user.perms << create(:perm, :change_org_affiliation) user.perms << create(:perm, :add_organisations) user.org = create(:org) end it "sets other_organisation to nil" do expect { subject }.to change { user.other_organisation }.to(nil) end it "doesn't destroy user roles" do expect { user.save }.not_to change { user.perms.count } end it "doesn't reset api_token" do expect { subject }.not_to change { user.api_token } end end context "when org has changed and can not change org" do let!(:user) do create(:user, other_organisation: "Foo bar", api_token: "barfoo") end let!(:org) { create(:org, is_other: true) } before do user.perms << create(:perm, :use_api) user.perms << create(:perm, :modify_guidance) user.perms << create(:perm, :modify_templates) user.org = create(:org) end it "sets other_organisation to nil" do expect { user.save }.to change { user.other_organisation }.to(nil) end it "destroy's user perms" do expect { user.save }.to change { user.perms.count }.to(0) end it "resets api_token to blank string" do expect { user.save }.to change { user.api_token }.to(nil) end end end describe "#get_locale" do let!(:user) { build(:user) } subject { user.get_locale } context "when user language present" do let(:language) { create(:language) } before do user.update(language: language) end it { is_expected.to eql(language.abbreviation) } end context "when user language and org absent" do before do user.language = nil user.org = nil end it { is_expected.to be_nil } end context "when user language absent and org present" do before do user.language = nil @locale = user.org.get_locale end it { is_expected.to eql(@locale) } end end describe "#name" do let!(:user) { build(:user) } subject { user.name } context "when user firstname and surname not blank and use_email set to false" do subject { user.name(false) } before do @name = "#{user.firstname} #{user.surname}".strip end it { is_expected.to eql(@name) } end context "when user firstname is blank and surname is not blank and use_email set to false" do subject { user.name(false) } before do user.firstname = "" @name = user.surname.to_s.strip end it { is_expected.to eql(@name) } end context "when user firstname is blank and surname is not blank and use_email set to false" do subject { user.name(false) } before do user.surname = "" @name = user.firstname.to_s.strip end it { is_expected.to eql(@name) } end context "when user firstname is blank and surname is not blank use_email set to true (by default)" do before do user.surname = "" @email = user.email end it { is_expected.to eql(@email) } end context "when user firstname is not blank and surname is blank use_email set to true (by default)" do before do user.firstname = "" @email = user.email end it { is_expected.to eql(@email) } end context "when user firstname is not blank and surname is blank use_email set to true (by default)" do before do user.firstname = "" @email = user.email end it { is_expected.to eql(@email) } end end describe "#identifier_for" do let!(:user) { create(:user) } let!(:identifier_scheme) { create(:identifier_scheme) } subject { user.identifier_for(identifier_scheme) } context "when user has an user_identifier present" do let!(:user_identifier) do create(:user_identifier, identifier_scheme: identifier_scheme, user: user) end it { is_expected.to eql(user_identifier) } end context "when user has no user_identifier present" do let!(:user_identifier) { create(:user_identifier, user: user) } it { is_expected.not_to eql(user_identifier) } end end describe "#can_super_admin?" do subject { user.can_super_admin? } context "when user includes Perm with name 'add_organisations'" do let!(:perms) { create_list(:perm, 1, name: "add_organisations") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end context "when user includes Perm with name 'grant_api_to_orgs'" do let!(:perms) { create_list(:perm, 1, name: "grant_api_to_orgs") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end context "when user includes Perm with name 'change_org_affiliation'" do let!(:perms) { create_list(:perm, 1, name: "change_org_affiliation") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end end describe "#can_org_admin?" do subject { user.can_org_admin? } context "when user includes Perm with name 'grant_permissions'" do let!(:perms) { create_list(:perm, 1, name: "grant_permissions") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end context "when user includes Perm with name 'modify_guidance'" do let!(:perms) { create_list(:perm, 1, name: "modify_guidance") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end context "when user includes Perm with name 'modify_templates'" do let!(:perms) { create_list(:perm, 1, name: "modify_templates") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end context "when user includes Perm with name 'change_org_details'" do let!(:perms) { create_list(:perm, 1, name: "change_org_details") } let!(:user) { create(:user, perms: perms) } it { is_expected.to eq(true) } end end describe "#can_add_orgs?" do let!(:perms) { create_list(:perm, 1, name: "add_organisations") } let!(:user) { create(:user, perms: perms) } subject { user.can_add_orgs? } it { is_expected.to eq(true) } end describe "#can_change_org?" do let!(:perms) { create_list(:perm, 1, name: "change_org_affiliation") } let!(:user) { create(:user, perms: perms) } subject { user.can_change_org? } it { is_expected.to eq(true) } end describe "#can_grant_permissions?" do let!(:perms) { create_list(:perm, 1, name: "grant_permissions") } let!(:user) { create(:user, perms: perms) } subject { user.can_grant_permissions? } it { is_expected.to eq(true) } end describe "#can_modify_templates?" do let!(:perms) { create_list(:perm, 1, name: "modify_templates") } let!(:user) { create(:user, perms: perms) } subject { user.can_modify_templates? } it { is_expected.to eq(true) } end describe "#can_modify_guidance?" do let!(:perms) { create_list(:perm, 1, name: "modify_guidance") } let!(:user) { create(:user, perms: perms) } subject { user.can_modify_guidance? } it { is_expected.to eq(true) } end describe "#can_use_api?" do let!(:perms) { create_list(:perm, 1, name: "use_api") } let!(:user) { create(:user, perms: perms) } subject { user.can_use_api? } it { is_expected.to eq(true) } end describe "#can_modify_org_details?" do let!(:perms) { create_list(:perm, 1, name: "change_org_details") } let!(:user) { create(:user, perms: perms) } subject { user.can_modify_org_details? } it { is_expected.to eq(true) } end describe "#can_grant_api_to_orgs?" do let!(:perms) { create_list(:perm, 1, name: "grant_api_to_orgs") } let!(:user) { create(:user, perms: perms) } subject { user.can_grant_api_to_orgs? } it { is_expected.to eq(true) } end describe "#remove_token!" do subject { user.remove_token! } context "when user is not a new record and api_token is not blank" do let!(:user) { create(:user, api_token: "an token string") } it { expect { subject }.to change { user.api_token }.to(nil) } end context "when user is not a new record and api_token is nil" do let!(:user) { create(:user, api_token: nil) } it { expect { subject }.not_to change { user.api_token } } end context "when user is not a new record and api_token is an empty string" do let!(:user) { create(:user, api_token: "") } it { expect { subject }.to change { user.api_token }.to(nil) } end context "when user is a new record" do let!(:user) { build(:user, api_token: "an token string") } it { expect { subject }.not_to change { user.api_token } } end end describe "#keep_or_generate_token!" do subject { user.keep_or_generate_token! } context "when user is not a new record and api_token is an empty string" do let!(:user) { create(:user, api_token: "") } it { expect { subject }.to change { user.api_token } } end context "when user is not a new record and api_token is nil" do let!(:user) { create(:user, api_token: nil) } it { expect { subject }.to change { user.api_token } } end context "when user is a new record and api_token is an empty string" do let!(:user) { build(:user, api_token: "") } it { expect { subject }.not_to change { user.api_token } } end end describe ".from_omniauth" do let!(:user) { create(:user) } let!(:auth) { stub(provider: "auth-provider", uid: "1234abcd") } subject { User.from_omniauth(auth) } context "when User has UserIdentifier, with different ID" do let!(:identifier_scheme) do create(:identifier_scheme, name: "auth-provider") end let!(:user_identifier) do create(:user_identifier, user: user, identifier_scheme: identifier_scheme, identifier: "another-auth-uid") end it { is_expected.to be_nil } end context "when user Identifier and auth Provider are the same string" do let!(:identifier_scheme) do create(:identifier_scheme, name: "auth-provider") end let!(:user_identifier) do create(:user_identifier, user: user, identifier_scheme: identifier_scheme, identifier: "1234abcd") end it { is_expected.to eql(user) } end end describe "#get_preferences" do let!(:user) { create(:user) } let!(:key) { :email } subject { user.get_preferences(key) } context "when the User doesn't have thier own Pref" do it "returns the default value" do Pref.expects(:default_settings) .returns(email: { foo: { "bar" => "baz" } }) expect(subject).to eql({ foo: { "bar" => "baz" } }) end end context "when the User has thier own Pref" do before do create(:pref, user: user, settings: { email: { foo: { bar: "bam" } } }) end it "returns the User's value" do Pref.expects(:default_settings) .returns(email: { foo: { bar: "baz" } }) expect(subject).to eql({ foo: { bar: "bam" } }) end end context "when the User's own Pref doesn't contain a new default" do before do create(:pref, user: user, settings: { email: { foo: { bar: "bam" } } }) end it "includes the default" do Pref.expects(:default_settings) .returns(email: { default: { val: true }, foo: { bar: "baz" } }) expect(subject).to eql({ default: { val: true }, foo: { bar: "bam" } }) end end end describe ".where_case_insensitive" do before do @user = create(:user, firstname: "Test") end subject { User.where_case_insensitive(:firstname, value) } context "when search value is capitalized" do let!(:value) { "TEST" } it { is_expected.to include(@user) } end context "when search value matches case" do let!(:value) { "Test" } it { is_expected.to include(@user) } end context "when search value is lowercase" do let!(:value) { "test" } it { is_expected.to include(@user) } end end describe "#acknowledge" do let!(:user) { create(:user) } subject { user.acknowledge(notification) } context "when notification is dismissable" do let!(:notification) { create(:notification, :dismissable) } it "adds the Notification to the User's notifications" do subject expect(user.notifications).to include(notification) end end context "when notification is not dismissable" do let!(:notification) { create(:notification) } it "doesn't add the Notification to the User's notifications" do subject expect(user.notifications).not_to include(notification) end end end end