add base feature specs
This commit is contained in:
+5
-2
@@ -53,10 +53,13 @@ RSpec/NestedGroups:
|
|||||||
Max: 6
|
Max: 6
|
||||||
|
|
||||||
RSpec/MultipleExpectations:
|
RSpec/MultipleExpectations:
|
||||||
Max: 7
|
Max: 20
|
||||||
|
|
||||||
RSpec/ExampleLength:
|
RSpec/ExampleLength:
|
||||||
Max: 15
|
Max: 40
|
||||||
|
|
||||||
|
RSpec/RSpec/MultipleMemoizedHelpers:
|
||||||
|
Max: 6
|
||||||
|
|
||||||
Rails/I18nLocaleTexts:
|
Rails/I18nLocaleTexts:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|||||||
@@ -16,16 +16,17 @@ class SetupController < ApplicationController
|
|||||||
def create
|
def create
|
||||||
@account = Account.new(account_params)
|
@account = Account.new(account_params)
|
||||||
@account.timezone = Accounts.normalize_timezone(@account.timezone)
|
@account.timezone = Accounts.normalize_timezone(@account.timezone)
|
||||||
|
|
||||||
@user = @account.users.new(user_params)
|
@user = @account.users.new(user_params)
|
||||||
|
@encrypted_config = EncryptedConfig.new(encrypted_config_params)
|
||||||
|
|
||||||
unless URI.parse(encrypted_config_params[:value].to_s).class.in?([URI::HTTP, URI::HTTPS])
|
unless URI.parse(encrypted_config_params[:value].to_s).class.in?([URI::HTTP, URI::HTTPS])
|
||||||
@encrypted_config = EncryptedConfig.new(encrypted_config_params)
|
|
||||||
@encrypted_config.errors.add(:value, 'should be a valid URL')
|
@encrypted_config.errors.add(:value, 'should be a valid URL')
|
||||||
|
|
||||||
return render :index, status: :unprocessable_entity
|
return render :index, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return render :index, status: :unprocessable_entity unless @account.valid?
|
||||||
|
|
||||||
if @user.save
|
if @user.save
|
||||||
encrypted_configs = [
|
encrypted_configs = [
|
||||||
{ key: EncryptedConfig::APP_URL_KEY, value: encrypted_config_params[:value] },
|
{ key: EncryptedConfig::APP_URL_KEY, value: encrypted_config_params[:value] },
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
data-tip="Type text"
|
data-tip="Type text"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
id="type_text_button"
|
||||||
class="btn btn-sm btn-circle"
|
class="btn btn-sm btn-circle"
|
||||||
:class="{ 'btn-neutral': isTextSignature, 'btn-outline': !isTextSignature }"
|
:class="{ 'btn-neutral': isTextSignature, 'btn-outline': !isTextSignature }"
|
||||||
@click.prevent="toggleTextInput"
|
@click.prevent="toggleTextInput"
|
||||||
@@ -78,6 +79,7 @@
|
|||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-if="isTextSignature"
|
v-if="isTextSignature"
|
||||||
|
id="signature_text_input"
|
||||||
ref="textInput"
|
ref="textInput"
|
||||||
class="base-input !text-2xl w-full mt-6"
|
class="base-input !text-2xl w-full mt-6"
|
||||||
:required="field.required"
|
:required="field.required"
|
||||||
|
|||||||
@@ -21,14 +21,18 @@
|
|||||||
# fk_rails_... (account_id => accounts.id)
|
# fk_rails_... (account_id => accounts.id)
|
||||||
#
|
#
|
||||||
class EncryptedConfig < ApplicationRecord
|
class EncryptedConfig < ApplicationRecord
|
||||||
FILES_STORAGE_KEY = 'active_storage'
|
CONFIG_KEYS = [
|
||||||
EMAIL_SMTP_KEY = 'action_mailer_smtp'
|
FILES_STORAGE_KEY = 'active_storage',
|
||||||
ESIGN_CERTS_KEY = 'esign_certs'
|
EMAIL_SMTP_KEY = 'action_mailer_smtp',
|
||||||
APP_URL_KEY = 'app_url'
|
ESIGN_CERTS_KEY = 'esign_certs',
|
||||||
WEBHOOK_URL_KEY = 'webhook_url'
|
APP_URL_KEY = 'app_url',
|
||||||
|
WEBHOOK_URL_KEY = 'webhook_url'
|
||||||
|
].freeze
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
||||||
|
validates :key, inclusion: { in: CONFIG_KEYS }
|
||||||
|
|
||||||
encrypts :value
|
encrypts :value
|
||||||
|
|
||||||
serialize :value, JSON
|
serialize :value, JSON
|
||||||
|
|||||||
+5
-2
@@ -40,7 +40,9 @@
|
|||||||
# fk_rails_... (account_id => accounts.id)
|
# fk_rails_... (account_id => accounts.id)
|
||||||
#
|
#
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
ROLES = %w[admin].freeze
|
ROLES = [
|
||||||
|
ADMIN_ROLE = 'admin'
|
||||||
|
].freeze
|
||||||
|
|
||||||
EMAIL_REGEXP = /[^@,\s]+@[^@,\s]+/
|
EMAIL_REGEXP = /[^@,\s]+@[^@,\s]+/
|
||||||
|
|
||||||
@@ -51,10 +53,11 @@ class User < ApplicationRecord
|
|||||||
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable
|
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable
|
||||||
devise :registerable, :omniauthable, omniauth_providers: [:google_oauth2] if Docuseal.multitenant?
|
devise :registerable, :omniauthable, omniauth_providers: [:google_oauth2] if Docuseal.multitenant?
|
||||||
|
|
||||||
attribute :role, :string, default: 'admin'
|
attribute :role, :string, default: ADMIN_ROLE
|
||||||
attribute :uuid, :string, default: -> { SecureRandom.uuid }
|
attribute :uuid, :string, default: -> { SecureRandom.uuid }
|
||||||
|
|
||||||
scope :active, -> { where(deleted_at: nil) }
|
scope :active, -> { where(deleted_at: nil) }
|
||||||
|
scope :admins, -> { where(role: ADMIN_ROLE) }
|
||||||
|
|
||||||
def access_token
|
def access_token
|
||||||
super || build_access_token.tap(&:save!)
|
super || build_access_token.tap(&:save!)
|
||||||
|
|||||||
@@ -59,4 +59,10 @@ Rails.application.configure do
|
|||||||
|
|
||||||
# Annotate rendered view with file names.
|
# Annotate rendered view with file names.
|
||||||
# config.action_view.annotate_rendered_view_with_filenames = true
|
# config.action_view.annotate_rendered_view_with_filenames = true
|
||||||
|
|
||||||
|
config.active_record.encryption = {
|
||||||
|
primary_key: 'test master key',
|
||||||
|
deterministic_key: 'test deterministic key',
|
||||||
|
key_derivation_salt: 'test key derivation salt'
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -27,3 +27,8 @@ azure:
|
|||||||
storage_access_key: <%= ENV['AZURE_STORAGE_ACCESS_KEY'] %>
|
storage_access_key: <%= ENV['AZURE_STORAGE_ACCESS_KEY'] %>
|
||||||
container: <%= ENV['AZURE_CONTAINER'] %>
|
container: <%= ENV['AZURE_CONTAINER'] %>
|
||||||
public: <%= ENV['ACTIVE_STORAGE_PUBLIC'] == 'true' %>
|
public: <%= ENV['ACTIVE_STORAGE_PUBLIC'] == 'true' %>
|
||||||
|
|
||||||
|
test:
|
||||||
|
service: Disk
|
||||||
|
root: <%= Rails.root.join("tmp/storage") %>
|
||||||
|
public: true
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ module ActionMailerConfigsInterceptor
|
|||||||
module_function
|
module_function
|
||||||
|
|
||||||
def delivering_email(message)
|
def delivering_email(message)
|
||||||
|
return message unless Rails.env.production?
|
||||||
|
|
||||||
if Docuseal.demo?
|
if Docuseal.demo?
|
||||||
message.delivery_method(:test)
|
message.delivery_method(:test)
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ module LoadActiveStorageConfigs
|
|||||||
def reload
|
def reload
|
||||||
return if Docuseal.multitenant?
|
return if Docuseal.multitenant?
|
||||||
return if IS_ENV_CONFIGURED
|
return if IS_ENV_CONFIGURED
|
||||||
|
return if Rails.env.test?
|
||||||
|
|
||||||
encrypted_config = EncryptedConfig.find_by(key: EncryptedConfig::FILES_STORAGE_KEY)
|
encrypted_config = EncryptedConfig.find_by(key: EncryptedConfig::FILES_STORAGE_KEY)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ module Submitters
|
|||||||
SendWebhookRequestJob.perform_later(submitter)
|
SendWebhookRequestJob.perform_later(submitter)
|
||||||
end
|
end
|
||||||
|
|
||||||
submitter.submission.template.account.users.active.each do |user|
|
submitter.submission.template.account.users.active.admins.each do |user|
|
||||||
SubmitterMailer.completed_email(submitter, user).deliver_later!
|
SubmitterMailer.completed_email(submitter, user).deliver_later!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :account do
|
||||||
|
name { Faker::Company.name }
|
||||||
|
locale { 'en-US' }
|
||||||
|
timezone { 'UTC' }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :encrypted_config do
|
||||||
|
account
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :submission do
|
||||||
|
template
|
||||||
|
created_by_user factory: %i[user]
|
||||||
|
|
||||||
|
before(:create) do |submission, _|
|
||||||
|
submission.template_fields = submission.template.fields
|
||||||
|
submission.template_schema = submission.template.schema
|
||||||
|
submission.template_submitters = submission.template.submitters
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :submitter do
|
||||||
|
submission
|
||||||
|
email { Faker::Internet.email }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :template do
|
||||||
|
account
|
||||||
|
|
||||||
|
author factory: %i[user]
|
||||||
|
name { Faker::Book.title }
|
||||||
|
|
||||||
|
after(:create) do |template|
|
||||||
|
blob = ActiveStorage::Blob.create_and_upload!(
|
||||||
|
io: Rails.root.join('spec/fixtures/sample-document.pdf').open,
|
||||||
|
filename: 'sample-document.pdf',
|
||||||
|
content_type: 'application/pdf'
|
||||||
|
)
|
||||||
|
attachment = ActiveStorage::Attachment.create!(
|
||||||
|
blob:,
|
||||||
|
name: :documents,
|
||||||
|
record: template
|
||||||
|
)
|
||||||
|
|
||||||
|
Templates::ProcessDocument.call(attachment)
|
||||||
|
|
||||||
|
template.schema = [{ attachment_uuid: attachment.uuid, name: 'sample-document' }]
|
||||||
|
template.submitters = [
|
||||||
|
{
|
||||||
|
'name' => 'First Submitter',
|
||||||
|
'uuid' => '513848eb-1096-4abc-a743-68596b5aaa4c'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
template.fields = [
|
||||||
|
{
|
||||||
|
'uuid' => '21637fc9-0655-45df-8952-04ec64949e85',
|
||||||
|
'submitter_uuid' => '513848eb-1096-4abc-a743-68596b5aaa4c',
|
||||||
|
'name' => 'First Name',
|
||||||
|
'type' => 'text',
|
||||||
|
'required' => true,
|
||||||
|
'areas' => [
|
||||||
|
{
|
||||||
|
'x' => 0.09027777777777778,
|
||||||
|
'y' => 0.1197252208047105,
|
||||||
|
'w' => 0.3069444444444444,
|
||||||
|
'h' => 0.03336604514229637,
|
||||||
|
'attachment_uuid' => attachment.uuid,
|
||||||
|
'page' => 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'uuid' => '1f97f8e3-dc82-4586-aeea-6ebed6204e46',
|
||||||
|
'submitter_uuid' => '513848eb-1096-4abc-a743-68596b5aaa4c',
|
||||||
|
'name' => '',
|
||||||
|
'type' => 'signature',
|
||||||
|
'required' => true,
|
||||||
|
'areas' => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
template.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :user do
|
||||||
|
account
|
||||||
|
first_name { Faker::Name.first_name }
|
||||||
|
last_name { Faker::Name.last_name }
|
||||||
|
password { 'password' }
|
||||||
|
role { User::ADMIN_ROLE }
|
||||||
|
email { Faker::Internet.email }
|
||||||
|
end
|
||||||
|
end
|
||||||
Vendored
BIN
Binary file not shown.
@@ -7,6 +7,7 @@ require_relative '../config/environment'
|
|||||||
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
||||||
require 'rspec/rails'
|
require 'rspec/rails'
|
||||||
require 'capybara/cuprite'
|
require 'capybara/cuprite'
|
||||||
|
require 'capybara/rspec'
|
||||||
require 'webmock/rspec'
|
require 'webmock/rspec'
|
||||||
|
|
||||||
WebMock.disable_net_connect!(allow_localhost: true)
|
WebMock.disable_net_connect!(allow_localhost: true)
|
||||||
@@ -45,6 +46,7 @@ RSpec.configure do |config|
|
|||||||
config.filter_rails_from_backtrace!
|
config.filter_rails_from_backtrace!
|
||||||
|
|
||||||
config.include FactoryBot::Syntax::Methods
|
config.include FactoryBot::Syntax::Methods
|
||||||
|
config.include Devise::Test::IntegrationHelpers
|
||||||
|
|
||||||
config.before(:each, type: :system) do
|
config.before(:each, type: :system) do
|
||||||
if ENV['HEADLESS'] == 'false'
|
if ENV['HEADLESS'] == 'false'
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Account Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
let!(:encrypted_config) { create(:encrypted_config, account:, key: EncryptedConfig::APP_URL_KEY, value: 'https://www.test.com') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_account_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows pre-filled account settings page' do
|
||||||
|
expect(page).to have_content('Account')
|
||||||
|
expect(page).to have_field('Company Name', with: account.name)
|
||||||
|
expect(page).to have_field('Timezone', with: account.timezone)
|
||||||
|
expect(page).to have_field('Time format', with: account.locale)
|
||||||
|
expect(page).to have_field('App URL', with: encrypted_config.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the account settings' do
|
||||||
|
fill_in 'Company Name', with: 'New Company Name'
|
||||||
|
fill_in 'App URL', with: 'https://example.com'
|
||||||
|
select '(GMT+01:00) Berlin', from: 'Timezone'
|
||||||
|
select 'Spanish (Spain)', from: 'Time format'
|
||||||
|
|
||||||
|
click_button 'Update'
|
||||||
|
|
||||||
|
account.reload
|
||||||
|
encrypted_config.reload
|
||||||
|
|
||||||
|
expect(account.name).to eq('New Company Name')
|
||||||
|
expect(account.timezone).to eq('Berlin')
|
||||||
|
expect(account.locale).to eq('es-ES')
|
||||||
|
expect(encrypted_config.value).to eq('https://example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'API Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_api_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows verify signed PDF page' do
|
||||||
|
expect(page).to have_content('API')
|
||||||
|
expect(page).to have_field('X-Auth-Token', with: user.access_token.token)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Dashboard Page' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when are no templates' do
|
||||||
|
it 'shows empty state' do
|
||||||
|
visit root_path
|
||||||
|
|
||||||
|
expect(page).to have_content('Welcome to DocuSeal')
|
||||||
|
expect(page).to have_content('Streamline document workflows, from creating customizable')
|
||||||
|
expect(page).to have_link('Create Template', href: new_template_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are templates' do
|
||||||
|
let!(:authors) { create_list(:user, 5, account:) }
|
||||||
|
let!(:templates) { authors.map { |author| create(:template, account:, author:) } }
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit root_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the list of templates' do
|
||||||
|
templates.each do |template|
|
||||||
|
expect(page).to have_content(template.name)
|
||||||
|
expect(page).to have_content(template.author.full_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content('Templates')
|
||||||
|
expect(page).to have_link('Create', href: new_template_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'initializes the template creation process' do
|
||||||
|
click_link 'Create'
|
||||||
|
|
||||||
|
within('#modal') do
|
||||||
|
fill_in 'template[name]', with: 'New Template'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Create'
|
||||||
|
end.to change(Template, :count).by(1)
|
||||||
|
|
||||||
|
expect(page).to have_current_path(edit_template_path(Template.last), ignore_query: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Email Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when SMTP settings are not set' do
|
||||||
|
it 'setup SMTP settings' do
|
||||||
|
visit settings_email_index_path
|
||||||
|
|
||||||
|
fill_in 'Host', with: 'smtp.example.com'
|
||||||
|
fill_in 'Port', with: '587'
|
||||||
|
fill_in 'Username', with: 'user@example.com'
|
||||||
|
fill_in 'Password', with: 'password'
|
||||||
|
fill_in 'Domain', with: 'example.com'
|
||||||
|
fill_in 'Send from Email', with: 'user@example.com'
|
||||||
|
select 'Plain', from: 'Authentication'
|
||||||
|
choose 'TLS'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.to change(EncryptedConfig, :count).by(1)
|
||||||
|
|
||||||
|
encrypted_config = EncryptedConfig.find_by(account:, key: EncryptedConfig::EMAIL_SMTP_KEY)
|
||||||
|
|
||||||
|
expect(encrypted_config.value['host']).to eq('smtp.example.com')
|
||||||
|
expect(encrypted_config.value['port']).to eq('587')
|
||||||
|
expect(encrypted_config.value['username']).to eq('user@example.com')
|
||||||
|
expect(encrypted_config.value['password']).to eq('password')
|
||||||
|
expect(encrypted_config.value['domain']).to eq('example.com')
|
||||||
|
expect(encrypted_config.value['authentication']).to eq('plain')
|
||||||
|
expect(encrypted_config.value['security']).to eq('tls')
|
||||||
|
expect(encrypted_config.value['from_email']).to eq('user@example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when SMTP settings are set' do
|
||||||
|
let!(:encrypted_config) do
|
||||||
|
create(:encrypted_config, account:, key: EncryptedConfig::EMAIL_SMTP_KEY, value: {
|
||||||
|
host: 'smtp.example.com',
|
||||||
|
port: '587',
|
||||||
|
username: 'user@example.co',
|
||||||
|
password: 'password',
|
||||||
|
domain: 'example.com',
|
||||||
|
authentication: 'plain',
|
||||||
|
security: 'tls',
|
||||||
|
from_email: 'user@example.co'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit settings_email_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows pre-filled SMTP settings' do
|
||||||
|
expect(page).to have_content('Email SMTP')
|
||||||
|
expect(page).to have_field('Host', with: encrypted_config.value['host'])
|
||||||
|
expect(page).to have_field('Port', with: encrypted_config.value['port'])
|
||||||
|
expect(page).to have_field('Username', with: encrypted_config.value['username'])
|
||||||
|
expect(page).to have_field('Password', with: encrypted_config.value['password'])
|
||||||
|
expect(page).to have_field('Domain', with: encrypted_config.value['domain'])
|
||||||
|
expect(page).to have_select('Authentication', selected: 'Plain')
|
||||||
|
expect(page).to have_field('Send from Email', with: encrypted_config.value['from_email'])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates SMTP settings' do
|
||||||
|
fill_in 'Host', with: 'smtp.gmail.com'
|
||||||
|
fill_in 'Port', with: '465'
|
||||||
|
fill_in 'Username', with: 'user@gmail.com'
|
||||||
|
fill_in 'Password', with: 'new_password'
|
||||||
|
fill_in 'Domain', with: 'gmail.com'
|
||||||
|
fill_in 'Send from Email', with: 'user@gmail.com'
|
||||||
|
select 'Plain', from: 'Authentication'
|
||||||
|
choose 'SSL'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.not_to change(EncryptedConfig, :count)
|
||||||
|
|
||||||
|
encrypted_config.reload
|
||||||
|
|
||||||
|
expect(encrypted_config.value['host']).to eq('smtp.gmail.com')
|
||||||
|
expect(encrypted_config.value['port']).to eq('465')
|
||||||
|
expect(encrypted_config.value['username']).to eq('user@gmail.com')
|
||||||
|
expect(encrypted_config.value['password']).to eq('new_password')
|
||||||
|
expect(encrypted_config.value['domain']).to eq('gmail.com')
|
||||||
|
expect(encrypted_config.value['authentication']).to eq('plain')
|
||||||
|
expect(encrypted_config.value['security']).to eq('ssl')
|
||||||
|
expect(encrypted_config.value['from_email']).to eq('user@gmail.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'PDF Signature Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_esign_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows verify signed PDF page' do
|
||||||
|
expect(page).to have_content('PDF Signature')
|
||||||
|
expect(page).to have_content('Upload signed PDF file to validate its signature')
|
||||||
|
expect(page).to have_content('Verify Signed PDF')
|
||||||
|
expect(page).to have_content('Click to upload or drag and drop files')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Newsletter' do
|
||||||
|
let(:user) { create(:user, account: create(:account)) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
stub_request(:post, Docuseal::NEWSLETTER_URL).to_return(status: 200)
|
||||||
|
visit newsletter_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the newsletter page' do
|
||||||
|
expect(page).to have_content('Developer Newsletters')
|
||||||
|
expect(page).to have_button('Submit')
|
||||||
|
expect(page).to have_content('Skip')
|
||||||
|
expect(page).to have_field('user[email]', with: user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'submits the newsletter form' do
|
||||||
|
click_button 'Submit'
|
||||||
|
|
||||||
|
expect(a_request(:post, Docuseal::NEWSLETTER_URL)).to have_been_made.once
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'skips the newsletter form' do
|
||||||
|
click_on 'Skip'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(root_path, ignore_query: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Personalization' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_personalization_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the personalization page' do
|
||||||
|
expect(page).to have_content('Email Templates')
|
||||||
|
expect(page).to have_content('Signature Request Email')
|
||||||
|
expect(page).to have_content('Form Completed Email')
|
||||||
|
expect(page).to have_content('Documents Copy Email')
|
||||||
|
expect(page).to have_content('Company Logo')
|
||||||
|
expect(page).to have_content('Unlock with DocuSeal Enterprise')
|
||||||
|
expect(page).to have_content('Display your company name and logo when signing documents')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Profile Settings' do
|
||||||
|
let(:user) { create(:user, account: create(:account)) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_profile_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the profile settings page' do
|
||||||
|
expect(page).to have_content('Profile')
|
||||||
|
expect(page).to have_field('user[email]', with: user.email)
|
||||||
|
expect(page).to have_field('user[first_name]', with: user.first_name)
|
||||||
|
expect(page).to have_field('user[last_name]', with: user.last_name)
|
||||||
|
|
||||||
|
expect(page).to have_content('Change Password')
|
||||||
|
expect(page).to have_field('user[password]')
|
||||||
|
expect(page).to have_field('user[password_confirmation]')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when changes contact information' do
|
||||||
|
it 'updates first name, last name and email' do
|
||||||
|
fill_in 'First name', with: 'Devid'
|
||||||
|
fill_in 'Last name', with: 'Beckham'
|
||||||
|
fill_in 'Email', with: 'david.beckham@example.com'
|
||||||
|
|
||||||
|
all(:button, 'Update')[0].click
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
|
||||||
|
expect(user.first_name).to eq('Devid')
|
||||||
|
expect(user.last_name).to eq('Beckham')
|
||||||
|
expect(user.email).to eq('david.beckham@example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when changes password' do
|
||||||
|
it 'updates password' do
|
||||||
|
fill_in 'New password', with: 'newpassword'
|
||||||
|
fill_in 'Confirm new password', with: 'newpassword'
|
||||||
|
|
||||||
|
all(:button, 'Update')[1].click
|
||||||
|
|
||||||
|
expect(page).to have_content('Password has been changed')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not update if password confirmation does not match' do
|
||||||
|
fill_in 'New password', with: 'newpassword'
|
||||||
|
fill_in 'Confirm new password', with: 'newpassword1'
|
||||||
|
|
||||||
|
all(:button, 'Update')[1].click
|
||||||
|
|
||||||
|
expect(page).to have_content("Password confirmation doesn't match Password")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'App Setup', js: true do
|
||||||
|
let(:form_data) do
|
||||||
|
{
|
||||||
|
first_name: 'John',
|
||||||
|
last_name: 'Doe',
|
||||||
|
email: 'john.doe@example.com',
|
||||||
|
company_name: 'Example Company',
|
||||||
|
password: 'password',
|
||||||
|
app_url: 'https://example.com'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit setup_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows the setup page' do
|
||||||
|
expect(page).to have_content('Initial Setup')
|
||||||
|
|
||||||
|
['First name', 'Last name', 'Email', 'Company name', 'Password', 'App URL'].each do |field|
|
||||||
|
expect(page).to have_field(field)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when valid information' do
|
||||||
|
it 'setups the app' do
|
||||||
|
fill_setup_form(form_data)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Submit'
|
||||||
|
sleep 1
|
||||||
|
end.to change(Account, :count).by(1).and change(User, :count).by(1).and change(EncryptedConfig, :count).by(2)
|
||||||
|
|
||||||
|
user = User.last
|
||||||
|
encrypted_config_app_url = EncryptedConfig.find_by(account: user.account,
|
||||||
|
key: EncryptedConfig::APP_URL_KEY)
|
||||||
|
encrypted_config_esign_certs = EncryptedConfig.find_by(account: user.account,
|
||||||
|
key: EncryptedConfig::ESIGN_CERTS_KEY)
|
||||||
|
|
||||||
|
expect(user.first_name).to eq(form_data[:first_name])
|
||||||
|
expect(user.last_name).to eq(form_data[:last_name])
|
||||||
|
expect(user.email).to eq(form_data[:email])
|
||||||
|
expect(user.account.timezone).to eq('UTC')
|
||||||
|
expect(user.account.locale).to eq('en-US')
|
||||||
|
expect(user.account.name).to eq(form_data[:company_name])
|
||||||
|
expect(encrypted_config_app_url.value).to eq(form_data[:app_url])
|
||||||
|
expect(encrypted_config_esign_certs.value).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invalid information' do
|
||||||
|
it 'does not setup the app if the password is too short' do
|
||||||
|
fill_setup_form(form_data.merge(password: 'pass'))
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Submit'
|
||||||
|
end.not_to(change(User, :count))
|
||||||
|
|
||||||
|
expect(page).to have_content('Password is too short (minimum is 6 characters)')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the app is already setup' do
|
||||||
|
let!(:user) { create(:user, account: create(:account)) }
|
||||||
|
|
||||||
|
it 'redirects to the dashboard page' do
|
||||||
|
sign_in(user)
|
||||||
|
visit setup_index_path
|
||||||
|
|
||||||
|
expect(page).to have_content('Welcome to DocuSeal')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def fill_setup_form(form_data)
|
||||||
|
fill_in 'First name', with: form_data[:first_name]
|
||||||
|
fill_in 'Last name', with: form_data[:last_name]
|
||||||
|
fill_in 'Email', with: form_data[:email]
|
||||||
|
fill_in 'Company name', with: form_data[:company_name]
|
||||||
|
fill_in 'Password', with: form_data[:password]
|
||||||
|
fill_in 'App URL', with: form_data[:app_url]
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,247 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Storage Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when storage settings are not set' do
|
||||||
|
before do
|
||||||
|
visit settings_storage_index_path
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Disk is selected' do
|
||||||
|
it 'shows default storage settings page' do
|
||||||
|
expect(page).to have_content('Storage')
|
||||||
|
expect(page).to have_content('Store all files on disk')
|
||||||
|
expect(page).to have_content('No configs are needed but make sure your disk is persistent')
|
||||||
|
expect(page).to have_checked_field('Disk')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when AWS S3 is selected' do
|
||||||
|
it 'setups AWS S3 storage settings' do
|
||||||
|
choose 'AWS'
|
||||||
|
|
||||||
|
fill_in 'Access key ID', with: 'access_key_id'
|
||||||
|
fill_in 'Secret access key', with: 'secret_access_key'
|
||||||
|
fill_in 'Region', with: 'us-west-1'
|
||||||
|
fill_in 'Bucket', with: 'bucket'
|
||||||
|
fill_in 'Endpoint', with: 'https://s3.us-west-1.amazonaws.com'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.to change(EncryptedConfig, :count).by(1)
|
||||||
|
|
||||||
|
encrypted_config = EncryptedConfig.find_by(account:, key: EncryptedConfig::FILES_STORAGE_KEY)
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('aws_s3')
|
||||||
|
expect(configs['access_key_id']).to eq('access_key_id')
|
||||||
|
expect(configs['secret_access_key']).to eq('secret_access_key')
|
||||||
|
expect(configs['region']).to eq('us-west-1')
|
||||||
|
expect(configs['bucket']).to eq('bucket')
|
||||||
|
expect(configs['endpoint']).to eq('https://s3.us-west-1.amazonaws.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Google Cloud Storage is selected' do
|
||||||
|
it 'setups Google Cloud Storage settings' do
|
||||||
|
choose 'GCP'
|
||||||
|
|
||||||
|
fill_in 'Project', with: 'project_id'
|
||||||
|
fill_in 'Bucket', with: 'bucket'
|
||||||
|
fill_in 'Credentials (JSON key content)', with: '{ "type": "service_account", "project_id": "project_id" }'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.to change(EncryptedConfig, :count).by(1)
|
||||||
|
|
||||||
|
encrypted_config = EncryptedConfig.find_by(account:, key: EncryptedConfig::FILES_STORAGE_KEY)
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('google')
|
||||||
|
expect(configs['project']).to eq('project_id')
|
||||||
|
expect(configs['bucket']).to eq('bucket')
|
||||||
|
expect(configs['credentials']).to eq('{ "type": "service_account", "project_id": "project_id" }')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Azure is selected' do
|
||||||
|
it 'setup Azure storage settings' do
|
||||||
|
choose 'Azure'
|
||||||
|
|
||||||
|
fill_in 'Storage Account Name', with: 'storage_account_name'
|
||||||
|
fill_in 'Container', with: 'container'
|
||||||
|
fill_in 'Storage Access Key', with: 'storage_access_key'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.to change(EncryptedConfig, :count).by(1)
|
||||||
|
|
||||||
|
encrypted_config = EncryptedConfig.find_by(account:, key: EncryptedConfig::FILES_STORAGE_KEY)
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('azure')
|
||||||
|
expect(configs['storage_account_name']).to eq('storage_account_name')
|
||||||
|
expect(configs['container']).to eq('container')
|
||||||
|
expect(configs['storage_access_key']).to eq('storage_access_key')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when storage settings are set' do
|
||||||
|
context 'when updates the same storage settings' do
|
||||||
|
context 'when AWS S3' do
|
||||||
|
let!(:encrypted_config) do
|
||||||
|
create(:encrypted_config, account:, key: EncryptedConfig::FILES_STORAGE_KEY, value: {
|
||||||
|
service: 'aws_s3',
|
||||||
|
configs: {
|
||||||
|
access_key_id: 'access_key_id',
|
||||||
|
secret_access_key: 'secret_access_key',
|
||||||
|
region: 'us-west-1',
|
||||||
|
bucket: 'bucket',
|
||||||
|
endpoint: 'https://s3.us-west-1.amazonaws.com'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates AWS S3 storage settings' do
|
||||||
|
visit settings_storage_index_path
|
||||||
|
|
||||||
|
fill_in 'Access key ID', with: 'new_access_key_id'
|
||||||
|
fill_in 'Secret access key', with: 'new_secret_access_key'
|
||||||
|
fill_in 'Region', with: 'us-west-2'
|
||||||
|
fill_in 'Bucket', with: 'new_bucket'
|
||||||
|
fill_in 'Endpoint', with: 'https://s3.us-west-2.amazonaws.com'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.not_to(change(EncryptedConfig, :count))
|
||||||
|
|
||||||
|
encrypted_config.reload
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('aws_s3')
|
||||||
|
expect(configs['access_key_id']).to eq('new_access_key_id')
|
||||||
|
expect(configs['secret_access_key']).to eq('new_secret_access_key')
|
||||||
|
expect(configs['region']).to eq('us-west-2')
|
||||||
|
expect(configs['bucket']).to eq('new_bucket')
|
||||||
|
expect(configs['endpoint']).to eq('https://s3.us-west-2.amazonaws.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Google Cloud Storage' do
|
||||||
|
let!(:encrypted_config) do
|
||||||
|
create(:encrypted_config, account:, key: EncryptedConfig::FILES_STORAGE_KEY, value: {
|
||||||
|
service: 'google',
|
||||||
|
configs: {
|
||||||
|
project: 'project_id',
|
||||||
|
bucket: 'bucket',
|
||||||
|
credentials: '{ "type": "service_account", "project_id": "project_id" }'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates Google Cloud Storage settings' do
|
||||||
|
visit settings_storage_index_path
|
||||||
|
|
||||||
|
fill_in 'Project', with: 'new_project_id'
|
||||||
|
fill_in 'Bucket', with: 'new_bucket'
|
||||||
|
fill_in 'Credentials (JSON key content)',
|
||||||
|
with: '{ "type": "new_service_account", "project_id": "new_project_id" }'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.not_to(change(EncryptedConfig, :count))
|
||||||
|
|
||||||
|
encrypted_config.reload
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('google')
|
||||||
|
expect(configs['project']).to eq('new_project_id')
|
||||||
|
expect(configs['bucket']).to eq('new_bucket')
|
||||||
|
expect(configs['credentials']).to eq('{ "type": "new_service_account", "project_id": "new_project_id" }')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Azure' do
|
||||||
|
let!(:encrypted_config) do
|
||||||
|
create(:encrypted_config, account:, key: EncryptedConfig::FILES_STORAGE_KEY, value: {
|
||||||
|
service: 'azure',
|
||||||
|
configs: {
|
||||||
|
storage_account_name: 'storage_account_name',
|
||||||
|
container: 'container',
|
||||||
|
storage_access_key: 'storage_access_key'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates Azure storage settings' do
|
||||||
|
visit settings_storage_index_path
|
||||||
|
|
||||||
|
fill_in 'Storage Account Name', with: 'new_storage_account_name'
|
||||||
|
fill_in 'Container', with: 'new_container'
|
||||||
|
fill_in 'Storage Access Key', with: 'new_storage_access_key'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.not_to(change(EncryptedConfig, :count))
|
||||||
|
|
||||||
|
encrypted_config.reload
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('azure')
|
||||||
|
expect(configs['storage_account_name']).to eq('new_storage_account_name')
|
||||||
|
expect(configs['container']).to eq('new_container')
|
||||||
|
expect(configs['storage_access_key']).to eq('new_storage_access_key')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when switches to another storage settings' do
|
||||||
|
context 'when Google Cloud Storage' do
|
||||||
|
let!(:encrypted_config) do
|
||||||
|
create(:encrypted_config, account:, key: EncryptedConfig::FILES_STORAGE_KEY, value: {
|
||||||
|
service: 'google',
|
||||||
|
configs: {
|
||||||
|
project: 'project_id',
|
||||||
|
bucket: 'bucket',
|
||||||
|
credentials: '{ "type": "service_account", "project_id": "project_id" }'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'switches to AWS S3' do
|
||||||
|
visit settings_storage_index_path
|
||||||
|
choose 'AWS'
|
||||||
|
|
||||||
|
fill_in 'Access key ID', with: 'access_key_id'
|
||||||
|
fill_in 'Secret access key', with: 'secret_access_key'
|
||||||
|
fill_in 'Region', with: 'us-west-1'
|
||||||
|
fill_in 'Bucket', with: 'bucket'
|
||||||
|
fill_in 'Endpoint', with: 'https://s3.us-west-1.amazonaws.com'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.not_to(change(EncryptedConfig, :count))
|
||||||
|
|
||||||
|
encrypted_config.reload
|
||||||
|
configs = encrypted_config.value['configs']
|
||||||
|
|
||||||
|
expect(encrypted_config.value['service']).to eq('aws_s3')
|
||||||
|
expect(configs['access_key_id']).to eq('access_key_id')
|
||||||
|
expect(configs['secret_access_key']).to eq('secret_access_key')
|
||||||
|
expect(configs['region']).to eq('us-west-1')
|
||||||
|
expect(configs['bucket']).to eq('bucket')
|
||||||
|
expect(configs['endpoint']).to eq('https://s3.us-west-1.amazonaws.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Submit Form' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
let!(:template) { create(:template, account:, author: user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when initialized by shared link' do
|
||||||
|
before do
|
||||||
|
visit start_form_path(slug: template.slug)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows start form page' do
|
||||||
|
expect(page).to have_content('You have been invited to submit a form')
|
||||||
|
expect(page).to have_content(template.name)
|
||||||
|
expect(page).to have_content("Invited by #{template.account.name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'complete the form' do
|
||||||
|
fill_in 'Email', with: 'john.dou@example.com'
|
||||||
|
click_button 'Start'
|
||||||
|
|
||||||
|
fill_in 'First Name', with: 'Adam'
|
||||||
|
click_on 'Next'
|
||||||
|
click_on 'type_text_button'
|
||||||
|
fill_in 'signature_text_input', with: 'Adam'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on 'Submit'
|
||||||
|
end.not_to(change(Submitter, :count))
|
||||||
|
|
||||||
|
submitter = Submitter.find_by(email: 'john.dou@example.com')
|
||||||
|
|
||||||
|
expect(page).to have_button('Download')
|
||||||
|
expect(submitter.email).to eq('john.dou@example.com')
|
||||||
|
expect(submitter.ip).to eq('127.0.0.1')
|
||||||
|
expect(submitter.ua).to be_present
|
||||||
|
expect(submitter.opened_at).to be_present
|
||||||
|
expect(submitter.completed_at).to be_present
|
||||||
|
expect(submitter.values.values).to include('Adam')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when initialized by shared email address' do
|
||||||
|
let!(:submission) { create(:submission, template:, created_by_user: user) }
|
||||||
|
let!(:submitters) { template.submitters.map { |s| create(:submitter, submission:, uuid: s['uuid']) } }
|
||||||
|
let(:submitter) { submitters.first }
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit submit_form_path(slug: submitter.slug)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'completes the form' do
|
||||||
|
fill_in 'First Name', with: 'Sally'
|
||||||
|
click_on 'Next'
|
||||||
|
click_on 'type_text_button'
|
||||||
|
fill_in 'signature_text_input', with: 'Sally'
|
||||||
|
click_on 'Submit'
|
||||||
|
|
||||||
|
submitter.reload
|
||||||
|
|
||||||
|
expect(page).to have_button('Download')
|
||||||
|
expect(submitter.ip).to eq('127.0.0.1')
|
||||||
|
expect(submitter.ua).to be_present
|
||||||
|
expect(submitter.opened_at).to be_present
|
||||||
|
expect(submitter.completed_at).to be_present
|
||||||
|
expect(submitter.values.values).to include('Sally')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends completed email' do
|
||||||
|
fill_in 'First Name', with: 'Adam'
|
||||||
|
click_on 'Next'
|
||||||
|
click_on 'type_text_button'
|
||||||
|
fill_in 'signature_text_input', with: 'Adam'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_on 'Submit'
|
||||||
|
end.to change { ActionMailer::Base.deliveries.size }.by(1)
|
||||||
|
|
||||||
|
email = ActionMailer::Base.deliveries.last
|
||||||
|
|
||||||
|
expect(email.subject).to eq("#{submitter.email} has completed the \"#{template.name}\" form")
|
||||||
|
|
||||||
|
expect(email.body.encoded).to include "Hi #{user.first_name},"
|
||||||
|
expect(email.body.encoded).to include "#{submitter.email} has completed the \"#{template.name}\" form."
|
||||||
|
expect(email.body.encoded).to have_link('View Submission')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Team Settings' do
|
||||||
|
let(:account) { create(:account) }
|
||||||
|
let(:current_user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when multiple users' do
|
||||||
|
let!(:users) { create_list(:user, 2, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit settings_users_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows all users' do
|
||||||
|
within '.table' do
|
||||||
|
users.each do |user|
|
||||||
|
expect(page).to have_content(user.full_name)
|
||||||
|
expect(page).to have_content(user.email)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates a new user' do
|
||||||
|
click_link 'New User'
|
||||||
|
|
||||||
|
within '#modal' do
|
||||||
|
fill_in 'First name', with: 'Joseph'
|
||||||
|
fill_in 'Last name', with: 'Smith'
|
||||||
|
fill_in 'Email', with: 'joseph.smith@example.com'
|
||||||
|
fill_in 'Password', with: 'password'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Submit'
|
||||||
|
end.to change(User, :count).by(1)
|
||||||
|
|
||||||
|
user = User.last
|
||||||
|
|
||||||
|
expect(user.first_name).to eq('Joseph')
|
||||||
|
expect(user.last_name).to eq('Smith')
|
||||||
|
expect(user.email).to eq('joseph.smith@example.com')
|
||||||
|
expect(user.account).to eq(account)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates a user' do
|
||||||
|
first(:link, 'Edit').click
|
||||||
|
|
||||||
|
fill_in 'First name', with: 'Adam'
|
||||||
|
fill_in 'Last name', with: 'Meier'
|
||||||
|
fill_in 'Email', with: 'adam.meier@example.com'
|
||||||
|
fill_in 'Password', with: 'new_password'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Submit'
|
||||||
|
end.not_to change(User, :count)
|
||||||
|
|
||||||
|
user = User.find_by(email: 'adam.meier@example.com')
|
||||||
|
|
||||||
|
expect(user.first_name).to eq('Adam')
|
||||||
|
expect(user.last_name).to eq('Meier')
|
||||||
|
expect(user.email).to eq('adam.meier@example.com')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes a user' do
|
||||||
|
expect do
|
||||||
|
accept_confirm('Are you sure?') do
|
||||||
|
first(:link, 'Delete').click
|
||||||
|
end
|
||||||
|
end.to change { User.active.count }.by(-1)
|
||||||
|
|
||||||
|
expect(page).to have_content('User has been removed')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when single user' do
|
||||||
|
before do
|
||||||
|
visit settings_users_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not allow to remove the current user' do
|
||||||
|
expect do
|
||||||
|
accept_confirm('Are you sure?') do
|
||||||
|
first(:link, 'Delete').click
|
||||||
|
end
|
||||||
|
end.not_to(change { User.admins.count })
|
||||||
|
|
||||||
|
expect(page).to have_content('Unable to remove user')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Template' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
let!(:template) { create(:template, account:, author: user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when no submissions' do
|
||||||
|
it 'shows the template page' do
|
||||||
|
visit template_path(template)
|
||||||
|
|
||||||
|
expect(page).to have_content(template.name)
|
||||||
|
expect(page).to have_content('There are no Submissions')
|
||||||
|
expect(page).to have_content('Send an invitation to fill and complete the form')
|
||||||
|
expect(page).to have_link('Add Recipients', href: new_template_submission_path(template))
|
||||||
|
expect(page).to have_link('Submit it Yourself')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are submissions' do
|
||||||
|
let!(:submission) { create(:submission, template:, created_by_user: user) }
|
||||||
|
let!(:submitters) { template.submitters.map { |s| create(:submitter, submission:, uuid: s['uuid']) } }
|
||||||
|
|
||||||
|
it 'shows the template page with submissions' do
|
||||||
|
visit template_path(template)
|
||||||
|
|
||||||
|
submitters.each do |submitter|
|
||||||
|
expect(page).to have_content(submitter.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_content(template.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when managing a template' do
|
||||||
|
before do
|
||||||
|
visit template_path(template)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes a template' do
|
||||||
|
expect do
|
||||||
|
accept_confirm('Are you sure?') do
|
||||||
|
click_button 'Remove'
|
||||||
|
end
|
||||||
|
end.to change { Template.active.count }.by(-1)
|
||||||
|
|
||||||
|
expect(page).to have_content('Template has been archived')
|
||||||
|
expect(page).to have_current_path(root_path, ignore_query: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'edits a template' do
|
||||||
|
click_link 'Edit'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(edit_template_path(template), ignore_query: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'clones a template' do
|
||||||
|
click_link 'Clone'
|
||||||
|
|
||||||
|
within '#modal' do
|
||||||
|
fill_in 'template[name]', with: 'New Template Name'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Submit'
|
||||||
|
end.to change { Template.active.count }.by(1)
|
||||||
|
|
||||||
|
template = Template.last
|
||||||
|
|
||||||
|
expect(template.name).to eq('New Template Name')
|
||||||
|
expect(page).to have_current_path(edit_template_path(template), ignore_query: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Webhook Settings' do
|
||||||
|
let!(:account) { create(:account) }
|
||||||
|
let!(:user) { create(:user, account:) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
visit settings_webhooks_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows webhook settings page' do
|
||||||
|
expect(page).to have_content('Webhooks')
|
||||||
|
expect(page).to have_field('Webhook URL')
|
||||||
|
expect(page).to have_button('Save')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the webhook URL' do
|
||||||
|
fill_in 'Webhook URL', with: 'https://example.com'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
click_button 'Save'
|
||||||
|
end.to change(EncryptedConfig, :count).by(1)
|
||||||
|
|
||||||
|
encrypted_config = EncryptedConfig.find_by(account:, key: EncryptedConfig::WEBHOOK_URL_KEY)
|
||||||
|
|
||||||
|
expect(encrypted_config.value).to eq('https://example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user