use sidekiq
This commit is contained in:
@@ -36,3 +36,4 @@ yarn-debug.log*
|
|||||||
/attachments
|
/attachments
|
||||||
/docuseal
|
/docuseal
|
||||||
/ee
|
/ee
|
||||||
|
dump.rdb
|
||||||
|
|||||||
@@ -76,5 +76,8 @@ Rails/SkipsModelValidations:
|
|||||||
Rails/ApplicationController:
|
Rails/ApplicationController:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/Output:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
Capybara/ClickLinkOrButtonStyle:
|
Capybara/ClickLinkOrButtonStyle:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ ENV OPENSSL_CONF=/app/openssl_legacy.cnf
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apk add --no-cache sqlite-dev libpq-dev mariadb-dev vips-dev vips-poppler poppler-utils vips-heif gcompat ttf-freefont && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf
|
RUN apk add --no-cache sqlite-dev libpq-dev mariadb-dev vips-dev vips-poppler poppler-utils redis vips-heif gcompat ttf-freefont && mkdir /fonts && rm /usr/share/fonts/freefont/FreeSans.otf
|
||||||
|
|
||||||
RUN echo $'.include = /etc/ssl/openssl.cnf\n\
|
RUN echo $'.include = /etc/ssl/openssl.cnf\n\
|
||||||
\n\
|
\n\
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ gem 'pagy'
|
|||||||
gem 'pg', require: false
|
gem 'pg', require: false
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'pretender'
|
gem 'pretender'
|
||||||
gem 'puma'
|
gem 'puma', require: false
|
||||||
gem 'rack'
|
gem 'rack'
|
||||||
gem 'rails'
|
gem 'rails'
|
||||||
gem 'rails_autolink'
|
gem 'rails_autolink'
|
||||||
@@ -37,7 +37,7 @@ gem 'rqrcode'
|
|||||||
gem 'ruby-vips'
|
gem 'ruby-vips'
|
||||||
gem 'rubyXL'
|
gem 'rubyXL'
|
||||||
gem 'shakapacker'
|
gem 'shakapacker'
|
||||||
gem 'sidekiq', require: ENV.key?('REDIS_URL')
|
gem 'sidekiq'
|
||||||
gem 'sqlite3', require: false, force_ruby_platform: true
|
gem 'sqlite3', require: false, force_ruby_platform: true
|
||||||
gem 'strip_attributes'
|
gem 'strip_attributes'
|
||||||
gem 'turbo-rails'
|
gem 'turbo-rails'
|
||||||
|
|||||||
@@ -64,14 +64,14 @@ module Api
|
|||||||
submissions = create_submissions(@template, params)
|
submissions = create_submissions(@template, params)
|
||||||
|
|
||||||
submissions.each do |submission|
|
submissions.each do |submission|
|
||||||
SendSubmissionCreatedWebhookRequestJob.perform_later({ 'submission_id' => submission.id })
|
SendSubmissionCreatedWebhookRequestJob.perform_async({ 'submission_id' => submission.id })
|
||||||
end
|
end
|
||||||
|
|
||||||
Submissions.send_signature_requests(submissions)
|
Submissions.send_signature_requests(submissions)
|
||||||
|
|
||||||
submissions.each do |submission|
|
submissions.each do |submission|
|
||||||
if submission.submitters.all?(&:completed_at?) && submission.submitters.last
|
if submission.submitters.all?(&:completed_at?) && submission.submitters.last
|
||||||
ProcessSubmitterCompletionJob.perform_later({ 'submitter_id' => submission.submitters.last.id })
|
ProcessSubmitterCompletionJob.perform_async({ 'submitter_id' => submission.submitters.last.id })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ module Api
|
|||||||
else
|
else
|
||||||
@submission.update!(archived_at: Time.current)
|
@submission.update!(archived_at: Time.current)
|
||||||
|
|
||||||
SendSubmissionArchivedWebhookRequestJob.perform_later('submission_id' => @submission.id)
|
SendSubmissionArchivedWebhookRequestJob.perform_async('submission_id' => @submission.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: @submission.as_json(only: %i[id archived_at])
|
render json: @submission.as_json(only: %i[id archived_at])
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module Api
|
|||||||
|
|
||||||
SubmissionEvents.create_with_tracking_data(submitter, 'view_form', request)
|
SubmissionEvents.create_with_tracking_data(submitter, 'view_form', request)
|
||||||
|
|
||||||
SendFormViewedWebhookRequestJob.perform_later({ 'submitter_id' => submitter.id })
|
SendFormViewedWebhookRequestJob.perform_async({ 'submitter_id' => submitter.id })
|
||||||
|
|
||||||
render json: {}
|
render json: {}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ module Api
|
|||||||
end
|
end
|
||||||
|
|
||||||
if @submitter.completed_at?
|
if @submitter.completed_at?
|
||||||
ProcessSubmitterCompletionJob.perform_later({ 'submitter_id' => @submitter.id })
|
ProcessSubmitterCompletionJob.perform_async({ 'submitter_id' => @submitter.id })
|
||||||
elsif normalized_params[:send_email] || normalized_params[:send_sms]
|
elsif normalized_params[:send_email] || normalized_params[:send_sms]
|
||||||
Submitters.send_signature_requests([@submitter])
|
Submitters.send_signature_requests([@submitter])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ module Api
|
|||||||
|
|
||||||
Templates::CloneAttachments.call(template: cloned_template, original_template: @template)
|
Templates::CloneAttachments.call(template: cloned_template, original_template: @template)
|
||||||
|
|
||||||
SendTemplateCreatedWebhookRequestJob.perform_later('template_id' => cloned_template.id)
|
SendTemplateCreatedWebhookRequestJob.perform_async('template_id' => cloned_template.id)
|
||||||
|
|
||||||
render json: Templates::SerializeForApi.call(cloned_template)
|
render json: Templates::SerializeForApi.call(cloned_template)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ module Api
|
|||||||
|
|
||||||
@template.update!(template_params)
|
@template.update!(template_params)
|
||||||
|
|
||||||
SendTemplateUpdatedWebhookRequestJob.perform_later('template_id' => @template.id)
|
SendTemplateUpdatedWebhookRequestJob.perform_async('template_id' => @template.id)
|
||||||
|
|
||||||
render json: @template.as_json(only: %i[id updated_at])
|
render json: @template.as_json(only: %i[id updated_at])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class StartFormController < ApplicationController
|
|||||||
|
|
||||||
if @submitter.save
|
if @submitter.save
|
||||||
if is_new_record
|
if is_new_record
|
||||||
SendSubmissionCreatedWebhookRequestJob.perform_later({ 'submission_id' => @submitter.submission.id })
|
SendSubmissionCreatedWebhookRequestJob.perform_async({ 'submission_id' => @submitter.submission.id })
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to submit_form_path(@submitter.slug)
|
redirect_to submit_form_path(@submitter.slug)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class SubmissionsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
submissions.each do |submission|
|
submissions.each do |submission|
|
||||||
SendSubmissionCreatedWebhookRequestJob.perform_later({ 'submission_id' => submission.id })
|
SendSubmissionCreatedWebhookRequestJob.perform_async({ 'submission_id' => submission.id })
|
||||||
end
|
end
|
||||||
|
|
||||||
Submissions.send_signature_requests(submissions)
|
Submissions.send_signature_requests(submissions)
|
||||||
@@ -56,7 +56,7 @@ class SubmissionsController < ApplicationController
|
|||||||
def destroy
|
def destroy
|
||||||
@submission.update!(archived_at: Time.current)
|
@submission.update!(archived_at: Time.current)
|
||||||
|
|
||||||
SendSubmissionArchivedWebhookRequestJob.perform_later('submission_id' => @submission.id)
|
SendSubmissionArchivedWebhookRequestJob.perform_async('submission_id' => @submission.id)
|
||||||
|
|
||||||
redirect_back(fallback_location: template_path(@submission.template), notice: 'Submission has been archived')
|
redirect_back(fallback_location: template_path(@submission.template), notice: 'Submission has been archived')
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class SubmittersSendEmailController < ApplicationController
|
|||||||
alert: 'Email has been sent already.')
|
alert: 'Email has been sent already.')
|
||||||
end
|
end
|
||||||
|
|
||||||
SendSubmitterInvitationEmailJob.perform_later('submitter_id' => @submitter.id)
|
SendSubmitterInvitationEmailJob.perform_async('submitter_id' => @submitter.id)
|
||||||
|
|
||||||
@submitter.sent_at ||= Time.current
|
@submitter.sent_at ||= Time.current
|
||||||
@submitter.save!
|
@submitter.save!
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class TemplatesController < ApplicationController
|
|||||||
if @template.save
|
if @template.save
|
||||||
Templates::CloneAttachments.call(template: @template, original_template: @base_template) if @base_template
|
Templates::CloneAttachments.call(template: @template, original_template: @base_template) if @base_template
|
||||||
|
|
||||||
SendTemplateUpdatedWebhookRequestJob.perform_later('template_id' => @template.id)
|
SendTemplateUpdatedWebhookRequestJob.perform_async('template_id' => @template.id)
|
||||||
|
|
||||||
maybe_redirect_to_template(@template)
|
maybe_redirect_to_template(@template)
|
||||||
else
|
else
|
||||||
@@ -72,7 +72,7 @@ class TemplatesController < ApplicationController
|
|||||||
def update
|
def update
|
||||||
@template.update!(template_params)
|
@template.update!(template_params)
|
||||||
|
|
||||||
SendTemplateUpdatedWebhookRequestJob.perform_later('template_id' => @template.id)
|
SendTemplateUpdatedWebhookRequestJob.perform_async('template_id' => @template.id)
|
||||||
|
|
||||||
head :ok
|
head :ok
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class TemplatesUploadsController < ApplicationController
|
|||||||
|
|
||||||
@template.update!(schema:)
|
@template.update!(schema:)
|
||||||
|
|
||||||
SendTemplateCreatedWebhookRequestJob.perform_later('template_id' => @template.id)
|
SendTemplateCreatedWebhookRequestJob.perform_async('template_id' => @template.id)
|
||||||
|
|
||||||
redirect_to edit_template_path(@template)
|
redirect_to edit_template_path(@template)
|
||||||
rescue Templates::CreateAttachments::PdfEncrypted
|
rescue Templates::CreateAttachments::PdfEncrypted
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class WebhookSettingsController < ApplicationController
|
|||||||
def update
|
def update
|
||||||
submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last
|
submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last
|
||||||
|
|
||||||
SendFormCompletedWebhookRequestJob.perform_later({ 'submitter_id' => submitter.id })
|
SendFormCompletedWebhookRequestJob.perform_async({ 'submitter_id' => submitter.id })
|
||||||
|
|
||||||
redirect_back(fallback_location: settings_webhooks_path, notice: 'Webhook request has been sent.')
|
redirect_back(fallback_location: settings_webhooks_path, notice: 'Webhook request has been sent.')
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ProcessSubmitterCompletionJob < ApplicationJob
|
class ProcessSubmitterCompletionJob
|
||||||
|
include Sidekiq::Job
|
||||||
|
|
||||||
def perform(params = {})
|
def perform(params = {})
|
||||||
submitter = Submitter.find(params['submitter_id'])
|
submitter = Submitter.find(params['submitter_id'])
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ class ProcessSubmitterCompletionJob < ApplicationJob
|
|||||||
|
|
||||||
return if Accounts.load_webhook_url(submitter.account).blank?
|
return if Accounts.load_webhook_url(submitter.account).blank?
|
||||||
|
|
||||||
SendFormCompletedWebhookRequestJob.perform_later({ 'submitter_id' => submitter.id })
|
SendFormCompletedWebhookRequestJob.perform_async({ 'submitter_id' => submitter.id })
|
||||||
end
|
end
|
||||||
|
|
||||||
def enqueue_completed_emails(submitter)
|
def enqueue_completed_emails(submitter)
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendFormCompletedWebhookRequestJob < ApplicationJob
|
class SendFormCompletedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -38,8 +40,7 @@ class SendFormCompletedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
||||||
SendFormCompletedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendFormCompletedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'submitter_id' => submitter.id,
|
'submitter_id' => submitter.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendFormStartedWebhookRequestJob < ApplicationJob
|
class SendFormStartedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -36,8 +38,7 @@ class SendFormStartedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
||||||
SendFormStartedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendFormStartedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'submitter_id' => submitter.id,
|
'submitter_id' => submitter.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendFormViewedWebhookRequestJob < ApplicationJob
|
class SendFormViewedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -36,8 +38,7 @@ class SendFormViewedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || submitter.account.account_configs.exists?(key: :plan))
|
||||||
SendFormViewedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendFormViewedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'submitter_id' => submitter.id,
|
'submitter_id' => submitter.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendSubmissionArchivedWebhookRequestJob < ApplicationJob
|
class SendSubmissionArchivedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -34,8 +36,7 @@ class SendSubmissionArchivedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || submission.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || submission.account.account_configs.exists?(key: :plan))
|
||||||
SendSubmissionArchivedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendSubmissionArchivedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'submission_id' => submission.id,
|
'submission_id' => submission.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendSubmissionCreatedWebhookRequestJob < ApplicationJob
|
class SendSubmissionCreatedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -34,8 +36,7 @@ class SendSubmissionCreatedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || submission.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || submission.account.account_configs.exists?(key: :plan))
|
||||||
SendSubmissionCreatedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendSubmissionCreatedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'submission_id' => submission.id,
|
'submission_id' => submission.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendSubmitterInvitationEmailJob < ApplicationJob
|
class SendSubmitterInvitationEmailJob
|
||||||
|
include Sidekiq::Job
|
||||||
|
|
||||||
def perform(params = {})
|
def perform(params = {})
|
||||||
submitter = Submitter.find(params['submitter_id'])
|
submitter = Submitter.find(params['submitter_id'])
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendTemplateCreatedWebhookRequestJob < ApplicationJob
|
class SendTemplateCreatedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -34,8 +36,7 @@ class SendTemplateCreatedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || template.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || template.account.account_configs.exists?(key: :plan))
|
||||||
SendTemplateCreatedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendTemplateCreatedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'template_id' => template.id,
|
'template_id' => template.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SendTemplateUpdatedWebhookRequestJob < ApplicationJob
|
class SendTemplateUpdatedWebhookRequestJob
|
||||||
queue_as :webhooks
|
include Sidekiq::Job
|
||||||
|
|
||||||
|
sidekiq_options queue: :webhooks
|
||||||
|
|
||||||
USER_AGENT = 'DocuSeal.co Webhook'
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
@@ -34,8 +36,7 @@ class SendTemplateUpdatedWebhookRequestJob < ApplicationJob
|
|||||||
|
|
||||||
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
(!Docuseal.multitenant? || template.account.account_configs.exists?(key: :plan))
|
(!Docuseal.multitenant? || template.account.account_configs.exists?(key: :plan))
|
||||||
SendTemplateUpdatedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
SendTemplateUpdatedWebhookRequestJob.perform_in((2**attempt).minutes, {
|
||||||
.perform_later({
|
|
||||||
'template_id' => template.id,
|
'template_id' => template.id,
|
||||||
'attempt' => attempt + 1,
|
'attempt' => attempt + 1,
|
||||||
'last_status' => resp&.status.to_i
|
'last_status' => resp&.status.to_i
|
||||||
|
|||||||
@@ -81,6 +81,12 @@ class User < ApplicationRecord
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sidekiq?
|
||||||
|
return true if Rails.env.development?
|
||||||
|
|
||||||
|
role == 'admin'
|
||||||
|
end
|
||||||
|
|
||||||
def self.sign_in_after_reset_password
|
def self.sign_in_after_reset_password
|
||||||
if PasswordsController::Current.user.present?
|
if PasswordsController::Current.user.present?
|
||||||
!PasswordsController::Current.user.otp_required_for_login
|
!PasswordsController::Current.user.otp_required_for_login
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ module DocuSeal
|
|||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
config.load_defaults 7.1
|
config.load_defaults 7.1
|
||||||
|
|
||||||
config.autoload_lib(ignore: %w[assets tasks])
|
config.autoload_lib(ignore: %w[assets tasks puma])
|
||||||
|
|
||||||
config.active_storage.routes_prefix = ''
|
config.active_storage.routes_prefix = ''
|
||||||
|
|
||||||
|
|||||||
+1
-35
@@ -2,41 +2,7 @@
|
|||||||
|
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||||
|
|
||||||
if ENV['RAILS_ENV'] == 'production' && ENV['SECRET_KEY_BASE'].to_s.empty?
|
require_relative 'dotenv'
|
||||||
require 'dotenv'
|
|
||||||
require 'securerandom'
|
|
||||||
|
|
||||||
dotenv_path = "#{ENV.fetch('WORKDIR', '.')}/docuseal.env"
|
|
||||||
|
|
||||||
unless File.exist?(dotenv_path)
|
|
||||||
default_env = <<~TEXT
|
|
||||||
DATABASE_URL= # keep empty to use sqlite or specify postgresql database URL
|
|
||||||
SECRET_KEY_BASE=#{SecureRandom.hex(64)}
|
|
||||||
TEXT
|
|
||||||
|
|
||||||
File.write(dotenv_path, default_env)
|
|
||||||
end
|
|
||||||
|
|
||||||
database_url = ENV.fetch('DATABASE_URL', nil)
|
|
||||||
|
|
||||||
Dotenv.load(dotenv_path)
|
|
||||||
|
|
||||||
ENV['DATABASE_URL'] = ENV['DATABASE_URL'].to_s.empty? ? database_url : ENV.fetch('DATABASE_URL', nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
if ENV['DATABASE_URL'].to_s.split('@').last.to_s.split('/').first.to_s.include?('_')
|
|
||||||
require 'addressable'
|
|
||||||
|
|
||||||
url = Addressable::URI.parse(ENV.fetch('DATABASE_URL', ''))
|
|
||||||
|
|
||||||
ENV['DATABASE_HOST'] = url.host
|
|
||||||
ENV['DATABASE_PORT'] = (url.port || 5432).to_s
|
|
||||||
ENV['DATABASE_USER'] = url.user
|
|
||||||
ENV['DATABASE_PASSWORD'] = url.password
|
|
||||||
ENV['DATABASE_NAME'] = url.path.to_s.delete_prefix('/')
|
|
||||||
|
|
||||||
ENV.delete('DATABASE_URL')
|
|
||||||
end
|
|
||||||
|
|
||||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
||||||
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
|
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
|
||||||
|
|||||||
+4
-2
@@ -1,7 +1,7 @@
|
|||||||
default: &default
|
default: &default
|
||||||
adapter: postgresql
|
adapter: postgresql
|
||||||
encoding: unicode
|
encoding: unicode
|
||||||
pool: <%= ENV.fetch('RAILS_MAX_THREADS', 15) %>
|
pool: <%= ENV.fetch('RAILS_MAX_THREADS', 15).to_i + ENV.fetch('SIDEKIQ_THREADS', 5).to_i %>
|
||||||
|
|
||||||
development:
|
development:
|
||||||
<<: *default
|
<<: *default
|
||||||
@@ -22,12 +22,14 @@ production:
|
|||||||
<% elsif ENV['DATABASE_URL'].to_s.empty? %>
|
<% elsif ENV['DATABASE_URL'].to_s.empty? %>
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
database: <%= ENV['WORKDIR'] || '.' %>/db.sqlite3
|
database: <%= ENV['WORKDIR'] || '.' %>/db.sqlite3
|
||||||
|
pool: <%= ENV.fetch('RAILS_MAX_THREADS', 15).to_i + ENV.fetch('SIDEKIQ_THREADS', 5).to_i %>
|
||||||
|
timeout: 5000
|
||||||
<% elsif ENV['DATABASE_URL'].match?(/\Apostgres/) %>
|
<% elsif ENV['DATABASE_URL'].match?(/\Apostgres/) %>
|
||||||
<<: *default
|
<<: *default
|
||||||
url: <%= ENV['DATABASE_URL'] %>
|
url: <%= ENV['DATABASE_URL'] %>
|
||||||
<% elsif ENV['DATABASE_URL'].match?(/\Amysql/) %>
|
<% elsif ENV['DATABASE_URL'].match?(/\Amysql/) %>
|
||||||
adapter: mysql2
|
adapter: mysql2
|
||||||
encoding: utf8mb4
|
encoding: utf8mb4
|
||||||
pool: <%= ENV.fetch('RAILS_MAX_THREADS', 15) %>
|
pool: <%= ENV.fetch('RAILS_MAX_THREADS', 15).to_i + ENV.fetch('SIDEKIQ_THREADS', 5).to_i %>
|
||||||
url: <%= ENV['DATABASE_URL'] %>
|
url: <%= ENV['DATABASE_URL'] %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
if ENV['RAILS_ENV'] == 'production' && ENV['SECRET_KEY_BASE'].to_s.empty?
|
||||||
|
require 'dotenv'
|
||||||
|
require 'securerandom'
|
||||||
|
|
||||||
|
dotenv_path = "#{ENV.fetch('WORKDIR', '.')}/docuseal.env"
|
||||||
|
|
||||||
|
unless File.exist?(dotenv_path)
|
||||||
|
default_env = <<~TEXT
|
||||||
|
DATABASE_URL= # keep empty to use sqlite or specify postgresql database URL
|
||||||
|
SECRET_KEY_BASE=#{SecureRandom.hex(64)}
|
||||||
|
TEXT
|
||||||
|
|
||||||
|
File.write(dotenv_path, default_env)
|
||||||
|
end
|
||||||
|
|
||||||
|
database_url = ENV.fetch('DATABASE_URL', nil)
|
||||||
|
|
||||||
|
Dotenv.load(dotenv_path)
|
||||||
|
|
||||||
|
ENV['DATABASE_URL'] = ENV['DATABASE_URL'].to_s.empty? ? database_url : ENV.fetch('DATABASE_URL', nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
if ENV['DATABASE_URL'].to_s.split('@').last.to_s.split('/').first.to_s.include?('_')
|
||||||
|
require 'addressable'
|
||||||
|
|
||||||
|
url = Addressable::URI.parse(ENV.fetch('DATABASE_URL', ''))
|
||||||
|
|
||||||
|
ENV['DATABASE_HOST'] = url.host
|
||||||
|
ENV['DATABASE_PORT'] = (url.port || 5432).to_s
|
||||||
|
ENV['DATABASE_USER'] = url.user
|
||||||
|
ENV['DATABASE_PASSWORD'] = url.password
|
||||||
|
ENV['DATABASE_NAME'] = url.path.to_s.delete_prefix('/')
|
||||||
|
|
||||||
|
ENV.delete('DATABASE_URL')
|
||||||
|
end
|
||||||
|
|
||||||
|
if ENV['REDIS_URL'].to_s.empty?
|
||||||
|
require 'digest'
|
||||||
|
|
||||||
|
redis_password = Digest::SHA1.hexdigest("redis#{ENV.fetch('SECRET_KEY_BASE', '')}")
|
||||||
|
|
||||||
|
ENV['REDIS_URL'] = "redis://default:#{redis_password}@0.0.0.0:6379/0"
|
||||||
|
ENV['LOCAL_REDIS_URL'] = ENV.fetch('REDIS_URL', nil)
|
||||||
|
end
|
||||||
@@ -47,7 +47,7 @@ Rails.application.configure do
|
|||||||
config.cache_store = :null_store
|
config.cache_store = :null_store
|
||||||
end
|
end
|
||||||
|
|
||||||
config.active_job.queue_adapter = :sidekiq if defined?(Sidekiq)
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
|
||||||
# Store uploaded files on the local file system (see config/storage.yml for options).
|
# Store uploaded files on the local file system (see config/storage.yml for options).
|
||||||
config.active_storage.service = :disk
|
config.active_storage.service = :disk
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Rails.application.configure do
|
|||||||
config.action_controller.perform_caching = true
|
config.action_controller.perform_caching = true
|
||||||
config.active_record.sqlite3_production_warning = false
|
config.active_record.sqlite3_production_warning = false
|
||||||
|
|
||||||
config.active_job.queue_adapter = :sidekiq if defined?(Sidekiq)
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
|
||||||
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
|
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
|
||||||
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
|
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Rails.application.configure do
|
|||||||
# The :test delivery method accumulates sent emails in the
|
# The :test delivery method accumulates sent emails in the
|
||||||
# ActionMailer::Base.deliveries array.
|
# ActionMailer::Base.deliveries array.
|
||||||
config.action_mailer.delivery_method = :test
|
config.action_mailer.delivery_method = :test
|
||||||
config.active_job.queue_adapter = :test
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
|
||||||
# Print deprecation notices to the stderr.
|
# Print deprecation notices to the stderr.
|
||||||
config.active_support.deprecation = :stderr
|
config.active_support.deprecation = :stderr
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
if defined?(Sidekiq)
|
require 'sidekiq/web' if defined?(Puma)
|
||||||
require 'sidekiq/web'
|
|
||||||
|
|
||||||
|
if !ENV['SIDEKIQ_BASIC_AUTH_PASSWORD'].to_s.empty? && defined?(Sidekiq::Web)
|
||||||
Sidekiq::Web.use(Rack::Auth::Basic) do |_, password|
|
Sidekiq::Web.use(Rack::Auth::Basic) do |_, password|
|
||||||
next true if Rails.env.development?
|
|
||||||
|
|
||||||
ActiveSupport::SecurityUtils.secure_compare(
|
ActiveSupport::SecurityUtils.secure_compare(
|
||||||
Digest::SHA256.hexdigest(password),
|
Digest::SHA256.hexdigest(password),
|
||||||
Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_BASIC_AUTH_PASSWORD'))
|
Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_BASIC_AUTH_PASSWORD'))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
Sidekiq.strict_args!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Sidekiq.strict_args!
|
||||||
|
|||||||
+10
-3
@@ -5,7 +5,9 @@
|
|||||||
# Any libraries that use thread pools should be configured to match
|
# Any libraries that use thread pools should be configured to match
|
||||||
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
||||||
# and maximum; this matches the default thread size of Active Record.
|
# and maximum; this matches the default thread size of Active Record.
|
||||||
#
|
|
||||||
|
require_relative 'dotenv'
|
||||||
|
|
||||||
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 15)
|
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 15)
|
||||||
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
|
min_threads_count = ENV.fetch('RAILS_MIN_THREADS') { max_threads_count }
|
||||||
threads min_threads_count, max_threads_count
|
threads min_threads_count, max_threads_count
|
||||||
@@ -41,5 +43,10 @@ workers ENV.fetch('WEB_CONCURRENCY', 0)
|
|||||||
#
|
#
|
||||||
# preload_app!
|
# preload_app!
|
||||||
|
|
||||||
# Allow puma to be restarted by `bin/rails restart` command.
|
if ENV['MULTITENANT'] != 'true' || ENV['DEMO'] == 'true'
|
||||||
plugin :tmp_restart
|
require_relative '../lib/puma/plugin/redis_server'
|
||||||
|
require_relative '../lib/puma/plugin/sidekiq_embed'
|
||||||
|
|
||||||
|
plugin :sidekiq_embed
|
||||||
|
plugin :redis_server
|
||||||
|
end
|
||||||
|
|||||||
+6
-1
@@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
|
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
|
||||||
mount Sidekiq::Web => '/sidekiq' if defined?(Sidekiq)
|
|
||||||
|
if !Docuseal.multitenant? && defined?(Sidekiq::Web)
|
||||||
|
authenticated :user, ->(u) { u.sidekiq? } do
|
||||||
|
mount Sidekiq::Web => '/jobs'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
root 'dashboard#index'
|
root 'dashboard#index'
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'puma/plugin'
|
||||||
|
|
||||||
|
# rubocop:disable Metrics
|
||||||
|
Puma::Plugin.create do
|
||||||
|
def start(launcher)
|
||||||
|
return if ENV['LOCAL_REDIS_URL'].to_s.empty?
|
||||||
|
|
||||||
|
@puma_pid = $PROCESS_ID
|
||||||
|
|
||||||
|
launcher.events.on_booted do
|
||||||
|
@redis_server_pid = fork_redis
|
||||||
|
end
|
||||||
|
|
||||||
|
in_background { monitor_redis }
|
||||||
|
|
||||||
|
at_exit do
|
||||||
|
stop_redis_server if Process.pid == @puma_pid
|
||||||
|
end
|
||||||
|
|
||||||
|
launcher.events.on_stopped { stop_redis_server }
|
||||||
|
launcher.events.on_restart { stop_redis_server }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def monitor_redis
|
||||||
|
loop do
|
||||||
|
if redis_dead?
|
||||||
|
Process.kill(:INT, @puma_pid)
|
||||||
|
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def redis_dead?
|
||||||
|
return false unless @redis_server_pid
|
||||||
|
|
||||||
|
Process.waitpid(@redis_server_pid, Process::WNOHANG)
|
||||||
|
|
||||||
|
false
|
||||||
|
rescue Errno::ECHILD, Errno::ESRCH
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def fork_redis
|
||||||
|
fork do
|
||||||
|
Process.setsid
|
||||||
|
|
||||||
|
Dir.chdir(ENV.fetch('WORKDIR', nil)) unless ENV['WORKDIR'].to_s.empty?
|
||||||
|
|
||||||
|
exec('redis-server', '--requirepass', Digest::SHA1.hexdigest("redis#{ENV.fetch('SECRET_KEY_BASE', '')}"),
|
||||||
|
out: '/dev/null')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop_redis_server
|
||||||
|
if @redis_server_pid
|
||||||
|
Process.kill(:INT, @redis_server_pid)
|
||||||
|
Process.wait(@redis_server_pid)
|
||||||
|
end
|
||||||
|
rescue Errno::ECHILD, Errno::ESRCH
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# rubocop:enable Metrics
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'puma/plugin'
|
||||||
|
|
||||||
|
# rubocop:disable Metrics
|
||||||
|
Puma::Plugin.create do
|
||||||
|
def config(cfg)
|
||||||
|
return if cfg.instance_variable_get(:@options)[:workers] <= 0
|
||||||
|
|
||||||
|
cfg.on_worker_boot { start_sidekiq! }
|
||||||
|
|
||||||
|
cfg.on_worker_shutdown { @sidekiq&.stop }
|
||||||
|
cfg.on_refork { @sidekiq&.stop }
|
||||||
|
end
|
||||||
|
|
||||||
|
def start(launcher)
|
||||||
|
launcher.events.on_booted do
|
||||||
|
next if Puma.stats_hash[:workers].to_i != 0
|
||||||
|
|
||||||
|
start_sidekiq!
|
||||||
|
end
|
||||||
|
|
||||||
|
launcher.events.on_stopped { Thread.new { @sidekiq&.stop }.join }
|
||||||
|
launcher.events.on_restart { Thread.new { @sidekiq&.stop }.join }
|
||||||
|
end
|
||||||
|
|
||||||
|
def fire_event(config, event)
|
||||||
|
arr = config[:lifecycle_events][event]
|
||||||
|
|
||||||
|
arr.each(&:call)
|
||||||
|
|
||||||
|
arr.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def start_sidekiq!
|
||||||
|
Thread.new do
|
||||||
|
wait_for_redis!
|
||||||
|
|
||||||
|
configs = Sidekiq.configure_embed do |config|
|
||||||
|
config.logger.level = Logger::INFO
|
||||||
|
sidekiq_config = YAML.load_file('config/sidekiq.yml')
|
||||||
|
config.queues = sidekiq_config['queues']
|
||||||
|
config.concurrency = ENV.fetch('SIDEKIQ_THREADS', 5).to_i
|
||||||
|
config.merge!(sidekiq_config)
|
||||||
|
config[:max_retries] = 13
|
||||||
|
|
||||||
|
ActiveSupport.run_load_hooks(:sidekiq_config, config)
|
||||||
|
end.instance_variable_get(:@config)
|
||||||
|
|
||||||
|
@sidekiq = Sidekiq::Launcher.new(configs, embedded: true)
|
||||||
|
|
||||||
|
@sidekiq.run
|
||||||
|
|
||||||
|
fire_event(configs, :startup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_redis!
|
||||||
|
attempt = 0
|
||||||
|
|
||||||
|
loop do
|
||||||
|
attempt += 1
|
||||||
|
|
||||||
|
sleep (attempt - 1) / 10.0
|
||||||
|
|
||||||
|
RedisClient.new(url: ENV.fetch('REDIS_URL', nil)).call('GET', '1')
|
||||||
|
|
||||||
|
break
|
||||||
|
rescue RedisClient::CannotConnectError
|
||||||
|
raise('Unable to connect to redis') if attempt > 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# rubocop:enable Metrics
|
||||||
+1
-1
@@ -73,7 +73,7 @@ module Submitters
|
|||||||
next if submitter.email.blank?
|
next if submitter.email.blank?
|
||||||
next if submitter.preferences['send_email'] == false
|
next if submitter.preferences['send_email'] == false
|
||||||
|
|
||||||
SendSubmitterInvitationEmailJob.perform_later('submitter_id' => submitter.id)
|
SendSubmitterInvitationEmailJob.perform_async('submitter_id' => submitter.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ module Submitters
|
|||||||
unless submitter.submission_events.exists?(event_type: 'start_form')
|
unless submitter.submission_events.exists?(event_type: 'start_form')
|
||||||
SubmissionEvents.create_with_tracking_data(submitter, 'start_form', request)
|
SubmissionEvents.create_with_tracking_data(submitter, 'start_form', request)
|
||||||
|
|
||||||
SendFormStartedWebhookRequestJob.perform_later({ 'submitter_id' => submitter.id })
|
SendFormStartedWebhookRequestJob.perform_async({ 'submitter_id' => submitter.id })
|
||||||
end
|
end
|
||||||
|
|
||||||
update_submitter!(submitter, params, request)
|
update_submitter!(submitter, params, request)
|
||||||
|
|
||||||
submitter.submission.save!
|
submitter.submission.save!
|
||||||
|
|
||||||
ProcessSubmitterCompletionJob.perform_later({ 'submitter_id' => submitter.id }) if submitter.completed_at?
|
ProcessSubmitterCompletionJob.perform_async({ 'submitter_id' => submitter.id }) if submitter.completed_at?
|
||||||
|
|
||||||
submitter
|
submitter
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ require 'rspec/rails'
|
|||||||
require 'capybara/cuprite'
|
require 'capybara/cuprite'
|
||||||
require 'capybara/rspec'
|
require 'capybara/rspec'
|
||||||
require 'webmock/rspec'
|
require 'webmock/rspec'
|
||||||
|
require 'sidekiq/testing'
|
||||||
|
|
||||||
|
Sidekiq::Testing.fake!
|
||||||
|
|
||||||
WebMock.disable_net_connect!(allow_localhost: true)
|
WebMock.disable_net_connect!(allow_localhost: true)
|
||||||
|
|
||||||
@@ -56,4 +59,12 @@ RSpec.configure do |config|
|
|||||||
driven_by :headless_cuprite
|
driven_by :headless_cuprite
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.before do
|
||||||
|
Sidekiq::Worker.clear_all
|
||||||
|
end
|
||||||
|
|
||||||
|
config.before do |example|
|
||||||
|
Sidekiq::Testing.inline! if example.metadata[:sidekiq] == :inline
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ RSpec.describe 'Submit Form' do
|
|||||||
|
|
||||||
expect do
|
expect do
|
||||||
click_on 'submit'
|
click_on 'submit'
|
||||||
end.to change(enqueued_jobs, :size).by(2)
|
end.to change(enqueued_jobs, :size).by(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user