Revert "chore: Upgrade Rails to 7.2.2 and update Gemfile dependencies (#11037)"
This reverts commit ef6ba8aabd.
This commit is contained in:
@@ -279,10 +279,10 @@ jobs:
|
|||||||
echo -en "\nINSTALLATION_ENV=circleci" >> ".env"
|
echo -en "\nINSTALLATION_ENV=circleci" >> ".env"
|
||||||
echo -en "\nOPENSEARCH_URL=http://localhost:9200" >> ".env"
|
echo -en "\nOPENSEARCH_URL=http://localhost:9200" >> ".env"
|
||||||
|
|
||||||
# Database setup (match GitHub Actions flow)
|
# Database setup
|
||||||
- run:
|
- run:
|
||||||
name: Create database + load schema
|
name: Run DB migrations
|
||||||
command: bundle exec rake db:create db:schema:load
|
command: bundle exec rails db:chatwoot_prepare
|
||||||
|
|
||||||
# Run backend tests (parallelized)
|
# Run backend tests (parallelized)
|
||||||
- run:
|
- run:
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ plugins:
|
|||||||
- rubocop-performance
|
- rubocop-performance
|
||||||
- rubocop-rails
|
- rubocop-rails
|
||||||
- rubocop-rspec
|
- rubocop-rspec
|
||||||
- rubocop-rspec_rails
|
|
||||||
- rubocop-factory_bot
|
- rubocop-factory_bot
|
||||||
|
|
||||||
require:
|
require:
|
||||||
@@ -204,12 +203,6 @@ RSpec/MultipleExpectations:
|
|||||||
RSpec/MultipleMemoizedHelpers:
|
RSpec/MultipleMemoizedHelpers:
|
||||||
Max: 14
|
Max: 14
|
||||||
|
|
||||||
RSpecRails/InferredSpecType:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
RSpecRails/NegationBeValid:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# custom rules
|
# custom rules
|
||||||
UseFromEmail:
|
UseFromEmail:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
- **Ruby Version**: Manage Ruby via `rbenv` and install the version listed in `.ruby-version` (e.g., `rbenv install $(cat .ruby-version)`)
|
- **Ruby Version**: Manage Ruby via `rbenv` and install the version listed in `.ruby-version` (e.g., `rbenv install $(cat .ruby-version)`)
|
||||||
- **rbenv setup**: Before running any `bundle` or `rspec` commands, init rbenv in your shell (`eval "$(rbenv init -)"`) so the correct Ruby/Bundler versions are used
|
- **rbenv setup**: Before running any `bundle` or `rspec` commands, init rbenv in your shell (`eval "$(rbenv init -)"`) so the correct Ruby/Bundler versions are used
|
||||||
- Always prefer `bundle exec` for Ruby CLI tasks (rspec, rake, rubocop, etc.)
|
- Always prefer `bundle exec` for Ruby CLI tasks (rspec, rake, rubocop, etc.)
|
||||||
- **Test env**: Specs should run without `.env`. If present, temporarily rename it (e.g., `.env` -> `.env.bak`) while running specs and restore afterward.
|
|
||||||
|
|
||||||
## Code Style
|
## Code Style
|
||||||
|
|
||||||
|
|||||||
23
Gemfile
23
Gemfile
@@ -3,10 +3,8 @@ source 'https://rubygems.org'
|
|||||||
ruby '3.4.4'
|
ruby '3.4.4'
|
||||||
|
|
||||||
##-- base gems for rails --##
|
##-- base gems for rails --##
|
||||||
|
gem 'rack-cors', '2.0.0', require: 'rack/cors'
|
||||||
gem 'rack-cors', require: 'rack/cors'
|
gem 'rails', '~> 7.1'
|
||||||
gem 'rails', '~> 7.2.0'
|
|
||||||
|
|
||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', require: false
|
gem 'bootsnap', require: false
|
||||||
|
|
||||||
@@ -33,9 +31,7 @@ gem 'haikunator'
|
|||||||
# Template parsing safely
|
# Template parsing safely
|
||||||
gem 'liquid'
|
gem 'liquid'
|
||||||
# Parse Markdown to HTML
|
# Parse Markdown to HTML
|
||||||
# ref: https://github.com/gjtorikian/commonmarker/issues/358
|
gem 'commonmarker'
|
||||||
# can upgrade one this issue is fixed
|
|
||||||
gem 'commonmarker', '~> 0.23.11'
|
|
||||||
# Validate Data against JSON Schema
|
# Validate Data against JSON Schema
|
||||||
gem 'json_schemer'
|
gem 'json_schemer'
|
||||||
# used in swagger build
|
# used in swagger build
|
||||||
@@ -53,7 +49,9 @@ gem 'csv-safe'
|
|||||||
|
|
||||||
##-- for active storage --##
|
##-- for active storage --##
|
||||||
gem 'aws-sdk-s3', require: false
|
gem 'aws-sdk-s3', require: false
|
||||||
gem 'azure-blob', require: false
|
# original gem isn't maintained actively
|
||||||
|
# we wanted updated version of faraday which is a dependency for slack-ruby-client
|
||||||
|
gem 'azure-storage-blob', git: 'https://github.com/chatwoot/azure-storage-ruby', branch: 'chatwoot', require: false
|
||||||
gem 'google-cloud-storage', '>= 1.48.0', require: false
|
gem 'google-cloud-storage', '>= 1.48.0', require: false
|
||||||
gem 'image_processing'
|
gem 'image_processing'
|
||||||
|
|
||||||
@@ -91,9 +89,9 @@ gem 'jwt'
|
|||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
|
|
||||||
# super admin
|
# super admin
|
||||||
gem 'administrate'
|
gem 'administrate', '>= 0.20.1'
|
||||||
gem 'administrate-field-active_storage'
|
gem 'administrate-field-active_storage', '>= 1.0.3'
|
||||||
gem 'administrate-field-belongs_to_search'
|
gem 'administrate-field-belongs_to_search', '>= 0.9.0'
|
||||||
|
|
||||||
##--- gems for pubsub service ---##
|
##--- gems for pubsub service ---##
|
||||||
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
|
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/
|
||||||
@@ -133,7 +131,7 @@ gem 'sentry-sidekiq', '>= 5.19.0', require: false
|
|||||||
##-- background job processing --##
|
##-- background job processing --##
|
||||||
gem 'sidekiq', '>= 7.3.1'
|
gem 'sidekiq', '>= 7.3.1'
|
||||||
# We want cron jobs
|
# We want cron jobs
|
||||||
gem 'sidekiq-cron', '>= 2.3.1'
|
gem 'sidekiq-cron', '>= 1.12.0'
|
||||||
# for sidekiq healthcheck
|
# for sidekiq healthcheck
|
||||||
gem 'sidekiq_alive'
|
gem 'sidekiq_alive'
|
||||||
|
|
||||||
@@ -264,7 +262,6 @@ group :development, :test do
|
|||||||
gem 'rubocop-performance', require: false
|
gem 'rubocop-performance', require: false
|
||||||
gem 'rubocop-rails', require: false
|
gem 'rubocop-rails', require: false
|
||||||
gem 'rubocop-rspec', require: false
|
gem 'rubocop-rspec', require: false
|
||||||
gem 'rubocop-rspec_rails', require: false
|
|
||||||
gem 'rubocop-factory_bot', require: false
|
gem 'rubocop-factory_bot', require: false
|
||||||
gem 'seed_dump'
|
gem 'seed_dump'
|
||||||
gem 'shoulda-matchers'
|
gem 'shoulda-matchers'
|
||||||
|
|||||||
385
Gemfile.lock
385
Gemfile.lock
@@ -1,89 +1,110 @@
|
|||||||
GIT
|
GIT
|
||||||
remote: https://github.com/chatwoot/devise-secure_password
|
remote: https://github.com/chatwoot/azure-storage-ruby
|
||||||
revision: 479987594b576dbf23aed8dbd962e78342bc683c
|
revision: 9957cf899d33a285b5dfe15bdb875292398e392b
|
||||||
branch: chatwoot
|
branch: chatwoot
|
||||||
specs:
|
specs:
|
||||||
devise-secure_password (2.1.0)
|
azure-storage-blob (2.0.3)
|
||||||
|
azure-storage-common (~> 2.0)
|
||||||
|
nokogiri (~> 1, >= 1.10.8)
|
||||||
|
azure-storage-common (2.0.4)
|
||||||
|
faraday (~> 2.0)
|
||||||
|
faraday-follow_redirects (~> 0.3.0)
|
||||||
|
faraday-net_http_persistent (~> 2.0)
|
||||||
|
net-http-persistent (~> 4.0)
|
||||||
|
nokogiri (~> 1, >= 1.10.8)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/chatwoot/devise-secure_password
|
||||||
|
revision: adcc85fe1babfe40feae73dbcae64d14fff86e69
|
||||||
|
branch: chatwoot
|
||||||
|
specs:
|
||||||
|
devise-secure_password (2.0.1)
|
||||||
devise (>= 4.0.0, < 5.0.0)
|
devise (>= 4.0.0, < 5.0.0)
|
||||||
railties (>= 5.0.0, < 8.0.0)
|
railties (>= 5.0.0, < 8.0.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (7.2.2.2)
|
actioncable (7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
actionmailbox (7.2.2.2)
|
actionmailbox (7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
activejob (= 7.2.2.2)
|
activejob (= 7.1.5.2)
|
||||||
activerecord (= 7.2.2.2)
|
activerecord (= 7.1.5.2)
|
||||||
activestorage (= 7.2.2.2)
|
activestorage (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
mail (>= 2.8.0)
|
mail (>= 2.7.1)
|
||||||
actionmailer (7.2.2.2)
|
net-imap
|
||||||
actionpack (= 7.2.2.2)
|
net-pop
|
||||||
actionview (= 7.2.2.2)
|
net-smtp
|
||||||
activejob (= 7.2.2.2)
|
actionmailer (7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
mail (>= 2.8.0)
|
actionview (= 7.1.5.2)
|
||||||
|
activejob (= 7.1.5.2)
|
||||||
|
activesupport (= 7.1.5.2)
|
||||||
|
mail (~> 2.5, >= 2.5.4)
|
||||||
|
net-imap
|
||||||
|
net-pop
|
||||||
|
net-smtp
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (7.2.2.2)
|
actionpack (7.1.5.2)
|
||||||
actionview (= 7.2.2.2)
|
actionview (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
racc
|
racc
|
||||||
rack (>= 2.2.4, < 3.2)
|
rack (>= 2.2.4)
|
||||||
rack-session (>= 1.0.1)
|
rack-session (>= 1.0.1)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
useragent (~> 0.16)
|
actiontext (7.1.5.2)
|
||||||
actiontext (7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
activerecord (= 7.1.5.2)
|
||||||
activerecord (= 7.2.2.2)
|
activestorage (= 7.1.5.2)
|
||||||
activestorage (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.2.2.2)
|
actionview (7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
active_record_query_trace (1.8)
|
active_record_query_trace (1.8)
|
||||||
activejob (7.2.2.2)
|
activejob (7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.2.2.2)
|
activemodel (7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
activerecord (7.2.2.2)
|
activerecord (7.1.5.2)
|
||||||
activemodel (= 7.2.2.2)
|
activemodel (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
timeout (>= 0.4.0)
|
timeout (>= 0.4.0)
|
||||||
activerecord-import (2.1.0)
|
activerecord-import (2.1.0)
|
||||||
activerecord (>= 4.2)
|
activerecord (>= 4.2)
|
||||||
activestorage (7.2.2.2)
|
activestorage (7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
activejob (= 7.2.2.2)
|
activejob (= 7.1.5.2)
|
||||||
activerecord (= 7.2.2.2)
|
activerecord (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
activesupport (7.2.2.2)
|
activesupport (7.1.5.2)
|
||||||
base64
|
base64
|
||||||
benchmark (>= 0.3)
|
benchmark (>= 0.3)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
connection_pool (>= 2.2.5)
|
connection_pool (>= 2.2.5)
|
||||||
drb
|
drb
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
logger (>= 1.4.2)
|
logger (>= 1.4.2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
mutex_m
|
||||||
securerandom (>= 0.3)
|
securerandom (>= 0.3)
|
||||||
tzinfo (~> 2.0, >= 2.0.5)
|
tzinfo (~> 2.0)
|
||||||
acts-as-taggable-on (12.0.0)
|
acts-as-taggable-on (12.0.0)
|
||||||
activerecord (>= 7.1, < 8.1)
|
activerecord (>= 7.1, < 8.1)
|
||||||
zeitwerk (>= 2.4, < 3.0)
|
zeitwerk (>= 2.4, < 3.0)
|
||||||
@@ -100,10 +121,10 @@ GEM
|
|||||||
administrate-field-active_storage (1.0.3)
|
administrate-field-active_storage (1.0.3)
|
||||||
administrate (>= 0.2.2)
|
administrate (>= 0.2.2)
|
||||||
rails (>= 7.0)
|
rails (>= 7.0)
|
||||||
administrate-field-belongs_to_search (0.10.0)
|
administrate-field-belongs_to_search (0.9.0)
|
||||||
administrate (>= 0.3, < 1.0)
|
administrate (>= 0.3, < 1.0)
|
||||||
jbuilder (~> 2)
|
jbuilder (~> 2)
|
||||||
rails (>= 4.2, < 8.0)
|
rails (>= 4.2, < 7.2)
|
||||||
selectize-rails (~> 0.6)
|
selectize-rails (~> 0.6)
|
||||||
ai-agents (0.7.0)
|
ai-agents (0.7.0)
|
||||||
ruby_llm (~> 1.8.2)
|
ruby_llm (~> 1.8.2)
|
||||||
@@ -120,8 +141,8 @@ GEM
|
|||||||
aws-sdk-s3 (~> 1, >= 1.123.0)
|
aws-sdk-s3 (~> 1, >= 1.123.0)
|
||||||
aws-sdk-sns (~> 1, >= 1.61.0)
|
aws-sdk-sns (~> 1, >= 1.61.0)
|
||||||
aws-eventstream (1.4.0)
|
aws-eventstream (1.4.0)
|
||||||
aws-partitions (1.1205.0)
|
aws-partitions (1.1198.0)
|
||||||
aws-sdk-core (3.241.3)
|
aws-sdk-core (3.240.0)
|
||||||
aws-eventstream (~> 1, >= 1.3.0)
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
aws-partitions (~> 1, >= 1.992.0)
|
aws-partitions (~> 1, >= 1.992.0)
|
||||||
aws-sigv4 (~> 1.9)
|
aws-sigv4 (~> 1.9)
|
||||||
@@ -129,11 +150,11 @@ GEM
|
|||||||
bigdecimal
|
bigdecimal
|
||||||
jmespath (~> 1, >= 1.6.1)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
logger
|
logger
|
||||||
aws-sdk-kms (1.120.0)
|
aws-sdk-kms (1.118.0)
|
||||||
aws-sdk-core (~> 3, >= 3.241.3)
|
aws-sdk-core (~> 3, >= 3.239.1)
|
||||||
aws-sigv4 (~> 1.5)
|
aws-sigv4 (~> 1.5)
|
||||||
aws-sdk-s3 (1.211.0)
|
aws-sdk-s3 (1.208.0)
|
||||||
aws-sdk-core (~> 3, >= 3.241.3)
|
aws-sdk-core (~> 3, >= 3.234.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.5)
|
aws-sigv4 (~> 1.5)
|
||||||
aws-sdk-sns (1.70.0)
|
aws-sdk-sns (1.70.0)
|
||||||
@@ -141,22 +162,20 @@ GEM
|
|||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sigv4 (1.12.1)
|
aws-sigv4 (1.12.1)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
azure-blob (0.5.9.1)
|
|
||||||
rexml
|
|
||||||
barnes (0.0.9)
|
barnes (0.0.9)
|
||||||
multi_json (~> 1)
|
multi_json (~> 1)
|
||||||
statsd-ruby (~> 1.1)
|
statsd-ruby (~> 1.1)
|
||||||
base64 (0.3.0)
|
base64 (0.3.0)
|
||||||
bcrypt (3.1.20)
|
bcrypt (3.1.20)
|
||||||
benchmark (0.5.0)
|
benchmark (0.4.1)
|
||||||
bigdecimal (4.0.1)
|
bigdecimal (3.2.2)
|
||||||
bindex (0.8.1)
|
bindex (0.8.1)
|
||||||
bootsnap (1.16.0)
|
bootsnap (1.16.0)
|
||||||
msgpack (~> 1.2)
|
msgpack (~> 1.2)
|
||||||
brakeman (5.4.1)
|
brakeman (5.4.1)
|
||||||
browser (5.3.1)
|
browser (5.3.1)
|
||||||
builder (3.3.0)
|
builder (3.3.0)
|
||||||
bullet (7.2.0)
|
bullet (8.0.7)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.11)
|
uniform_notifier (~> 1.11)
|
||||||
bundle-audit (0.1.0)
|
bundle-audit (0.1.0)
|
||||||
@@ -165,21 +184,17 @@ GEM
|
|||||||
bundler (>= 1.2.0, < 3)
|
bundler (>= 1.2.0, < 3)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
byebug (11.1.3)
|
byebug (11.1.3)
|
||||||
cgi (0.5.1)
|
|
||||||
childprocess (5.1.0)
|
childprocess (5.1.0)
|
||||||
logger (~> 1.5)
|
logger (~> 1.5)
|
||||||
climate_control (1.2.0)
|
climate_control (1.2.0)
|
||||||
coderay (1.1.3)
|
coderay (1.1.3)
|
||||||
commonmarker (0.23.11)
|
commonmarker (0.23.10)
|
||||||
concurrent-ruby (1.3.6)
|
concurrent-ruby (1.3.5)
|
||||||
connection_pool (3.0.2)
|
connection_pool (2.5.3)
|
||||||
crack (1.0.0)
|
crack (1.0.0)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
rexml
|
rexml
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
cronex (0.15.0)
|
|
||||||
tzinfo
|
|
||||||
unicode (>= 0.4.4.5)
|
|
||||||
csv (3.3.0)
|
csv (3.3.0)
|
||||||
csv-safe (3.3.1)
|
csv-safe (3.3.1)
|
||||||
csv (~> 3.0)
|
csv (~> 3.0)
|
||||||
@@ -189,15 +204,14 @@ GEM
|
|||||||
activerecord (>= 5.a)
|
activerecord (>= 5.a)
|
||||||
database_cleaner-core (~> 2.0.0)
|
database_cleaner-core (~> 2.0.0)
|
||||||
database_cleaner-core (2.0.1)
|
database_cleaner-core (2.0.1)
|
||||||
datadog (2.25.0)
|
datadog (2.19.0)
|
||||||
cgi
|
datadog-ruby_core_source (~> 3.4, >= 3.4.1)
|
||||||
datadog-ruby_core_source (~> 3.5, >= 3.5.0)
|
libdatadog (~> 18.1.0.1.0)
|
||||||
libdatadog (~> 24.0.1.1.0)
|
libddwaf (~> 1.24.1.0.3)
|
||||||
libddwaf (~> 1.30.0.0.0)
|
|
||||||
logger
|
logger
|
||||||
msgpack
|
msgpack
|
||||||
datadog-ruby_core_source (3.5.1)
|
datadog-ruby_core_source (3.4.1)
|
||||||
date (3.5.1)
|
date (3.4.1)
|
||||||
debug (1.8.0)
|
debug (1.8.0)
|
||||||
irb (>= 1.5.0)
|
irb (>= 1.5.0)
|
||||||
reline (>= 0.3.1)
|
reline (>= 0.3.1)
|
||||||
@@ -208,10 +222,10 @@ GEM
|
|||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (6.3.0)
|
devise-two-factor (6.1.0)
|
||||||
activesupport (>= 7.0, < 8.2)
|
activesupport (>= 7.0, < 8.1)
|
||||||
devise (>= 4.0, < 5.0)
|
devise (~> 4.0)
|
||||||
railties (>= 7.0, < 8.2)
|
railties (>= 7.0, < 8.1)
|
||||||
rotp (~> 6.0)
|
rotp (~> 6.0)
|
||||||
devise_token_auth (1.2.5)
|
devise_token_auth (1.2.5)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
@@ -230,31 +244,31 @@ GEM
|
|||||||
down (5.4.0)
|
down (5.4.0)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
drb (2.2.3)
|
drb (2.2.3)
|
||||||
dry-cli (1.4.1)
|
dry-cli (1.1.0)
|
||||||
dry-configurable (1.3.0)
|
dry-configurable (1.3.0)
|
||||||
dry-core (~> 1.1)
|
dry-core (~> 1.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
dry-core (1.2.0)
|
dry-core (1.1.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
logger
|
logger
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
dry-inflector (1.3.1)
|
dry-inflector (1.2.0)
|
||||||
dry-initializer (3.2.0)
|
dry-initializer (3.2.0)
|
||||||
dry-logic (1.6.0)
|
dry-logic (1.6.0)
|
||||||
bigdecimal
|
bigdecimal
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
dry-core (~> 1.1)
|
dry-core (~> 1.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
dry-schema (1.15.0)
|
dry-schema (1.14.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
dry-configurable (~> 1.0, >= 1.0.1)
|
dry-configurable (~> 1.0, >= 1.0.1)
|
||||||
dry-core (~> 1.1)
|
dry-core (~> 1.1)
|
||||||
dry-initializer (~> 3.2)
|
dry-initializer (~> 3.2)
|
||||||
dry-logic (~> 1.6)
|
dry-logic (~> 1.5)
|
||||||
dry-types (~> 1.8)
|
dry-types (~> 1.8)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
dry-types (1.9.0)
|
dry-types (1.8.3)
|
||||||
bigdecimal (>= 3.0)
|
bigdecimal (~> 3.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
dry-core (~> 1.0)
|
dry-core (~> 1.0)
|
||||||
dry-inflector (~> 1.0)
|
dry-inflector (~> 1.0)
|
||||||
@@ -268,9 +282,8 @@ GEM
|
|||||||
ruby2_keywords
|
ruby2_keywords
|
||||||
email-provider-info (0.0.1)
|
email-provider-info (0.0.1)
|
||||||
email_reply_trimmer (0.1.13)
|
email_reply_trimmer (0.1.13)
|
||||||
erb (6.0.1)
|
erubi (1.13.0)
|
||||||
erubi (1.13.1)
|
et-orbi (1.2.11)
|
||||||
et-orbi (1.3.0)
|
|
||||||
tzinfo
|
tzinfo
|
||||||
event_stream_parser (1.0.0)
|
event_stream_parser (1.0.0)
|
||||||
execjs (2.8.1)
|
execjs (2.8.1)
|
||||||
@@ -284,27 +297,34 @@ GEM
|
|||||||
railties (>= 5.0.0)
|
railties (>= 5.0.0)
|
||||||
faker (3.2.0)
|
faker (3.2.0)
|
||||||
i18n (>= 1.8.11, < 2)
|
i18n (>= 1.8.11, < 2)
|
||||||
faraday (2.9.0)
|
faraday (2.13.1)
|
||||||
faraday-net_http (>= 2.0, < 3.2)
|
faraday-net_http (>= 2.0, < 3.5)
|
||||||
faraday-mashify (1.0.2)
|
json
|
||||||
|
logger
|
||||||
|
faraday-follow_redirects (0.3.0)
|
||||||
|
faraday (>= 1, < 3)
|
||||||
|
faraday-mashify (1.0.0)
|
||||||
faraday (~> 2.0)
|
faraday (~> 2.0)
|
||||||
hashie
|
hashie
|
||||||
faraday-multipart (1.0.4)
|
faraday-multipart (1.0.4)
|
||||||
multipart-post (~> 2)
|
multipart-post (~> 2)
|
||||||
faraday-net_http (3.1.0)
|
faraday-net_http (3.4.0)
|
||||||
net-http
|
net-http (>= 0.5.0)
|
||||||
|
faraday-net_http_persistent (2.1.0)
|
||||||
|
faraday (~> 2.5)
|
||||||
|
net-http-persistent (~> 4.0)
|
||||||
faraday-retry (2.2.1)
|
faraday-retry (2.2.1)
|
||||||
faraday (~> 2.0)
|
faraday (~> 2.0)
|
||||||
faraday_middleware-aws-sigv4 (1.0.1)
|
faraday_middleware-aws-sigv4 (1.0.1)
|
||||||
aws-sigv4 (~> 1.0)
|
aws-sigv4 (~> 1.0)
|
||||||
faraday (>= 2.0, < 3)
|
faraday (>= 2.0, < 3)
|
||||||
fast-mcp (1.6.0)
|
fast-mcp (1.5.0)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
base64
|
base64
|
||||||
dry-schema (~> 1.14)
|
dry-schema (~> 1.14)
|
||||||
json (~> 2.0)
|
json (~> 2.0)
|
||||||
mime-types (~> 3.4)
|
mime-types (~> 3.4)
|
||||||
rack (>= 2.0, < 4.0)
|
rack (~> 3.1)
|
||||||
fcm (1.0.8)
|
fcm (1.0.8)
|
||||||
faraday (>= 1.0.0, < 3.0)
|
faraday (>= 1.0.0, < 3.0)
|
||||||
googleauth (~> 1)
|
googleauth (~> 1)
|
||||||
@@ -421,21 +441,19 @@ GEM
|
|||||||
http-cookie (1.0.5)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (2.3.0)
|
http-form_data (2.3.0)
|
||||||
httparty (0.24.2)
|
httparty (0.24.0)
|
||||||
csv
|
csv
|
||||||
mini_mime (>= 1.0.0)
|
mini_mime (>= 1.0.0)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.14.8)
|
i18n (1.14.7)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
image_processing (1.12.2)
|
image_processing (1.12.2)
|
||||||
mini_magick (>= 4.9.5, < 5)
|
mini_magick (>= 4.9.5, < 5)
|
||||||
ruby-vips (>= 2.0.17, < 3)
|
ruby-vips (>= 2.0.17, < 3)
|
||||||
io-console (0.8.2)
|
io-console (0.6.0)
|
||||||
irb (1.16.0)
|
irb (1.7.2)
|
||||||
pp (>= 0.6.0)
|
reline (>= 0.3.6)
|
||||||
rdoc (>= 4.0.0)
|
|
||||||
reline (>= 0.4.2)
|
|
||||||
iso-639 (0.3.8)
|
iso-639 (0.3.8)
|
||||||
csv
|
csv
|
||||||
jbuilder (2.11.5)
|
jbuilder (2.11.5)
|
||||||
@@ -446,7 +464,7 @@ GEM
|
|||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
json (2.12.0)
|
json (2.13.2)
|
||||||
json_refs (0.1.8)
|
json_refs (0.1.8)
|
||||||
hana
|
hana
|
||||||
json_schemer (0.2.24)
|
json_schemer (0.2.24)
|
||||||
@@ -461,7 +479,7 @@ GEM
|
|||||||
judoscale-sidekiq (1.8.2)
|
judoscale-sidekiq (1.8.2)
|
||||||
judoscale-ruby (= 1.8.2)
|
judoscale-ruby (= 1.8.2)
|
||||||
sidekiq (>= 5.0)
|
sidekiq (>= 5.0)
|
||||||
jwt (2.8.1)
|
jwt (2.10.1)
|
||||||
base64
|
base64
|
||||||
kaminari (1.2.2)
|
kaminari (1.2.2)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
@@ -488,15 +506,15 @@ GEM
|
|||||||
logger (~> 1.6)
|
logger (~> 1.6)
|
||||||
letter_opener (1.10.0)
|
letter_opener (1.10.0)
|
||||||
launchy (>= 2.2, < 4)
|
launchy (>= 2.2, < 4)
|
||||||
libdatadog (24.0.1.1.0)
|
libdatadog (18.1.0.1.0)
|
||||||
libdatadog (24.0.1.1.0-x86_64-linux)
|
libdatadog (18.1.0.1.0-x86_64-linux)
|
||||||
libddwaf (1.30.0.0.0)
|
libddwaf (1.24.1.0.3)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
libddwaf (1.30.0.0.0-arm64-darwin)
|
libddwaf (1.24.1.0.3-arm64-darwin)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
libddwaf (1.30.0.0.0-x86_64-darwin)
|
libddwaf (1.24.1.0.3-x86_64-darwin)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
libddwaf (1.30.0.0.0-x86_64-linux)
|
libddwaf (1.24.1.0.3-x86_64-linux)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
line-bot-api (1.28.0)
|
line-bot-api (1.28.0)
|
||||||
lint_roller (1.1.0)
|
lint_roller (1.1.0)
|
||||||
@@ -513,7 +531,7 @@ GEM
|
|||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
railties (>= 4)
|
railties (>= 4)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.25.0)
|
loofah (2.23.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
mail (2.8.1)
|
mail (2.8.1)
|
||||||
@@ -533,19 +551,21 @@ GEM
|
|||||||
mini_magick (4.12.0)
|
mini_magick (4.12.0)
|
||||||
mini_mime (1.1.5)
|
mini_mime (1.1.5)
|
||||||
mini_portile2 (2.8.9)
|
mini_portile2 (2.8.9)
|
||||||
minitest (5.27.0)
|
minitest (5.25.5)
|
||||||
mock_redis (0.36.0)
|
mock_redis (0.36.0)
|
||||||
ruby2_keywords
|
ruby2_keywords
|
||||||
msgpack (1.8.0)
|
msgpack (1.8.0)
|
||||||
multi_json (1.15.0)
|
multi_json (1.15.0)
|
||||||
multi_xml (0.8.1)
|
multi_xml (0.8.0)
|
||||||
bigdecimal (>= 3.1, < 5)
|
bigdecimal (>= 3.1, < 5)
|
||||||
multipart-post (2.3.0)
|
multipart-post (2.3.0)
|
||||||
mutex_m (0.3.0)
|
mutex_m (0.3.0)
|
||||||
neighbor (0.2.3)
|
neighbor (0.2.3)
|
||||||
activerecord (>= 5.2)
|
activerecord (>= 5.2)
|
||||||
net-http (0.4.1)
|
net-http (0.6.0)
|
||||||
uri
|
uri
|
||||||
|
net-http-persistent (4.0.2)
|
||||||
|
connection_pool (~> 2.2)
|
||||||
net-imap (0.4.20)
|
net-imap (0.4.20)
|
||||||
date
|
date
|
||||||
net-protocol
|
net-protocol
|
||||||
@@ -562,14 +582,14 @@ GEM
|
|||||||
newrelic_rpm (9.6.0)
|
newrelic_rpm (9.6.0)
|
||||||
base64
|
base64
|
||||||
nio4r (2.7.3)
|
nio4r (2.7.3)
|
||||||
nokogiri (1.19.0)
|
nokogiri (1.18.9)
|
||||||
mini_portile2 (~> 2.8.2)
|
mini_portile2 (~> 2.8.2)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.0-arm64-darwin)
|
nokogiri (1.18.9-arm64-darwin)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.0-x86_64-darwin)
|
nokogiri (1.18.9-x86_64-darwin)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nokogiri (1.19.0-x86_64-linux-gnu)
|
nokogiri (1.18.9-x86_64-linux-gnu)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
oauth (1.1.0)
|
oauth (1.1.0)
|
||||||
oauth-tty (~> 1.0, >= 1.0.1)
|
oauth-tty (~> 1.0, >= 1.0.1)
|
||||||
@@ -587,8 +607,9 @@ GEM
|
|||||||
oj (3.16.10)
|
oj (3.16.10)
|
||||||
bigdecimal (>= 3.0)
|
bigdecimal (>= 3.0)
|
||||||
ostruct (>= 0.2)
|
ostruct (>= 0.2)
|
||||||
omniauth (2.1.2)
|
omniauth (2.1.4)
|
||||||
hashie (>= 3.4.6)
|
hashie (>= 3.4.6)
|
||||||
|
logger
|
||||||
rack (>= 2.2.3)
|
rack (>= 2.2.3)
|
||||||
rack-protection
|
rack-protection
|
||||||
omniauth-google-oauth2 (1.1.3)
|
omniauth-google-oauth2 (1.1.3)
|
||||||
@@ -640,9 +661,6 @@ GEM
|
|||||||
activerecord (>= 5.2)
|
activerecord (>= 5.2)
|
||||||
activesupport (>= 5.2)
|
activesupport (>= 5.2)
|
||||||
pgvector (0.1.1)
|
pgvector (0.1.1)
|
||||||
pp (0.6.3)
|
|
||||||
prettyprint
|
|
||||||
prettyprint (0.2.0)
|
|
||||||
prism (1.4.0)
|
prism (1.4.0)
|
||||||
procore-sift (1.0.0)
|
procore-sift (1.0.0)
|
||||||
activerecord (>= 6.1)
|
activerecord (>= 6.1)
|
||||||
@@ -651,9 +669,6 @@ GEM
|
|||||||
method_source (~> 1.0)
|
method_source (~> 1.0)
|
||||||
pry-rails (0.3.9)
|
pry-rails (0.3.9)
|
||||||
pry (>= 0.10.4)
|
pry (>= 0.10.4)
|
||||||
psych (5.3.1)
|
|
||||||
date
|
|
||||||
stringio
|
|
||||||
public_suffix (6.0.2)
|
public_suffix (6.0.2)
|
||||||
puma (6.4.3)
|
puma (6.4.3)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
@@ -661,7 +676,7 @@ GEM
|
|||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
raabro (1.4.0)
|
raabro (1.4.0)
|
||||||
racc (1.8.1)
|
racc (1.8.1)
|
||||||
rack (3.1.19)
|
rack (3.2.3)
|
||||||
rack-attack (6.7.0)
|
rack-attack (6.7.0)
|
||||||
rack (>= 1.0, < 4)
|
rack (>= 1.0, < 4)
|
||||||
rack-contrib (2.5.0)
|
rack-contrib (2.5.0)
|
||||||
@@ -679,57 +694,53 @@ GEM
|
|||||||
rack-session (2.1.1)
|
rack-session (2.1.1)
|
||||||
base64 (>= 0.1.0)
|
base64 (>= 0.1.0)
|
||||||
rack (>= 3.0.0)
|
rack (>= 3.0.0)
|
||||||
rack-test (2.2.0)
|
rack-test (2.1.0)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rack-timeout (0.6.3)
|
rack-timeout (0.6.3)
|
||||||
rackup (2.3.1)
|
rackup (2.2.1)
|
||||||
rack (>= 3)
|
rack (>= 3)
|
||||||
rails (7.2.2.2)
|
rails (7.1.5.2)
|
||||||
actioncable (= 7.2.2.2)
|
actioncable (= 7.1.5.2)
|
||||||
actionmailbox (= 7.2.2.2)
|
actionmailbox (= 7.1.5.2)
|
||||||
actionmailer (= 7.2.2.2)
|
actionmailer (= 7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
actiontext (= 7.2.2.2)
|
actiontext (= 7.1.5.2)
|
||||||
actionview (= 7.2.2.2)
|
actionview (= 7.1.5.2)
|
||||||
activejob (= 7.2.2.2)
|
activejob (= 7.1.5.2)
|
||||||
activemodel (= 7.2.2.2)
|
activemodel (= 7.1.5.2)
|
||||||
activerecord (= 7.2.2.2)
|
activerecord (= 7.1.5.2)
|
||||||
activestorage (= 7.2.2.2)
|
activestorage (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.2.2.2)
|
railties (= 7.1.5.2)
|
||||||
rails-dom-testing (2.3.0)
|
rails-dom-testing (2.2.0)
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
minitest
|
minitest
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.6.2)
|
rails-html-sanitizer (1.6.1)
|
||||||
loofah (~> 2.21)
|
loofah (~> 2.21)
|
||||||
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
||||||
railties (7.2.2.2)
|
railties (7.1.5.2)
|
||||||
actionpack (= 7.2.2.2)
|
actionpack (= 7.1.5.2)
|
||||||
activesupport (= 7.2.2.2)
|
activesupport (= 7.1.5.2)
|
||||||
irb (~> 1.13)
|
irb
|
||||||
rackup (>= 1.0.0)
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0, >= 1.2.2)
|
thor (~> 1.0, >= 1.2.2)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
rake (13.3.1)
|
rake (13.2.1)
|
||||||
rb-fsevent (0.11.2)
|
rb-fsevent (0.11.2)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
rdoc (7.1.0)
|
|
||||||
erb
|
|
||||||
psych (>= 4.0.0)
|
|
||||||
tsort
|
|
||||||
redis (5.0.6)
|
redis (5.0.6)
|
||||||
redis-client (>= 0.9.0)
|
redis-client (>= 0.9.0)
|
||||||
redis-client (0.25.2)
|
redis-client (0.22.2)
|
||||||
connection_pool
|
connection_pool
|
||||||
redis-namespace (1.10.0)
|
redis-namespace (1.10.0)
|
||||||
redis (>= 4)
|
redis (>= 4)
|
||||||
regexp_parser (2.10.0)
|
regexp_parser (2.10.0)
|
||||||
reline (0.6.3)
|
reline (0.3.6)
|
||||||
io-console (~> 0.5)
|
io-console (~> 0.5)
|
||||||
representable (3.2.0)
|
representable (3.2.0)
|
||||||
declarative (< 0.1.0)
|
declarative (< 0.1.0)
|
||||||
@@ -799,10 +810,6 @@ GEM
|
|||||||
rubocop-rspec (3.6.0)
|
rubocop-rspec (3.6.0)
|
||||||
lint_roller (~> 1.1)
|
lint_roller (~> 1.1)
|
||||||
rubocop (~> 1.72, >= 1.72.1)
|
rubocop (~> 1.72, >= 1.72.1)
|
||||||
rubocop-rspec_rails (2.31.0)
|
|
||||||
lint_roller (~> 1.1)
|
|
||||||
rubocop (~> 1.72, >= 1.72.1)
|
|
||||||
rubocop-rspec (~> 3.5)
|
|
||||||
ruby-openai (7.3.1)
|
ruby-openai (7.3.1)
|
||||||
event_stream_parser (>= 0.3.0, < 2.0.0)
|
event_stream_parser (>= 0.3.0, < 2.0.0)
|
||||||
faraday (>= 1)
|
faraday (>= 1)
|
||||||
@@ -825,8 +832,9 @@ GEM
|
|||||||
faraday-net_http (>= 1)
|
faraday-net_http (>= 1)
|
||||||
faraday-retry (>= 1)
|
faraday-retry (>= 1)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
|
ruby_llm-schema (~> 0.2.1)
|
||||||
zeitwerk (~> 2)
|
zeitwerk (~> 2)
|
||||||
ruby_llm-schema (0.1.0)
|
ruby_llm-schema (0.2.5)
|
||||||
ruby_parser (3.20.0)
|
ruby_parser (3.20.0)
|
||||||
sexp_processor (~> 4.16)
|
sexp_processor (~> 4.16)
|
||||||
sass (3.7.4)
|
sass (3.7.4)
|
||||||
@@ -846,8 +854,9 @@ GEM
|
|||||||
parser
|
parser
|
||||||
scss_lint (0.60.0)
|
scss_lint (0.60.0)
|
||||||
sass (~> 3.5, >= 3.5.5)
|
sass (~> 3.5, >= 3.5.5)
|
||||||
searchkick (6.0.3)
|
searchkick (5.5.2)
|
||||||
activemodel (>= 7.2)
|
activemodel (>= 7.1)
|
||||||
|
hashie
|
||||||
securerandom (0.4.1)
|
securerandom (0.4.1)
|
||||||
seed_dump (3.3.1)
|
seed_dump (3.3.1)
|
||||||
activerecord (>= 4)
|
activerecord (>= 4)
|
||||||
@@ -876,17 +885,16 @@ GEM
|
|||||||
zeitwerk (~> 2.5)
|
zeitwerk (~> 2.5)
|
||||||
shoulda-matchers (5.3.0)
|
shoulda-matchers (5.3.0)
|
||||||
activesupport (>= 5.2.0)
|
activesupport (>= 5.2.0)
|
||||||
sidekiq (7.3.9)
|
sidekiq (7.3.1)
|
||||||
base64
|
concurrent-ruby (< 2)
|
||||||
connection_pool (>= 2.3.0)
|
connection_pool (>= 2.3.0)
|
||||||
logger
|
logger
|
||||||
rack (>= 2.2.4)
|
rack (>= 2.2.4)
|
||||||
redis-client (>= 0.22.2)
|
redis-client (>= 0.22.2)
|
||||||
sidekiq-cron (2.3.1)
|
sidekiq-cron (1.12.0)
|
||||||
cronex (>= 0.13.0)
|
fugit (~> 1.8)
|
||||||
fugit (~> 1.8, >= 1.11.1)
|
|
||||||
globalid (>= 1.0.1)
|
globalid (>= 1.0.1)
|
||||||
sidekiq (>= 6.5.0)
|
sidekiq (>= 6)
|
||||||
sidekiq_alive (2.5.0)
|
sidekiq_alive (2.5.0)
|
||||||
gserver (~> 0.0.1)
|
gserver (~> 0.0.1)
|
||||||
sidekiq (>= 5, < 9)
|
sidekiq (>= 5, < 9)
|
||||||
@@ -926,13 +934,12 @@ GEM
|
|||||||
squasher (0.7.2)
|
squasher (0.7.2)
|
||||||
stackprof (0.2.25)
|
stackprof (0.2.25)
|
||||||
statsd-ruby (1.5.0)
|
statsd-ruby (1.5.0)
|
||||||
stringio (3.2.0)
|
stripe (18.0.1)
|
||||||
stripe (18.1.0)
|
|
||||||
telephone_number (1.4.20)
|
telephone_number (1.4.20)
|
||||||
test-prof (1.2.1)
|
test-prof (1.2.1)
|
||||||
thor (1.5.0)
|
thor (1.4.0)
|
||||||
tidewave (0.4.1)
|
tidewave (0.2.0)
|
||||||
fast-mcp (~> 1.6.0)
|
fast-mcp (~> 1.5.0)
|
||||||
rack (>= 2.0)
|
rack (>= 2.0)
|
||||||
rails (>= 7.1.0)
|
rails (>= 7.1.0)
|
||||||
tilt (2.3.0)
|
tilt (2.3.0)
|
||||||
@@ -941,8 +948,7 @@ GEM
|
|||||||
i18n
|
i18n
|
||||||
timeout (0.4.3)
|
timeout (0.4.3)
|
||||||
trailblazer-option (0.1.2)
|
trailblazer-option (0.1.2)
|
||||||
tsort (0.2.0)
|
twilio-ruby (7.6.0)
|
||||||
twilio-ruby (5.77.0)
|
|
||||||
faraday (>= 0.9, < 3.0)
|
faraday (>= 0.9, < 3.0)
|
||||||
jwt (>= 1.5, < 3.0)
|
jwt (>= 1.5, < 3.0)
|
||||||
nokogiri (>= 1.6, < 2.0)
|
nokogiri (>= 1.6, < 2.0)
|
||||||
@@ -958,25 +964,21 @@ GEM
|
|||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.8.2)
|
unf_ext (0.0.8.2)
|
||||||
unicode (0.4.4.5)
|
|
||||||
unicode-display_width (3.1.4)
|
unicode-display_width (3.1.4)
|
||||||
unicode-emoji (~> 4.0, >= 4.0.4)
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
||||||
unicode-emoji (4.0.4)
|
unicode-emoji (4.0.4)
|
||||||
uniform_notifier (1.17.0)
|
uniform_notifier (1.17.0)
|
||||||
uri (1.1.1)
|
uri (1.0.4)
|
||||||
uri_template (0.7.0)
|
uri_template (0.7.0)
|
||||||
useragent (0.16.11)
|
|
||||||
valid_email2 (5.2.6)
|
valid_email2 (5.2.6)
|
||||||
activemodel (>= 3.2)
|
activemodel (>= 3.2)
|
||||||
mail (~> 2.5)
|
mail (~> 2.5)
|
||||||
version_gem (1.1.4)
|
version_gem (1.1.4)
|
||||||
vite_rails (3.0.20)
|
vite_rails (3.0.17)
|
||||||
railties (>= 5.1, < 9)
|
railties (>= 5.1, < 8)
|
||||||
vite_ruby (~> 3.0, >= 3.2.2)
|
vite_ruby (~> 3.0, >= 3.2.2)
|
||||||
vite_ruby (3.9.2)
|
vite_ruby (3.8.0)
|
||||||
dry-cli (>= 0.7, < 2)
|
dry-cli (>= 0.7, < 2)
|
||||||
logger (~> 1.6)
|
|
||||||
mutex_m
|
|
||||||
rack-proxy (~> 0.6, >= 0.6.1)
|
rack-proxy (~> 0.6, >= 0.6.1)
|
||||||
zeitwerk (~> 2.2)
|
zeitwerk (~> 2.2)
|
||||||
warden (1.2.9)
|
warden (1.2.9)
|
||||||
@@ -993,7 +995,7 @@ GEM
|
|||||||
addressable (>= 2.8.0)
|
addressable (>= 2.8.0)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff (>= 0.4.0, < 2.0.0)
|
hashdiff (>= 0.4.0, < 2.0.0)
|
||||||
websocket-driver (0.8.0)
|
websocket-driver (0.7.7)
|
||||||
base64
|
base64
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.5)
|
websocket-extensions (0.1.5)
|
||||||
@@ -1001,7 +1003,7 @@ GEM
|
|||||||
working_hours (1.4.1)
|
working_hours (1.4.1)
|
||||||
activesupport (>= 3.2)
|
activesupport (>= 3.2)
|
||||||
tzinfo
|
tzinfo
|
||||||
zeitwerk (2.7.4)
|
zeitwerk (2.6.17)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
arm64-darwin-20
|
arm64-darwin-20
|
||||||
@@ -1018,16 +1020,16 @@ DEPENDENCIES
|
|||||||
active_record_query_trace
|
active_record_query_trace
|
||||||
activerecord-import
|
activerecord-import
|
||||||
acts-as-taggable-on
|
acts-as-taggable-on
|
||||||
administrate
|
administrate (>= 0.20.1)
|
||||||
administrate-field-active_storage
|
administrate-field-active_storage (>= 1.0.3)
|
||||||
administrate-field-belongs_to_search
|
administrate-field-belongs_to_search (>= 0.9.0)
|
||||||
ai-agents (>= 0.7.0)
|
ai-agents (>= 0.7.0)
|
||||||
annotaterb
|
annotaterb
|
||||||
attr_extras
|
attr_extras
|
||||||
audited (~> 5.4, >= 5.4.1)
|
audited (~> 5.4, >= 5.4.1)
|
||||||
aws-actionmailbox-ses (~> 0)
|
aws-actionmailbox-ses (~> 0)
|
||||||
aws-sdk-s3
|
aws-sdk-s3
|
||||||
azure-blob
|
azure-storage-blob!
|
||||||
barnes
|
barnes
|
||||||
bootsnap
|
bootsnap
|
||||||
brakeman
|
brakeman
|
||||||
@@ -1036,7 +1038,7 @@ DEPENDENCIES
|
|||||||
bundle-audit
|
bundle-audit
|
||||||
byebug
|
byebug
|
||||||
climate_control
|
climate_control
|
||||||
commonmarker (~> 0.23.11)
|
commonmarker
|
||||||
csv-safe
|
csv-safe
|
||||||
database_cleaner
|
database_cleaner
|
||||||
datadog (~> 2.0)
|
datadog (~> 2.0)
|
||||||
@@ -1106,10 +1108,10 @@ DEPENDENCIES
|
|||||||
puma
|
puma
|
||||||
pundit
|
pundit
|
||||||
rack-attack (>= 6.7.0)
|
rack-attack (>= 6.7.0)
|
||||||
rack-cors
|
rack-cors (= 2.0.0)
|
||||||
rack-mini-profiler (>= 3.2.0)
|
rack-mini-profiler (>= 3.2.0)
|
||||||
rack-timeout
|
rack-timeout
|
||||||
rails (~> 7.2.0)
|
rails (~> 7.1)
|
||||||
redis
|
redis
|
||||||
redis-namespace
|
redis-namespace
|
||||||
responders (>= 3.1.1)
|
responders (>= 3.1.1)
|
||||||
@@ -1122,7 +1124,6 @@ DEPENDENCIES
|
|||||||
rubocop-performance
|
rubocop-performance
|
||||||
rubocop-rails
|
rubocop-rails
|
||||||
rubocop-rspec
|
rubocop-rspec
|
||||||
rubocop-rspec_rails
|
|
||||||
ruby-openai
|
ruby-openai
|
||||||
ruby_llm (>= 1.8.2)
|
ruby_llm (>= 1.8.2)
|
||||||
ruby_llm-schema
|
ruby_llm-schema
|
||||||
@@ -1136,7 +1137,7 @@ DEPENDENCIES
|
|||||||
shopify_api
|
shopify_api
|
||||||
shoulda-matchers
|
shoulda-matchers
|
||||||
sidekiq (>= 7.3.1)
|
sidekiq (>= 7.3.1)
|
||||||
sidekiq-cron (>= 2.3.1)
|
sidekiq-cron (>= 1.12.0)
|
||||||
sidekiq_alive
|
sidekiq_alive
|
||||||
simplecov (>= 0.21)
|
simplecov (>= 0.21)
|
||||||
simplecov_json_formatter
|
simplecov_json_formatter
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class Api::V1::Accounts::Integrations::LinearController < Api::V1::Accounts::Bas
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_issue
|
def create_issue
|
||||||
issue = linear_processor_service.create_issue(permitted_params.to_h.stringify_keys, Current.user)
|
issue = linear_processor_service.create_issue(permitted_params, Current.user)
|
||||||
if issue[:error]
|
if issue[:error]
|
||||||
render json: { error: issue[:error] }, status: :unprocessable_entity
|
render json: { error: issue[:error] }, status: :unprocessable_entity
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -20,9 +20,7 @@ class SuperAdmin::InstanceStatusesController < SuperAdmin::ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def instance_meta
|
def instance_meta
|
||||||
migrations_paths = ActiveRecord::Migrator.migrations_paths
|
@metrics['Database Migrations'] = ActiveRecord::Base.connection.migration_context.needs_migration? ? 'pending' : 'completed'
|
||||||
migrations_context = ActiveRecord::MigrationContext.new(migrations_paths)
|
|
||||||
@metrics['Database Migrations'] = migrations_context.needs_migration? ? 'pending' : 'completed'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def chatwoot_version
|
def chatwoot_version
|
||||||
|
|||||||
@@ -19,11 +19,6 @@ class InstallationConfig < ApplicationRecord
|
|||||||
# https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
|
# https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
|
||||||
# FIX ME : fixes breakage of installation config. we need to migrate.
|
# FIX ME : fixes breakage of installation config. we need to migrate.
|
||||||
# Fix configuration in application.rb
|
# Fix configuration in application.rb
|
||||||
#
|
|
||||||
# Note: This whole thing is because we store the installation config serialized in YAML in Database
|
|
||||||
# This serialized version stores HashWithIndifferentAccess, We could avoid all this complexity if we store the value as JSONB
|
|
||||||
# We could also avoid this issue if we migrate the installation config to JSONB
|
|
||||||
# We should do this migration at some point in time.
|
|
||||||
serialize :serialized_value, coder: YAML, type: ActiveSupport::HashWithIndifferentAccess
|
serialize :serialized_value, coder: YAML, type: ActiveSupport::HashWithIndifferentAccess
|
||||||
|
|
||||||
before_validation :set_lock
|
before_validation :set_lock
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class Integrations::Hook < ApplicationRecord
|
|||||||
include Reauthorizable
|
include Reauthorizable
|
||||||
|
|
||||||
attr_readonly :app_id, :account_id, :inbox_id, :hook_type
|
attr_readonly :app_id, :account_id, :inbox_id, :hook_type
|
||||||
before_validation :ensure_hook_type, on: :create
|
before_validation :ensure_hook_type
|
||||||
after_create :trigger_setup_if_crm
|
after_create :trigger_setup_if_crm
|
||||||
|
|
||||||
# TODO: Remove guard once encryption keys become mandatory (target 3-4 releases out).
|
# TODO: Remove guard once encryption keys become mandatory (target 3-4 releases out).
|
||||||
@@ -86,9 +86,7 @@ class Integrations::Hook < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def ensure_hook_type
|
def ensure_hook_type
|
||||||
return if app.blank?
|
self.hook_type = app.params[:hook_type] if app.present?
|
||||||
|
|
||||||
self.hook_type = app.params[:hook_type]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_settings_json_schema
|
def validate_settings_json_schema
|
||||||
|
|||||||
@@ -421,8 +421,6 @@ class Message < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def reindex_for_search
|
def reindex_for_search
|
||||||
return unless respond_to?(:reindex)
|
|
||||||
|
|
||||||
reindex(mode: :async)
|
reindex(mode: :async)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
# TODO: remove in a future version once online status is moved to account users
|
# TODO: remove in a future version once online status is moved to account users
|
||||||
# remove the column availability from users
|
# remove the column availability from users
|
||||||
enum :availability, { online: 0, offline: 1, busy: 2 }
|
enum availability: { online: 0, offline: 1, busy: 2 }
|
||||||
|
|
||||||
# The validation below has been commented out as it does not
|
# The validation below has been commented out as it does not
|
||||||
# work because :validatable in devise overrides this.
|
# work because :validatable in devise overrides this.
|
||||||
@@ -77,7 +77,7 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
validates :email, presence: true
|
validates :email, presence: true
|
||||||
|
|
||||||
serialize :otp_backup_codes, coder: JSON, type: Array
|
serialize :otp_backup_codes, type: Array
|
||||||
|
|
||||||
# Encrypt sensitive MFA fields
|
# Encrypt sensitive MFA fields
|
||||||
encrypts :otp_secret, deterministic: true
|
encrypts :otp_secret, deterministic: true
|
||||||
@@ -88,7 +88,7 @@ class User < ApplicationRecord
|
|||||||
accepts_nested_attributes_for :account_users
|
accepts_nested_attributes_for :account_users
|
||||||
|
|
||||||
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify, inverse_of: :assignee
|
has_many :assigned_conversations, foreign_key: 'assignee_id', class_name: 'Conversation', dependent: :nullify, inverse_of: :assignee
|
||||||
alias conversations assigned_conversations
|
alias_attribute :conversations, :assigned_conversations
|
||||||
has_many :csat_survey_responses, foreign_key: 'assigned_agent_id', dependent: :nullify, inverse_of: :assigned_agent
|
has_many :csat_survey_responses, foreign_key: 'assigned_agent_id', dependent: :nullify, inverse_of: :assigned_agent
|
||||||
has_many :reviewed_csat_survey_responses, foreign_key: 'review_notes_updated_by_id', class_name: 'CsatSurveyResponse',
|
has_many :reviewed_csat_survey_responses, foreign_key: 'review_notes_updated_by_id', class_name: 'CsatSurveyResponse',
|
||||||
dependent: :nullify, inverse_of: :review_notes_updated_by
|
dependent: :nullify, inverse_of: :review_notes_updated_by
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class Crm::Leadsquared::SetupService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_hook_settings(params)
|
def update_hook_settings(params)
|
||||||
@hook.settings = @hook.settings.merge(params.stringify_keys)
|
@hook.settings = @hook.settings.merge(params)
|
||||||
@hook.save!
|
@hook.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ end
|
|||||||
module Chatwoot
|
module Chatwoot
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
config.load_defaults 7.2
|
config.load_defaults 7.0
|
||||||
|
|
||||||
config.eager_load_paths << Rails.root.join('lib')
|
config.eager_load_paths << Rails.root.join('lib')
|
||||||
config.eager_load_paths << Rails.root.join('enterprise/lib')
|
config.eager_load_paths << Rails.root.join('enterprise/lib')
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ google:
|
|||||||
|
|
||||||
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
|
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
|
||||||
microsoft:
|
microsoft:
|
||||||
service: AzureBlob
|
service: AzureStorage
|
||||||
storage_account_name: <%= ENV.fetch('AZURE_STORAGE_ACCOUNT_NAME', '') %>
|
storage_account_name: <%= ENV.fetch('AZURE_STORAGE_ACCOUNT_NAME', '') %>
|
||||||
storage_access_key: <%= ENV.fetch('AZURE_STORAGE_ACCESS_KEY', '') %>
|
storage_access_key: <%= ENV.fetch('AZURE_STORAGE_ACCESS_KEY', '') %>
|
||||||
container: <%= ENV.fetch('AZURE_STORAGE_CONTAINER', '') %>
|
container: <%= ENV.fetch('AZURE_STORAGE_CONTAINER', '') %>
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ class ArticleKeyConverter
|
|||||||
|
|
||||||
def convert_key(id)
|
def convert_key(id)
|
||||||
verifier_name = 'ActiveStorage'
|
verifier_name = 'ActiveStorage'
|
||||||
secret_key_base = Rails.application.credentials.secret_key_base ||
|
key_generator = ActiveSupport::KeyGenerator.new(Rails.application.secrets.secret_key_base, iterations: 1000,
|
||||||
Rails.application.secrets.secret_key_base
|
|
||||||
key_generator = ActiveSupport::KeyGenerator.new(secret_key_base,
|
|
||||||
iterations: 1000,
|
|
||||||
hash_digest_class: OpenSSL::Digest::SHA1)
|
hash_digest_class: OpenSSL::Digest::SHA1)
|
||||||
key_generator = ActiveSupport::CachingKeyGenerator.new(key_generator)
|
key_generator = ActiveSupport::CachingKeyGenerator.new(key_generator)
|
||||||
secret = key_generator.generate_key(verifier_name.to_s)
|
secret = key_generator.generate_key(verifier_name.to_s)
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ RUN apk update && apk add --no-cache \
|
|||||||
tar \
|
tar \
|
||||||
build-base \
|
build-base \
|
||||||
tzdata \
|
tzdata \
|
||||||
yaml-dev \
|
|
||||||
pkgconf \
|
|
||||||
postgresql-dev \
|
postgresql-dev \
|
||||||
postgresql-client \
|
postgresql-client \
|
||||||
git \
|
git \
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class Seeders::Reports::MessageCreator
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_messages
|
def create_messages
|
||||||
message_count = rand(MESSAGES_PER_CONVERSATION..(MESSAGES_PER_CONVERSATION + 5))
|
message_count = rand(MESSAGES_PER_CONVERSATION..MESSAGES_PER_CONVERSATION + 5)
|
||||||
first_agent_reply = true
|
first_agent_reply = true
|
||||||
|
|
||||||
message_count.times do |i|
|
message_count.times do |i|
|
||||||
|
|||||||
@@ -144,8 +144,8 @@
|
|||||||
"prosemirror-model": "^1.22.3",
|
"prosemirror-model": "^1.22.3",
|
||||||
"size-limit": "^8.2.4",
|
"size-limit": "^8.2.4",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"vite": "5.4.21",
|
"vite": "^5.4.21",
|
||||||
"vite-plugin-ruby": "^5.1.1",
|
"vite-plugin-ruby": "^5.0.0",
|
||||||
"vitest": "3.0.5"
|
"vitest": "3.0.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
@@ -351,8 +351,8 @@ importers:
|
|||||||
specifier: 5.4.21
|
specifier: 5.4.21
|
||||||
version: 5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)
|
version: 5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)
|
||||||
vite-plugin-ruby:
|
vite-plugin-ruby:
|
||||||
specifier: ^5.1.1
|
specifier: ^5.0.0
|
||||||
version: 5.1.1(vite@5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0))
|
version: 5.0.0(vite@5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0))
|
||||||
vitest:
|
vitest:
|
||||||
specifier: 3.0.5
|
specifier: 3.0.5
|
||||||
version: 3.0.5(@types/node@22.7.0)(jsdom@27.2.0)(sass@1.79.3)(terser@5.33.0)
|
version: 3.0.5(@types/node@22.7.0)(jsdom@27.2.0)(sass@1.79.3)(terser@5.33.0)
|
||||||
@@ -4519,8 +4519,8 @@ packages:
|
|||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
vite-plugin-ruby@5.1.1:
|
vite-plugin-ruby@5.0.0:
|
||||||
resolution: {integrity: sha512-I1dXJq2ywdvTD2Cz5LYNcYLujqQ3eUxPoCjruRdfm2QBtHBY15NEeb6x5HuPM3T5S+y8S3p9fwRsieQQCjk0gg==}
|
resolution: {integrity: sha512-c8PjTp21Ah/ttgnNUyu0qvCXZI08Jr9I24oUKg3TRIRhF5GcOZ++6wtlTCrNFd9COEQbpXHxlRIXd/MEg0iZJw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: 5.4.21
|
vite: 5.4.21
|
||||||
|
|
||||||
@@ -6245,7 +6245,7 @@ snapshots:
|
|||||||
|
|
||||||
agent-base@6.0.2:
|
agent-base@6.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -7647,7 +7647,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@tootallnate/once': 2.0.0
|
'@tootallnate/once': 2.0.0
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.4.3
|
debug: 4.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -7661,7 +7661,7 @@ snapshots:
|
|||||||
https-proxy-agent@5.0.1:
|
https-proxy-agent@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.4.3
|
debug: 4.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -9599,9 +9599,9 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- terser
|
- terser
|
||||||
|
|
||||||
vite-plugin-ruby@5.1.1(vite@5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)):
|
vite-plugin-ruby@5.0.0(vite@5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.4.3
|
debug: 4.3.5
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
vite: 5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)
|
vite: 5.4.21(@types/node@22.7.0)(sass@1.79.3)(terser@5.33.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|||||||
@@ -1,22 +1,15 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe V2::ReportBuilder do
|
describe V2::ReportBuilder do
|
||||||
include ActiveJob::TestHelper
|
include ActiveJob::TestHelper
|
||||||
self.use_transactional_tests = false
|
let_it_be(:account) { create(:account) }
|
||||||
|
let_it_be(:label_1) { create(:label, title: 'Label_1', account: account) }
|
||||||
def truncate_test_data
|
let_it_be(:label_2) { create(:label, title: 'Label_2', account: account) }
|
||||||
connection = ActiveRecord::Base.connection
|
|
||||||
connection.truncate_tables(*connection.tables)
|
|
||||||
end
|
|
||||||
|
|
||||||
before { truncate_test_data }
|
|
||||||
|
|
||||||
let(:account) { create(:account) }
|
|
||||||
let!(:label_1) { create(:label, title: 'Label_1', account: account) }
|
|
||||||
let!(:label_2) { create(:label, title: 'Label_2', account: account) }
|
|
||||||
|
|
||||||
describe '#timeseries' do
|
describe '#timeseries' do
|
||||||
before do
|
# Use before_all to share expensive setup across all tests in this describe block
|
||||||
|
# This runs once instead of 21 times, dramatically speeding up the suite
|
||||||
|
before_all do
|
||||||
travel_to(Time.zone.today) do
|
travel_to(Time.zone.today) do
|
||||||
user = create(:user, account: account)
|
user = create(:user, account: account)
|
||||||
inbox = create(:inbox, account: account)
|
inbox = create(:inbox, account: account)
|
||||||
@@ -28,7 +21,7 @@ RSpec.describe V2::ReportBuilder do
|
|||||||
perform_enqueued_jobs do
|
perform_enqueued_jobs do
|
||||||
10.times do
|
10.times do
|
||||||
conversation = create(:conversation, account: account,
|
conversation = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: Time.zone.today)
|
created_at: Time.zone.today)
|
||||||
create_list(:message, 5, message_type: 'outgoing',
|
create_list(:message, 5, message_type: 'outgoing',
|
||||||
account: account, inbox: inbox,
|
account: account, inbox: inbox,
|
||||||
@@ -44,7 +37,7 @@ RSpec.describe V2::ReportBuilder do
|
|||||||
|
|
||||||
5.times do
|
5.times do
|
||||||
conversation = create(:conversation, account: account,
|
conversation = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: (Time.zone.today - 2.days))
|
created_at: (Time.zone.today - 2.days))
|
||||||
create_list(:message, 3, message_type: 'outgoing',
|
create_list(:message, 3, message_type: 'outgoing',
|
||||||
account: account, inbox: inbox,
|
account: account, inbox: inbox,
|
||||||
|
|||||||
@@ -2,19 +2,11 @@ require 'rails_helper'
|
|||||||
|
|
||||||
RSpec.describe V2::Reports::LabelSummaryBuilder do
|
RSpec.describe V2::Reports::LabelSummaryBuilder do
|
||||||
include ActiveJob::TestHelper
|
include ActiveJob::TestHelper
|
||||||
self.use_transactional_tests = false
|
|
||||||
|
|
||||||
def truncate_test_data
|
let_it_be(:account) { create(:account) }
|
||||||
connection = ActiveRecord::Base.connection
|
let_it_be(:label_1) { create(:label, title: 'label_1', account: account) }
|
||||||
connection.truncate_tables(*connection.tables)
|
let_it_be(:label_2) { create(:label, title: 'label_2', account: account) }
|
||||||
end
|
let_it_be(:label_3) { create(:label, title: 'label_3', account: account) }
|
||||||
|
|
||||||
before { truncate_test_data }
|
|
||||||
|
|
||||||
let(:account) { create(:account) }
|
|
||||||
let!(:label_1) { create(:label, title: 'label_1', account: account) }
|
|
||||||
let!(:label_2) { create(:label, title: 'label_2', account: account) }
|
|
||||||
let!(:label_3) { create(:label, title: 'label_3', account: account) }
|
|
||||||
|
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
@@ -100,7 +92,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
# Create conversations with label_1
|
# Create conversations with label_1
|
||||||
3.times do
|
3.times do
|
||||||
conversation = create(:conversation, account: account,
|
conversation = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: Time.zone.today)
|
created_at: Time.zone.today)
|
||||||
create_list(:message, 2, message_type: 'outgoing',
|
create_list(:message, 2, message_type: 'outgoing',
|
||||||
account: account, inbox: inbox,
|
account: account, inbox: inbox,
|
||||||
@@ -118,7 +110,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
# Create conversations with label_2
|
# Create conversations with label_2
|
||||||
2.times do
|
2.times do
|
||||||
conversation = create(:conversation, account: account,
|
conversation = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: Time.zone.today)
|
created_at: Time.zone.today)
|
||||||
create_list(:message, 1, message_type: 'outgoing',
|
create_list(:message, 1, message_type: 'outgoing',
|
||||||
account: account, inbox: inbox,
|
account: account, inbox: inbox,
|
||||||
@@ -237,7 +229,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
perform_enqueued_jobs do
|
perform_enqueued_jobs do
|
||||||
# Conversation within range
|
# Conversation within range
|
||||||
conversation_in_range = create(:conversation, account: account,
|
conversation_in_range = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: 2.days.ago)
|
created_at: 2.days.ago)
|
||||||
conversation_in_range.update_labels('label_1')
|
conversation_in_range.update_labels('label_1')
|
||||||
conversation_in_range.label_list
|
conversation_in_range.label_list
|
||||||
@@ -252,7 +244,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
|
|
||||||
# Conversation outside range (too old)
|
# Conversation outside range (too old)
|
||||||
conversation_out_of_range = create(:conversation, account: account,
|
conversation_out_of_range = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: 1.week.ago)
|
created_at: 1.week.ago)
|
||||||
conversation_out_of_range.update_labels('label_1')
|
conversation_out_of_range.update_labels('label_1')
|
||||||
conversation_out_of_range.label_list
|
conversation_out_of_range.label_list
|
||||||
@@ -294,7 +286,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
|
|
||||||
perform_enqueued_jobs do
|
perform_enqueued_jobs do
|
||||||
conversation = create(:conversation, account: account,
|
conversation = create(:conversation, account: account,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: Time.zone.today)
|
created_at: Time.zone.today)
|
||||||
conversation.update_labels('label_1')
|
conversation.update_labels('label_1')
|
||||||
conversation.label_list
|
conversation.label_list
|
||||||
@@ -331,8 +323,8 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
let(:account2_builder) do
|
let(:account2_builder) do
|
||||||
described_class.new(account: account2, params: {
|
described_class.new(account: account2, params: {
|
||||||
business_hours: false,
|
business_hours: false,
|
||||||
since: test_date.in_time_zone.to_i.to_s,
|
since: test_date.to_time.to_i.to_s,
|
||||||
until: test_date.end_of_day.in_time_zone.to_i.to_s,
|
until: test_date.end_of_day.to_time.to_i.to_s,
|
||||||
timezone_offset: 0
|
timezone_offset: 0
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@@ -351,7 +343,7 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
|
|
||||||
perform_enqueued_jobs do
|
perform_enqueued_jobs do
|
||||||
conversation = create(:conversation, account: account2,
|
conversation = create(:conversation, account: account2,
|
||||||
inbox: inbox,
|
inbox: inbox, assignee: user,
|
||||||
created_at: test_date)
|
created_at: test_date)
|
||||||
conversation.update_labels(unique_label_name)
|
conversation.update_labels(unique_label_name)
|
||||||
conversation.label_list
|
conversation.label_list
|
||||||
@@ -366,7 +358,6 @@ RSpec.describe V2::Reports::LabelSummaryBuilder do
|
|||||||
# Second resolution
|
# Second resolution
|
||||||
conversation.resolved!
|
conversation.resolved!
|
||||||
end
|
end
|
||||||
perform_enqueued_jobs
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ RSpec.describe 'Api::V1::Accounts::MacrosController', type: :request do
|
|||||||
headers: administrator.create_new_auth_token
|
headers: administrator.create_new_auth_token
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(conversation.reload.assignee_id).to eq(user_1.id)
|
expect(conversation.messages.activity.last.content).to eq("Assigned to #{user_1.name} by #{administrator.name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Assign the agent when he is not inbox member' do
|
it 'Assign the agent when he is not inbox member' do
|
||||||
@@ -402,7 +402,7 @@ RSpec.describe 'Api::V1::Accounts::MacrosController', type: :request do
|
|||||||
headers: administrator.create_new_auth_token
|
headers: administrator.create_new_auth_token
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(conversation.reload.assignee_id).to be_nil
|
expect(conversation.messages.activity.last.content).not_to eq("Assigned to #{user_1.name} by #{administrator.name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Assign the labels' do
|
it 'Assign the labels' do
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe BulkActionsJob do
|
RSpec.describe BulkActionsJob do
|
||||||
|
params = {
|
||||||
|
type: 'Conversation',
|
||||||
|
fields: { status: 'snoozed' },
|
||||||
|
ids: Conversation.first(3).pluck(:display_id)
|
||||||
|
}
|
||||||
|
|
||||||
subject(:job) { described_class.perform_later(account: account, params: params, user: agent) }
|
subject(:job) { described_class.perform_later(account: account, params: params, user: agent) }
|
||||||
|
|
||||||
let(:account) { create(:account) }
|
let(:account) { create(:account) }
|
||||||
@@ -8,8 +14,6 @@ RSpec.describe BulkActionsJob do
|
|||||||
let!(:conversation_1) { create(:conversation, account_id: account.id, status: :open) }
|
let!(:conversation_1) { create(:conversation, account_id: account.id, status: :open) }
|
||||||
let!(:conversation_2) { create(:conversation, account_id: account.id, status: :open) }
|
let!(:conversation_2) { create(:conversation, account_id: account.id, status: :open) }
|
||||||
let!(:conversation_3) { create(:conversation, account_id: account.id, status: :open) }
|
let!(:conversation_3) { create(:conversation, account_id: account.id, status: :open) }
|
||||||
let(:conversation_ids) { Conversation.where(id: [conversation_1.id, conversation_2.id, conversation_3.id]).pluck(:display_id) }
|
|
||||||
let(:params) { { type: 'Conversation', fields: { status: 'snoozed' }, ids: conversation_ids } }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Conversation.all.find_each do |conversation|
|
Conversation.all.find_each do |conversation|
|
||||||
@@ -34,10 +38,10 @@ RSpec.describe BulkActionsJob do
|
|||||||
params = {
|
params = {
|
||||||
type: 'Conversation',
|
type: 'Conversation',
|
||||||
fields: { status: 'snoozed', assignee_id: agent.id },
|
fields: { status: 'snoozed', assignee_id: agent.id },
|
||||||
ids: conversation_ids
|
ids: Conversation.first(3).pluck(:display_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(conversation_1.status).to eq('open')
|
expect(Conversation.first.status).to eq('open')
|
||||||
|
|
||||||
described_class.perform_now(account: account, params: params, user: agent)
|
described_class.perform_now(account: account, params: params, user: agent)
|
||||||
|
|
||||||
@@ -50,32 +54,32 @@ RSpec.describe BulkActionsJob do
|
|||||||
params = {
|
params = {
|
||||||
type: 'Conversation',
|
type: 'Conversation',
|
||||||
fields: { status: 'snoozed', assignee_id: agent.id },
|
fields: { status: 'snoozed', assignee_id: agent.id },
|
||||||
ids: conversation_ids
|
ids: Conversation.first(3).pluck(:display_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(conversation_1.assignee_id).to be_nil
|
expect(Conversation.first.assignee_id).to be_nil
|
||||||
|
|
||||||
described_class.perform_now(account: account, params: params, user: agent)
|
described_class.perform_now(account: account, params: params, user: agent)
|
||||||
|
|
||||||
expect(conversation_1.reload.assignee_id).to eq(agent.id)
|
expect(Conversation.first.assignee_id).to eq(agent.id)
|
||||||
expect(conversation_2.reload.assignee_id).to eq(agent.id)
|
expect(Conversation.second.assignee_id).to eq(agent.id)
|
||||||
expect(conversation_3.reload.assignee_id).to eq(agent.id)
|
expect(Conversation.third.assignee_id).to eq(agent.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'bulk updates the snoozed_until' do
|
it 'bulk updates the snoozed_until' do
|
||||||
params = {
|
params = {
|
||||||
type: 'Conversation',
|
type: 'Conversation',
|
||||||
fields: { status: 'snoozed', snoozed_until: Time.zone.now },
|
fields: { status: 'snoozed', snoozed_until: Time.zone.now },
|
||||||
ids: conversation_ids
|
ids: Conversation.first(3).pluck(:display_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(conversation_1.snoozed_until).to be_nil
|
expect(Conversation.first.snoozed_until).to be_nil
|
||||||
|
|
||||||
described_class.perform_now(account: account, params: params, user: agent)
|
described_class.perform_now(account: account, params: params, user: agent)
|
||||||
|
|
||||||
expect(conversation_1.reload.snoozed_until).to be_present
|
expect(Conversation.first.snoozed_until).to be_present
|
||||||
expect(conversation_2.reload.snoozed_until).to be_present
|
expect(Conversation.second.snoozed_until).to be_present
|
||||||
expect(conversation_3.reload.snoozed_until).to be_present
|
expect(Conversation.third.snoozed_until).to be_present
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_context 'with smtp config' do
|
RSpec.shared_context 'with smtp config' do
|
||||||
around do |example|
|
before do
|
||||||
# Set SMTP_ADDRESS so mailers build a Mail::Message in test without touching real SMTP.
|
# We need to use allow_any_instance_of here because smtp_config_set_or_development?
|
||||||
# Scoped to this shared context to avoid affecting other specs.
|
# is defined in ApplicationMailer and needs to be stubbed for all mailer instances
|
||||||
with_modified_env('SMTP_ADDRESS' => 'smtp.example.com') { example.run }
|
# rubocop:disable RSpec/AnyInstance
|
||||||
|
allow_any_instance_of(ApplicationMailer).to receive(:smtp_config_set_or_development?).and_return(true)
|
||||||
|
# rubocop:enable RSpec/AnyInstance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ RSpec.describe ContactInbox do
|
|||||||
obj.reload
|
obj.reload
|
||||||
|
|
||||||
# ensure the column is nil in database
|
# ensure the column is nil in database
|
||||||
expect(described_class.where(id: obj.id).pick(:pubsub_token)).to be_nil
|
results = ActiveRecord::Base.connection.execute('Select * from contact_inboxes;')
|
||||||
|
expect(results.first['pubsub_token']).to be_nil
|
||||||
|
|
||||||
new_token = obj.pubsub_token
|
new_token = obj.pubsub_token
|
||||||
obj.update(source_id: '234234323')
|
obj.update(source_id: '234234323')
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
|||||||
it 'raises InvalidEmail with invalid message' do
|
it 'raises InvalidEmail with invalid message' do
|
||||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(invalid_email_address)
|
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(invalid_email_address)
|
||||||
expect { service.perform }.to raise_error do |error|
|
expect { service.perform }.to raise_error do |error|
|
||||||
expect(error.class.name).to eq('CustomExceptions::Account::InvalidEmail')
|
expect(error).to be_a(CustomExceptions::Account::InvalidEmail)
|
||||||
expect(error.message).to eq(I18n.t('errors.signup.invalid_email'))
|
expect(error.message).to eq(I18n.t('errors.signup.invalid_email'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -32,7 +32,7 @@ RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
|||||||
it 'raises InvalidEmail with blocked domain message' do
|
it 'raises InvalidEmail with blocked domain message' do
|
||||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(valid_email_address)
|
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(valid_email_address)
|
||||||
expect { service.perform }.to raise_error do |error|
|
expect { service.perform }.to raise_error do |error|
|
||||||
expect(error.class.name).to eq('CustomExceptions::Account::InvalidEmail')
|
expect(error).to be_a(CustomExceptions::Account::InvalidEmail)
|
||||||
expect(error.message).to eq(I18n.t('errors.signup.blocked_domain'))
|
expect(error.message).to eq(I18n.t('errors.signup.blocked_domain'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -44,7 +44,7 @@ RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
|||||||
it 'raises InvalidEmail with blocked domain message' do
|
it 'raises InvalidEmail with blocked domain message' do
|
||||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(valid_email_address)
|
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(valid_email_address)
|
||||||
expect { service.perform }.to raise_error do |error|
|
expect { service.perform }.to raise_error do |error|
|
||||||
expect(error.class.name).to eq('CustomExceptions::Account::InvalidEmail')
|
expect(error).to be_a(CustomExceptions::Account::InvalidEmail)
|
||||||
expect(error.message).to eq(I18n.t('errors.signup.blocked_domain'))
|
expect(error.message).to eq(I18n.t('errors.signup.blocked_domain'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -56,7 +56,7 @@ RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
|||||||
it 'raises InvalidEmail with disposable message' do
|
it 'raises InvalidEmail with disposable message' do
|
||||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(disposable_email_address)
|
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(disposable_email_address)
|
||||||
expect { service.perform }.to raise_error do |error|
|
expect { service.perform }.to raise_error do |error|
|
||||||
expect(error.class.name).to eq('CustomExceptions::Account::InvalidEmail')
|
expect(error).to be_a(CustomExceptions::Account::InvalidEmail)
|
||||||
expect(error.message).to eq(I18n.t('errors.signup.disposable_email'))
|
expect(error.message).to eq(I18n.t('errors.signup.disposable_email'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ describe Telegram::IncomingMessageService do
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_for(source_id = nil)
|
|
||||||
source_id ||= message_params.dig('from', 'id')
|
|
||||||
ContactInbox.find_by!(inbox: telegram_channel.inbox, source_id: source_id).contact
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#perform' do
|
describe '#perform' do
|
||||||
context 'when valid text message params' do
|
context 'when valid text message params' do
|
||||||
it 'creates appropriate conversations, message and contacts' do
|
it 'creates appropriate conversations, message and contacts' do
|
||||||
@@ -56,7 +51,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.content).to eq('test')
|
expect(telegram_channel.inbox.messages.first.content).to eq('test')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -69,9 +64,9 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(contact_for.additional_attributes['social_telegram_user_id']).to eq(23)
|
expect(Contact.all.first.additional_attributes['social_telegram_user_id']).to eq(23)
|
||||||
expect(contact_for.additional_attributes['social_telegram_user_name']).to eq('sojan')
|
expect(Contact.all.first.additional_attributes['social_telegram_user_name']).to eq('sojan')
|
||||||
expect(telegram_channel.inbox.messages.first.content).to eq('test')
|
expect(telegram_channel.inbox.messages.first.content).to eq('test')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -112,7 +107,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(telegram_channel.inbox.conversations.last.additional_attributes).to include({ 'chat_id' => 23,
|
expect(telegram_channel.inbox.conversations.last.additional_attributes).to include({ 'chat_id' => 23,
|
||||||
'business_connection_id' => 'eooW3KF5WB5HxTD7T826' })
|
'business_connection_id' => 'eooW3KF5WB5HxTD7T826' })
|
||||||
contact = contact_for
|
contact = Contact.all.first
|
||||||
expect(contact.name).to eq('Sojan Jose')
|
expect(contact.name).to eq('Sojan Jose')
|
||||||
expect(contact.additional_attributes['language_code']).to eq('en')
|
expect(contact.additional_attributes['language_code']).to eq('en')
|
||||||
message = telegram_channel.inbox.messages.first
|
message = telegram_channel.inbox.messages.first
|
||||||
@@ -136,7 +131,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(telegram_channel.inbox.conversations.last.additional_attributes).to include({ 'chat_id' => 23,
|
expect(telegram_channel.inbox.conversations.last.additional_attributes).to include({ 'chat_id' => 23,
|
||||||
'business_connection_id' => 'eooW3KF5WB5HxTD7T826' })
|
'business_connection_id' => 'eooW3KF5WB5HxTD7T826' })
|
||||||
contact = contact_for
|
contact = Contact.all.first
|
||||||
expect(contact.name).to eq('Sojan Jose')
|
expect(contact.name).to eq('Sojan Jose')
|
||||||
# TODO: The language code is not present when we send the first message to the client.
|
# TODO: The language code is not present when we send the first message to the client.
|
||||||
# Should we update it when the user replies?
|
# Should we update it when the user replies?
|
||||||
@@ -166,9 +161,9 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(contact_for.additional_attributes['social_telegram_user_id']).to eq(23)
|
expect(Contact.all.first.additional_attributes['social_telegram_user_id']).to eq(23)
|
||||||
expect(contact_for.additional_attributes['social_telegram_user_name']).to eq('sojan')
|
expect(Contact.all.first.additional_attributes['social_telegram_user_name']).to eq('sojan')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('audio')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('audio')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -187,7 +182,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('image')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('image')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -212,7 +207,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('image')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('image')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -234,7 +229,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('video')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('video')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -263,7 +258,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('video')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('video')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -282,7 +277,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('audio')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('audio')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -303,7 +298,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('file')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('file')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -341,7 +336,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('location')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('location')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -360,7 +355,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
|
|
||||||
attachment = telegram_channel.inbox.messages.first.attachments.first
|
attachment = telegram_channel.inbox.messages.first.attachments.first
|
||||||
expect(attachment.file_type).to eq('location')
|
expect(attachment.file_type).to eq('location')
|
||||||
@@ -393,8 +388,8 @@ describe Telegram::IncomingMessageService do
|
|||||||
|
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for(5_171_248).name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(contact_for(5_171_248).additional_attributes['social_telegram_user_id']).to eq(5_171_248)
|
expect(Contact.all.first.additional_attributes['social_telegram_user_id']).to eq(5_171_248)
|
||||||
expect(telegram_channel.inbox.messages.first.content).to eq('Option 1')
|
expect(telegram_channel.inbox.messages.first.content).to eq('Option 1')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -411,7 +406,7 @@ describe Telegram::IncomingMessageService do
|
|||||||
}.with_indifferent_access
|
}.with_indifferent_access
|
||||||
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
described_class.new(inbox: telegram_channel.inbox, params: params).perform
|
||||||
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
expect(telegram_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect(contact_for.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('contact')
|
expect(telegram_channel.inbox.messages.first.attachments.first.file_type).to eq('contact')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ require 'rails_helper'
|
|||||||
describe Whatsapp::IncomingMessageWhatsappCloudService do
|
describe Whatsapp::IncomingMessageWhatsappCloudService do
|
||||||
describe '#perform' do
|
describe '#perform' do
|
||||||
let!(:whatsapp_channel) { create(:channel_whatsapp, provider: 'whatsapp_cloud', sync_templates: false, validate_provider_config: false) }
|
let!(:whatsapp_channel) { create(:channel_whatsapp, provider: 'whatsapp_cloud', sync_templates: false, validate_provider_config: false) }
|
||||||
let(:sender_number) { '2423423243' }
|
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
phone_number: whatsapp_channel.phone_number,
|
phone_number: whatsapp_channel.phone_number,
|
||||||
@@ -11,9 +10,9 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
entry: [{
|
entry: [{
|
||||||
changes: [{
|
changes: [{
|
||||||
value: {
|
value: {
|
||||||
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: sender_number }],
|
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: '2423423243' }],
|
||||||
messages: [{
|
messages: [{
|
||||||
from: sender_number,
|
from: '2423423243',
|
||||||
image: {
|
image: {
|
||||||
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
||||||
mime_type: 'image/jpeg',
|
mime_type: 'image/jpeg',
|
||||||
@@ -49,7 +48,7 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
|
|
||||||
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
described_class.new(inbox: whatsapp_channel.inbox, params: params).perform
|
||||||
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect_contact_name
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(whatsapp_channel.inbox.messages.first.content).to eq('Check out my product!')
|
expect(whatsapp_channel.inbox.messages.first.content).to eq('Check out my product!')
|
||||||
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be false
|
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be false
|
||||||
expect(whatsapp_channel.authorization_error_count).to eq(1)
|
expect(whatsapp_channel.authorization_error_count).to eq(1)
|
||||||
@@ -64,9 +63,9 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
entry: [{
|
entry: [{
|
||||||
changes: [{
|
changes: [{
|
||||||
value: {
|
value: {
|
||||||
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: sender_number }],
|
contacts: [{ profile: { name: 'Sojan Jose' }, wa_id: '2423423243' }],
|
||||||
messages: [{
|
messages: [{
|
||||||
from: sender_number,
|
from: '2423423243',
|
||||||
image: {
|
image: {
|
||||||
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
id: 'b1c68f38-8734-4ad3-b4a1-ef0c10d683',
|
||||||
mime_type: 'image/jpeg',
|
mime_type: 'image/jpeg',
|
||||||
@@ -89,7 +88,7 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
it 'with attachment errors' do
|
it 'with attachment errors' do
|
||||||
described_class.new(inbox: whatsapp_channel.inbox, params: error_params).perform
|
described_class.new(inbox: whatsapp_channel.inbox, params: error_params).perform
|
||||||
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
expect(whatsapp_channel.inbox.conversations.count).not_to eq(0)
|
||||||
expect_contact_name
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -99,7 +98,7 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
described_class.new(inbox: whatsapp_channel.inbox, params: { phone_number: whatsapp_channel.phone_number,
|
described_class.new(inbox: whatsapp_channel.inbox, params: { phone_number: whatsapp_channel.phone_number,
|
||||||
object: 'whatsapp_business_account', entry: {} }).perform
|
object: 'whatsapp_business_account', entry: {} }).perform
|
||||||
expect(whatsapp_channel.inbox.conversations.count).to eq(0)
|
expect(whatsapp_channel.inbox.conversations.count).to eq(0)
|
||||||
expect(Contact.find_by(phone_number: contact_phone_number)).to be_nil
|
expect(Contact.all.first).to be_nil
|
||||||
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
expect(whatsapp_channel.inbox.messages.count).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -137,7 +136,7 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def expect_contact_name
|
def expect_contact_name
|
||||||
expect(contact_from_number&.name).to eq('Sojan Jose')
|
expect(Contact.all.first.name).to eq('Sojan Jose')
|
||||||
end
|
end
|
||||||
|
|
||||||
def expect_message_content
|
def expect_message_content
|
||||||
@@ -147,12 +146,4 @@ describe Whatsapp::IncomingMessageWhatsappCloudService do
|
|||||||
def expect_message_has_attachment
|
def expect_message_has_attachment
|
||||||
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
|
expect(whatsapp_channel.inbox.messages.first.attachments.present?).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_phone_number
|
|
||||||
"+#{sender_number}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def contact_from_number
|
|
||||||
Contact.find_by(phone_number: contact_phone_number)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user