* feat: add customizable signature position and separator options * fix: correct default value note for signatureSeparator and ensure reactivity * fix: correct watcher boolean conversion and add immediate ui_settings updates - Fix watchers to convert string props to boolean values for reactive refs - Add immediate event handlers for switch changes to update ui_settings in real-time - Ensure proper synchronization between switch states and user.ui_settings Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: split signature content and ui_settings updates to resolve persistence bug - Use updateUISettings store action for signature_position and signature_separator - Keep updateProfile for message_signature content only - Fixes FormData serialization issue that corrupted nested ui_settings object - Add diagnostic logging to verify data flow Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * clean: remove diagnostic console logging from updateSignature method - Remove temporary console.log statements added for verification - Keep core implementation that splits signature content and ui_settings updates - Keep console.error for proper error handling with eslint-disable comment - Implementation now ready for production use Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: updateUISettings call in updateSignature method * chore: move signature application to send-time and add button highlighting (#79) * fix: move signature application from editor manipulation to send-time - Remove addSignature/removeSignature/toggleSignatureInEditor from WootWriter - Remove signature logic from draft handling and canned response insertion - Apply signatures only in getMessagePayload during message sending - Add button highlighting for signature toggle when activated - Prevents signature duplication and persistence in editor content - Fixes signature position toggle bug Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: escape signature separator to prevent markdown setext heading interpretation - Escape '--' separator as '\--' in appendSignature to prevent H2 heading creation - Update removeSignature to handle escaped separators correctly - Fixes signature separator being rendered as markdown instead of plain text - Refactor nested ternary to fix ESLint error Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: prevent signature separator markdown interpretation in message processing - Add fix_signature_separator_markdown method to escape '--' separators - Update ensure_processed_message_content to fix separators before saving - Prevents signature separators from being interpreted as setext headings - Ensures correct message display in channels and email notifications Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: update separator format to use \n--\n instead of escaping - Change separator delimiter from '\--' to '\n--\n' format - Update removeSignature function to handle new separator format correctly - Simplify message processing since separators are already properly formatted - Ensures consistent separator handling across frontend and backend Co-Authored-By: cayo@fazer.ai <cayoproliveira@gmail.com> * fix: update signature delimiter format to include extra new lines * chore: remove comment about signature application logic * refactor: remove unused method and comments related to signature separator markdown processing * chore: simplify slash command detection by using updatedMessage directly * refactor: remove signature logic from draft message handling * refactor: simplify body empty check by removing signature manipulation logic --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: cayo@fazer.ai <cayoproliveira@gmail.com> * refactor: extract signature settings logic into a separate method * fix: handle nil ui_settings in signature position and separator methods * fix: update return value of findSignatureInBody to include position information * fix: update signature handling in findSignatureInBody and related methods * fix: adjust delimiter length handling in removeSignature function * test: add cases for appending, removing, and replacing signatures with various separators * test: add cases for signature position and separator handling * test: add cases for updating signature position and separator in ui_settings * fix: correct typo in comment for findSignatureInBody function * refactor: simplify translation function calls in MessageSignature component * chore: refactoring * chore: refactor * feat: switch -> select * chore: refactor and undo changes * chore: refactor and undo changes * chore: refactor * fix: remove old select component usage * chore: remove useless style --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: gabrieljablonski <contact@gabrieljablonski.com>
142 lines
4.5 KiB
Ruby
142 lines
4.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
require Rails.root.join 'spec/models/concerns/access_tokenable_shared.rb'
|
|
require Rails.root.join 'spec/models/concerns/avatarable_shared.rb'
|
|
|
|
RSpec.describe User do
|
|
let!(:user) { create(:user) }
|
|
|
|
context 'with validations' do
|
|
it { is_expected.to validate_presence_of(:email) }
|
|
end
|
|
|
|
context 'with associations' do
|
|
it { is_expected.to have_many(:accounts).through(:account_users) }
|
|
it { is_expected.to have_many(:account_users) }
|
|
it { is_expected.to have_many(:assigned_conversations).class_name('Conversation').dependent(:nullify) }
|
|
it { is_expected.to have_many(:inbox_members).dependent(:destroy_async) }
|
|
it { is_expected.to have_many(:notification_settings).dependent(:destroy_async) }
|
|
it { is_expected.to have_many(:messages) }
|
|
it { is_expected.to have_many(:reporting_events) }
|
|
it { is_expected.to have_many(:teams) }
|
|
end
|
|
|
|
describe 'concerns' do
|
|
it_behaves_like 'access_tokenable'
|
|
it_behaves_like 'avatarable'
|
|
end
|
|
|
|
describe 'pubsub_token' do
|
|
before { user.update(name: Faker::Name.name) }
|
|
|
|
it { expect(user.pubsub_token).not_to be_nil }
|
|
it { expect(user.saved_changes.keys).not_to eq('pubsub_token') }
|
|
|
|
context 'with rotate the pubsub_token' do
|
|
it 'changes the pubsub_token when password changes' do
|
|
pubsub_token = user.pubsub_token
|
|
user.password = Faker::Internet.password(special_characters: true)
|
|
user.save!
|
|
expect(user.pubsub_token).not_to eq(pubsub_token)
|
|
end
|
|
|
|
it 'will not change pubsub_token when other attributes change' do
|
|
pubsub_token = user.pubsub_token
|
|
user.name = Faker::Name.name
|
|
user.save!
|
|
expect(user.pubsub_token).to eq(pubsub_token)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'hmac_identifier' do
|
|
it 'return nil if CHATWOOT_INBOX_HMAC_KEY is not set' do
|
|
expect(user.hmac_identifier).to eq('')
|
|
end
|
|
|
|
it 'return value if CHATWOOT_INBOX_HMAC_KEY is set' do
|
|
ConfigLoader.new.process
|
|
i = InstallationConfig.find_by(name: 'CHATWOOT_INBOX_HMAC_KEY')
|
|
i.value = 'random_secret_key'
|
|
i.save!
|
|
GlobalConfig.clear_cache
|
|
|
|
expected_hmac_identifier = OpenSSL::HMAC.hexdigest('sha256', 'random_secret_key', user.email)
|
|
|
|
expect(user.hmac_identifier).to eq expected_hmac_identifier
|
|
end
|
|
end
|
|
|
|
context 'with sso_auth_token' do
|
|
it 'can generate multiple sso tokens which can be validated' do
|
|
sso_auth_token1 = user.generate_sso_auth_token
|
|
sso_auth_token2 = user.generate_sso_auth_token
|
|
expect(sso_auth_token1).present?
|
|
expect(sso_auth_token2).present?
|
|
expect(user.valid_sso_auth_token?(sso_auth_token1)).to be true
|
|
expect(user.valid_sso_auth_token?(sso_auth_token2)).to be true
|
|
end
|
|
|
|
it 'wont validate an invalid token' do
|
|
expect(user.valid_sso_auth_token?(SecureRandom.hex(32))).to be false
|
|
end
|
|
|
|
it 'wont validate an invalidated token' do
|
|
sso_auth_token = user.generate_sso_auth_token
|
|
user.invalidate_sso_auth_token(sso_auth_token)
|
|
expect(user.valid_sso_auth_token?(sso_auth_token)).to be false
|
|
end
|
|
end
|
|
|
|
describe 'access token' do
|
|
it 'creates a single access token upon user creation' do
|
|
new_user = create(:user)
|
|
token_count = AccessToken.where(owner: new_user).count
|
|
expect(token_count).to eq(1)
|
|
end
|
|
end
|
|
|
|
context 'when user changes the email' do
|
|
it 'mutates the value' do
|
|
user.email = 'user@example.com'
|
|
expect(user.will_save_change_to_email?).to be true
|
|
end
|
|
end
|
|
|
|
context 'when the supplied email is uppercase' do
|
|
it 'downcases the email on save' do
|
|
new_user = create(:user, email: 'Test123@test.com')
|
|
expect(new_user.email).to eq('test123@test.com')
|
|
end
|
|
end
|
|
|
|
context 'when the user does not have signature position set' do
|
|
it 'returns the default signature position' do
|
|
expect(user.signature_position).to eq('top')
|
|
end
|
|
end
|
|
|
|
context 'when the user has signature position set' do
|
|
it 'returns the user signature position' do
|
|
user.update!(ui_settings: { signature_position: 'bottom' })
|
|
|
|
expect(user.signature_position).to eq('bottom')
|
|
end
|
|
end
|
|
|
|
context 'when the user does not have signature separator set' do
|
|
it 'returns the default signature separator' do
|
|
expect(user.signature_separator).to eq('blank')
|
|
end
|
|
end
|
|
|
|
context 'when the user has signature separator set' do
|
|
it 'returns the user signature separator' do
|
|
user.update!(ui_settings: { signature_separator: '--' })
|
|
|
|
expect(user.signature_separator).to eq('--')
|
|
end
|
|
end
|
|
end
|