fat_free_crm 0.15.0.beta.2 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fat_free_crm might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.docker/nginx/sites-enabled/ffcrm.conf +8 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +4 -1
- data/.rubocop_todo.yml +190 -89
- data/.travis.yml +10 -3
- data/CHANGELOG.md +27 -0
- data/{CONTRIBUTORS → CONTRIBUTORS.md} +2 -1
- data/Dockerfile +15 -13
- data/Gemfile +7 -4
- data/Gemfile.lock +200 -167
- data/README.md +4 -2
- data/app/assets/javascripts/crm_sortable.js.coffee +5 -0
- data/app/assets/javascripts/timeago.js.coffee +5 -0
- data/app/assets/stylesheets/about.css.scss +5 -0
- data/app/assets/stylesheets/common.scss +2 -1
- data/app/controllers/admin/fields_controller.rb +1 -1
- data/app/controllers/admin/groups_controller.rb +5 -1
- data/app/controllers/admin/tags_controller.rb +1 -1
- data/app/controllers/admin/users_controller.rb +10 -6
- data/app/controllers/application_controller.rb +13 -13
- data/app/controllers/authentications_controller.rb +2 -2
- data/app/controllers/comments_controller.rb +3 -2
- data/app/controllers/entities/contacts_controller.rb +9 -7
- data/app/controllers/entities/opportunities_controller.rb +1 -1
- data/app/controllers/entities_controller.rb +4 -4
- data/app/controllers/home_controller.rb +9 -9
- data/app/controllers/passwords_controller.rb +1 -1
- data/app/controllers/tasks_controller.rb +2 -1
- data/app/controllers/users_controller.rb +4 -2
- data/app/helpers/application_helper.rb +9 -9
- data/app/helpers/javascript_helper.rb +5 -0
- data/app/helpers/opportunities_helper.rb +1 -1
- data/app/helpers/remote_link_pagination_helper.rb +5 -0
- data/app/inputs/date_pair_input.rb +1 -1
- data/app/models/entities/account.rb +2 -2
- data/app/models/entities/account_contact.rb +1 -1
- data/app/models/entities/campaign.rb +3 -3
- data/app/models/entities/contact.rb +3 -3
- data/app/models/entities/lead.rb +2 -2
- data/app/models/entities/opportunity.rb +3 -3
- data/app/models/fields/custom_field.rb +1 -1
- data/app/models/fields/custom_field_pair.rb +2 -2
- data/app/models/fields/field.rb +1 -1
- data/app/models/polymorphic/address.rb +2 -2
- data/app/models/polymorphic/avatar.rb +4 -2
- data/app/models/polymorphic/email.rb +8 -6
- data/app/models/polymorphic/task.rb +3 -1
- data/app/models/polymorphic/version.rb +3 -3
- data/app/models/users/ability.rb +1 -1
- data/app/models/users/permission.rb +2 -0
- data/app/models/users/user.rb +2 -2
- data/app/views/accounts/index.js.haml +1 -1
- data/app/views/admin/fields/_sort_by.html.haml +1 -1
- data/app/views/admin/users/_user.html.haml +1 -1
- data/app/views/campaigns/index.js.haml +1 -1
- data/app/views/contacts/index.js.haml +1 -1
- data/app/views/entities/_basic_search.html.haml +1 -1
- data/app/views/home/_duration_menu.html.haml +1 -1
- data/app/views/home/_events_menu.html.haml +1 -1
- data/app/views/home/_users_menu.html.haml +1 -1
- data/app/views/layouts/application.html.haml +1 -1
- data/app/views/leads/index.js.haml +1 -1
- data/app/views/opportunities/index.js.haml +1 -1
- data/app/views/shared/_naming.html.haml +1 -1
- data/app/views/users/_languages.html.haml +1 -1
- data/config/application.rb +2 -3
- data/config/boot.rb +2 -0
- data/config/deploy.example.rb +1 -1
- data/config/environments/development.rb +2 -0
- data/config/environments/production.rb +1 -1
- data/config/environments/test.rb +2 -2
- data/config/initializers/assets.rb +6 -1
- data/config/initializers/backtrace_silencers.rb +5 -0
- data/config/initializers/constants.rb +1 -1
- data/config/initializers/cookies_serializer.rb +5 -0
- data/config/initializers/custom_field_ransack_translations.rb +5 -0
- data/config/initializers/filter_parameter_logging.rb +5 -0
- data/config/initializers/inflections.rb +5 -0
- data/config/initializers/paper_trail.rb +5 -0
- data/config/initializers/ransack.rb +3 -3
- data/config/initializers/session_store.rb +5 -0
- data/config/initializers/wrap_parameters.rb +5 -0
- data/config/locales/et.yml +207 -0
- data/config/locales/et_fat_free_crm.yml +928 -0
- data/config/locales/pt-BR_ransack.yml +81 -0
- data/config/locales/th.rb +1 -1
- data/config/routes.rb +18 -18
- data/db/migrate/20100928030598_create_sessions.rb +1 -1
- data/db/migrate/20100928030599_create_users.rb +2 -2
- data/db/migrate/20100928030600_create_openid_tables.rb +1 -1
- data/db/migrate/20100928030601_create_accounts.rb +2 -2
- data/db/migrate/20100928030602_create_permissions.rb +1 -1
- data/db/migrate/20100928030603_create_settings.rb +1 -1
- data/db/migrate/20100928030604_create_preferences.rb +2 -2
- data/db/migrate/20100928030605_create_campaigns.rb +2 -2
- data/db/migrate/20100928030606_create_leads.rb +2 -2
- data/db/migrate/20100928030607_create_contacts.rb +2 -2
- data/db/migrate/20100928030608_create_opportunities.rb +2 -2
- data/db/migrate/20100928030609_create_account_contacts.rb +1 -1
- data/db/migrate/20100928030610_create_account_opportunities.rb +1 -1
- data/db/migrate/20100928030611_create_contact_opportunities.rb +1 -1
- data/db/migrate/20100928030612_create_tasks.rb +2 -2
- data/db/migrate/20100928030613_create_comments.rb +1 -1
- data/db/migrate/20100928030614_create_activities.rb +1 -1
- data/db/migrate/20100928030615_create_avatars.rb +1 -1
- data/db/migrate/20100928030616_rename_remember_token.rb +1 -1
- data/db/migrate/20100928030617_drop_openid_tables.rb +1 -1
- data/db/migrate/20100928030618_add_admin_to_users.rb +1 -1
- data/db/migrate/20100928030619_add_suspended_to_users.rb +1 -1
- data/db/migrate/20100928030620_remove_uuid.rb +2 -2
- data/db/migrate/20100928030621_add_email_to_accounts.rb +1 -1
- data/db/migrate/20100928030622_add_background_info_to_models.rb +1 -1
- data/db/migrate/20100928030623_create_addresses.rb +2 -2
- data/db/migrate/20100928030624_add_index_on_permissions.rb +3 -3
- data/db/migrate/20100928030625_create_emails.rb +2 -2
- data/db/migrate/20100928030626_add_state_to_timeline_objects.rb +1 -1
- data/db/migrate/20100928030627_acts_as_taggable_on_migration.rb +2 -2
- data/db/migrate/20101221123456_add_single_access_token_to_users.rb +1 -1
- data/db/migrate/20101221345678_add_rating_and_category_to_accounts.rb +1 -1
- data/db/migrate/20110719082054_add_skype_to_contacts_and_leads.rb +1 -1
- data/db/migrate/20111101083437_create_fields.rb +1 -1
- data/db/migrate/20111101090312_create_field_groups.rb +1 -1
- data/db/migrate/20111116091952_add_field_groups_tag_id.rb +1 -1
- data/db/migrate/20111117041311_change_fields_collection_to_text.rb +1 -1
- data/db/migrate/20111201030535_add_field_groups_klass_name.rb +2 -2
- data/db/migrate/20120121054235_create_lists.rb +1 -1
- data/db/migrate/20120216031616_create_versions.rb +3 -3
- data/db/migrate/20120216042541_is_paranoid_to_paper_trail.rb +1 -1
- data/db/migrate/20120220233724_add_versions_object_changes.rb +1 -1
- data/db/migrate/20120224073107_remove_default_value_and_clear_settings.rb +1 -1
- data/db/migrate/20120309070209_add_versions_related.rb +1 -1
- data/db/migrate/20120314080441_add_subscribed_users_to_entities.rb +2 -2
- data/db/migrate/20120316045804_activities_to_versions.rb +1 -1
- data/db/migrate/20120405080727_change_subscribed_users_to_set.rb +1 -1
- data/db/migrate/20120405080742_change_further_subscribed_users_to_set.rb +2 -2
- data/db/migrate/20120406082136_create_groups.rb +2 -2
- data/db/migrate/20120413034923_add_index_on_versions_item_type.rb +1 -1
- data/db/migrate/20120510025219_add_not_null_constraints_for_timestamp_columns.rb +3 -3
- data/db/migrate/20120528102124_increase_length_of_version_events.rb +1 -1
- data/db/migrate/20120801032706_add_pair_id_to_fields.rb +1 -1
- data/db/migrate/20121003063155_add_settings_to_custom_fields.rb +1 -1
- data/db/migrate/20121221033947_fix_country_mapping.rb +1 -1
- data/db/migrate/20131207033244_add_user_id_to_lists.rb +1 -1
- data/db/migrate/20140916011927_add_created_at_index_on_versions.rb +1 -1
- data/db/migrate/20140916012922_add_indexes_to_model_associations.rb +3 -3
- data/db/migrate/20141126031837_increase_email_to254_chars.rb +1 -1
- data/db/migrate/20141230021159_add_transaction_id_column_to_versions.rb +1 -1
- data/db/migrate/20141230205453_add_missing_unique_indices.acts_as_taggable_on_engine.rb +4 -4
- data/db/migrate/20141230205454_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +1 -1
- data/db/migrate/20141230205455_add_missing_taggable_index.acts_as_taggable_on_engine.rb +3 -3
- data/db/migrate/20150123060900_convert_radio_to_radio_buttons.rb +1 -1
- data/db/migrate/20150227123054_remove_last_request_at_from_users.rb +1 -1
- data/db/migrate/20150427131956_create_index_related_type.rb +3 -3
- data/db/migrate/20160511053730_add_account_contacts_index.rb +2 -2
- data/docker-compose.yml +17 -13
- data/fat_free_crm.gemspec +4 -6
- data/lib/development_tasks/license.rake +12 -9
- data/lib/fat_free_crm/callback.rb +4 -4
- data/lib/fat_free_crm/engine.rb +2 -2
- data/lib/fat_free_crm/exportable.rb +2 -2
- data/lib/fat_free_crm/fields.rb +2 -4
- data/lib/fat_free_crm/gem_ext.rb +0 -1
- data/lib/fat_free_crm/gem_ext/rake/task.rb +2 -0
- data/lib/fat_free_crm/mail_processor/base.rb +4 -4
- data/lib/fat_free_crm/mail_processor/dropbox.rb +1 -1
- data/lib/fat_free_crm/permissions.rb +5 -5
- data/lib/fat_free_crm/sortable.rb +1 -1
- data/lib/fat_free_crm/version.rb +1 -1
- data/lib/gravatar_image_tag.rb +1 -0
- data/lib/tasks/ffcrm/demo.rake +2 -2
- data/spec/controllers/admin/users_controller_spec.rb +25 -25
- data/spec/controllers/authentications_controller_spec.rb +9 -9
- data/spec/controllers/comments_controller_spec.rb +15 -15
- data/spec/controllers/emails_controller_spec.rb +2 -2
- data/spec/controllers/entities/accounts_controller_spec.rb +46 -46
- data/spec/controllers/entities/campaigns_controller_spec.rb +46 -46
- data/spec/controllers/entities/contacts_controller_spec.rb +55 -55
- data/spec/controllers/entities/leads_controller_spec.rb +85 -85
- data/spec/controllers/entities/opportunities_controller_spec.rb +74 -74
- data/spec/controllers/home_controller_spec.rb +11 -11
- data/spec/controllers/passwords_controller_spec.rb +2 -2
- data/spec/controllers/tasks_controller_spec.rb +37 -37
- data/spec/controllers/users_controller_spec.rb +31 -31
- data/spec/factories/campaign_factories.rb +1 -1
- data/spec/factories/contact_factories.rb +1 -1
- data/spec/factories/field_factories.rb +1 -1
- data/spec/factories/lead_factories.rb +2 -2
- data/spec/factories/opportunity_factories.rb +3 -3
- data/spec/factories/shared_factories.rb +1 -1
- data/spec/factories/task_factories.rb +1 -1
- data/spec/features/support/browser.rb +9 -1
- data/spec/lib/fields_spec.rb +2 -2
- data/spec/lib/permissions_spec.rb +38 -6
- data/spec/lib/view_factory_spec.rb +2 -2
- data/spec/models/fields/custom_field_spec.rb +3 -3
- data/spec/models/observers/entity_observer_spec.rb +1 -1
- data/spec/models/polymorphic/version_spec.rb +11 -11
- data/spec/models/users/abilities/user_ability_spec.rb +8 -3
- data/spec/models/users/permission_spec.rb +8 -0
- data/spec/models/users/user_spec.rb +1 -1
- data/spec/shared/controllers.rb +10 -10
- data/spec/spec_helper.rb +1 -1
- data/spec/views/accounts/index.haml_spec.rb +1 -1
- data/spec/views/accounts/update.js.haml_spec.rb +2 -2
- data/spec/views/admin/users/update.js.haml_spec.rb +2 -2
- data/spec/views/application/auto_complete.haml_spec.rb +1 -1
- data/spec/views/campaigns/index.haml_spec.rb +1 -1
- data/spec/views/campaigns/update.js.haml_spec.rb +2 -2
- data/spec/views/contacts/index.haml_spec.rb +1 -1
- data/spec/views/contacts/update.js.haml_spec.rb +2 -2
- data/spec/views/home/options.js.haml_spec.rb +1 -1
- data/spec/views/leads/index.haml_spec.rb +1 -1
- data/spec/views/leads/promote.js.haml_spec.rb +2 -2
- data/spec/views/leads/update.js.haml_spec.rb +2 -2
- data/spec/views/opportunities/index.haml_spec.rb +1 -1
- data/spec/views/opportunities/update.js.haml_spec.rb +1 -1
- data/spec/views/tasks/_edit.haml_spec.rb +2 -2
- data/spec/views/tasks/create.js.haml_spec.rb +2 -2
- data/spec/views/tasks/edit.js.haml_spec.rb +1 -1
- data/spec/views/users/change_password.js.haml_spec.rb +2 -2
- data/spec/views/users/update.js.haml_spec.rb +2 -2
- data/spec/views/users/upload_avatar.js.haml_spec.rb +2 -2
- metadata +17 -20
- data/lib/fat_free_crm/gem_ext/active_record/schema_dumper.rb +0 -27
@@ -9,7 +9,7 @@ FactoryGirl.define do
|
|
9
9
|
name { FFaker::Lorem.sentence[0, 64] }
|
10
10
|
assigned_to nil
|
11
11
|
access "Public"
|
12
|
-
status { %w
|
12
|
+
status { %w[planned started completed planned started completed on_hold called_off].sample }
|
13
13
|
budget { rand(500) }
|
14
14
|
target_leads { rand(200) }
|
15
15
|
target_conversion { rand(20) }
|
@@ -14,7 +14,7 @@ FactoryGirl.define do
|
|
14
14
|
access "Public"
|
15
15
|
title { FactoryGirl.generate(:title) }
|
16
16
|
department { FFaker::Name.name + " Dept." }
|
17
|
-
source { %w
|
17
|
+
source { %w[campaign cold_call conference online referral self web word_of_mouth other].sample }
|
18
18
|
email { FFaker::Internet.email }
|
19
19
|
alt_email { FFaker::Internet.email }
|
20
20
|
phone { FFaker::PhoneNumber.phone_number }
|
@@ -5,7 +5,7 @@
|
|
5
5
|
#------------------------------------------------------------------------------
|
6
6
|
FactoryGirl.define do
|
7
7
|
sequence :klass_name do |_x|
|
8
|
-
%w
|
8
|
+
%w[Contact Account Opportunity Lead Campaign].sample
|
9
9
|
end
|
10
10
|
|
11
11
|
sequence(:field_position) { |x| x }
|
@@ -13,8 +13,8 @@ FactoryGirl.define do
|
|
13
13
|
access "Public"
|
14
14
|
company { FFaker::Company.name }
|
15
15
|
title { FactoryGirl.generate(:title) }
|
16
|
-
source { %w
|
17
|
-
status { %w
|
16
|
+
source { %w[campaign cold_call conference online referral self web word_of_mouth other].sample }
|
17
|
+
status { %w[new contacted converted rejected].sample }
|
18
18
|
rating 1
|
19
19
|
referred_by { FFaker::Name.name }
|
20
20
|
do_not_call false
|
@@ -5,11 +5,11 @@
|
|
5
5
|
#------------------------------------------------------------------------------
|
6
6
|
FactoryGirl.define do
|
7
7
|
sequence :opportunity_status do |_s|
|
8
|
-
%w
|
8
|
+
%w[prospecting analysis presentation proposal negotiation final_review won lost].sample
|
9
9
|
end
|
10
10
|
|
11
11
|
sequence :opportunity_open_status do |_s|
|
12
|
-
%w
|
12
|
+
%w[prospecting analysis presentation proposal negotiation final_review].sample
|
13
13
|
end
|
14
14
|
|
15
15
|
factory :opportunity do
|
@@ -19,7 +19,7 @@ FactoryGirl.define do
|
|
19
19
|
assigned_to nil
|
20
20
|
name { FFaker::Lorem.sentence[0, 64] }
|
21
21
|
access "Public"
|
22
|
-
source { %w
|
22
|
+
source { %w[campaign cold_call conference online referral self web word_of_mouth other].sample }
|
23
23
|
stage { FactoryGirl.generate(:opportunity_status) }
|
24
24
|
probability { rand(50) }
|
25
25
|
amount { rand(1000) }
|
@@ -50,7 +50,7 @@ FactoryGirl.define do
|
|
50
50
|
zipcode { FFaker::AddressUS.zip_code }
|
51
51
|
country { FFaker::AddressUK.country }
|
52
52
|
full_address { FactoryGirl.generate(:address) }
|
53
|
-
address_type { %w
|
53
|
+
address_type { %w[Business Billing Shipping].sample }
|
54
54
|
updated_at { FactoryGirl.generate(:time) }
|
55
55
|
created_at { FactoryGirl.generate(:time) }
|
56
56
|
deleted_at nil
|
@@ -11,7 +11,7 @@ FactoryGirl.define do
|
|
11
11
|
completed_by nil
|
12
12
|
name { FFaker::Lorem.sentence[0, 64] }
|
13
13
|
priority nil
|
14
|
-
category { %w
|
14
|
+
category { %w[call email follow_up lunch meeting money presentation trip].sample }
|
15
15
|
bucket "due_asap"
|
16
16
|
due_at { FactoryGirl.generate(:time) }
|
17
17
|
background_info { FFaker::Lorem.paragraph[0, 255] }
|
@@ -8,7 +8,15 @@
|
|
8
8
|
#
|
9
9
|
if ENV['BROWSER'] == 'chrome'
|
10
10
|
Capybara.register_driver :selenium do |app|
|
11
|
-
|
11
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: ['no-sandbox', 'headless', 'disable-gpu'] })
|
12
|
+
Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
Capybara.register_driver :selenium do |app|
|
16
|
+
options = Selenium::WebDriver::Firefox::Options.new
|
17
|
+
options.args << '--headless'
|
18
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(marionette: false)
|
19
|
+
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options, desired_capabilities: capabilities)
|
12
20
|
end
|
13
21
|
end
|
14
22
|
|
data/spec/lib/fields_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe 'FatFreeCRM::Fields' do
|
|
36
36
|
|
37
37
|
describe "field_groups" do
|
38
38
|
it "should call FieldGroup" do
|
39
|
-
expect(ActiveRecord::Base.connection).to receive(:
|
39
|
+
expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with('field_groups').and_return(true)
|
40
40
|
dummy_scope = double
|
41
41
|
expect(dummy_scope).to receive(:order).with(:position)
|
42
42
|
expect(FieldGroup).to receive(:where).and_return(dummy_scope)
|
@@ -44,7 +44,7 @@ describe 'FatFreeCRM::Fields' do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should not call FieldGroup if table doesn't exist (migrations not yet run)" do
|
47
|
-
expect(ActiveRecord::Base.connection).to receive(:
|
47
|
+
expect(ActiveRecord::Base.connection).to receive(:data_source_exists?).with('field_groups').and_return(false)
|
48
48
|
expect(Foo.new.field_groups).to eq([])
|
49
49
|
end
|
50
50
|
end
|
@@ -30,19 +30,22 @@ describe FatFreeCRM::Permissions do
|
|
30
30
|
|
31
31
|
it "should assign permissions to the object" do
|
32
32
|
expect(@entity.permissions.size).to eq(0)
|
33
|
-
@entity.
|
33
|
+
@entity.user_ids = %w[1 2 3]
|
34
|
+
@entity.save!
|
34
35
|
expect(@entity.permissions.where(user_id: [1, 2, 3]).size).to eq(3)
|
35
36
|
end
|
36
37
|
|
37
38
|
it "should handle [] permissions" do
|
38
|
-
@entity.
|
39
|
+
@entity.user_ids = []
|
40
|
+
@entity.save!
|
39
41
|
expect(@entity.permissions.size).to eq(0)
|
40
42
|
end
|
41
43
|
|
42
44
|
it "should replace existing permissions" do
|
43
45
|
@entity.permissions << FactoryGirl.create(:permission, user_id: 1, asset: @entity)
|
44
46
|
@entity.permissions << FactoryGirl.create(:permission, user_id: 2, asset: @entity)
|
45
|
-
@entity.
|
47
|
+
@entity.user_ids = %w[2 3]
|
48
|
+
@entity.save!
|
46
49
|
expect(@entity.permissions.size).to eq(2)
|
47
50
|
expect(@entity.permissions.where(user_id: [1]).size).to eq(0)
|
48
51
|
expect(@entity.permissions.where(user_id: [2]).size).to eq(1)
|
@@ -56,12 +59,14 @@ describe FatFreeCRM::Permissions do
|
|
56
59
|
end
|
57
60
|
it "should assign permissions to the object" do
|
58
61
|
expect(@entity.permissions.size).to eq(0)
|
59
|
-
@entity.
|
62
|
+
@entity.group_ids = %w[1 2 3]
|
63
|
+
@entity.save!
|
60
64
|
expect(@entity.permissions.where(group_id: [1, 2, 3]).size).to eq(3)
|
61
65
|
end
|
62
66
|
|
63
67
|
it "should handle [] permissions" do
|
64
|
-
@entity.
|
68
|
+
@entity.group_ids = []
|
69
|
+
@entity.save!
|
65
70
|
expect(@entity.permissions.size).to eq(0)
|
66
71
|
end
|
67
72
|
|
@@ -69,7 +74,8 @@ describe FatFreeCRM::Permissions do
|
|
69
74
|
@entity.permissions << FactoryGirl.build(:permission, group_id: 1, user_id: nil, asset: @entity)
|
70
75
|
@entity.permissions << FactoryGirl.build(:permission, group_id: 2, user_id: nil, asset: @entity)
|
71
76
|
expect(@entity.permissions.size).to eq(2)
|
72
|
-
@entity.
|
77
|
+
@entity.group_ids = ['3']
|
78
|
+
@entity.save!
|
73
79
|
expect(@entity.permissions.size).to eq(1)
|
74
80
|
expect(@entity.permissions.where(group_id: [1, 2]).size).to eq(0)
|
75
81
|
expect(@entity.permissions.where(group_id: [3]).size).to eq(1)
|
@@ -131,4 +137,30 @@ describe FatFreeCRM::Permissions do
|
|
131
137
|
entity.save_with_model_permissions(model)
|
132
138
|
end
|
133
139
|
end
|
140
|
+
|
141
|
+
describe 'remove_permissions' do
|
142
|
+
context 'with a new record' do
|
143
|
+
before :each do
|
144
|
+
@entity = UserWithPermission.new
|
145
|
+
end
|
146
|
+
it 'should have no relationships to destroy' do
|
147
|
+
expect(@entity.remove_permissions).to eq []
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'with an existing record' do
|
152
|
+
before :each do
|
153
|
+
@entity = UserWithPermission.create
|
154
|
+
|
155
|
+
@permission1 = Permission.create(user_id: 1, group_id: 1, asset_id: @entity.id, asset_type: 'UserWithPermission')
|
156
|
+
@permission2 = Permission.create(user_id: 1, group_id: 2, asset_id: @entity.id, asset_type: 'UserWithPermission')
|
157
|
+
end
|
158
|
+
it 'should remove the related permissions' do
|
159
|
+
current = Permission.all.count
|
160
|
+
|
161
|
+
expect(@entity.remove_permissions.length).to eq 2
|
162
|
+
expect(Permission.all.count).to eq(current - 2)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
134
166
|
end
|
@@ -13,7 +13,7 @@ describe FatFreeCRM::ViewFactory do
|
|
13
13
|
|
14
14
|
describe "initialization" do
|
15
15
|
before(:each) do
|
16
|
-
@view_params = { name: 'brief', title: 'Brief View', icon: 'fa-bars', controllers: ['contacts'], actions: %w
|
16
|
+
@view_params = { name: 'brief', title: 'Brief View', icon: 'fa-bars', controllers: ['contacts'], actions: %w[show index] }
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should initialize with required parameters" do
|
@@ -41,7 +41,7 @@ describe FatFreeCRM::ViewFactory do
|
|
41
41
|
|
42
42
|
describe "views_for" do
|
43
43
|
before(:each) do
|
44
|
-
@v1 = FatFreeCRM::ViewFactory.new name: 'brief', title: 'Brief View', controllers: ['contacts'], actions: %w
|
44
|
+
@v1 = FatFreeCRM::ViewFactory.new name: 'brief', title: 'Brief View', controllers: ['contacts'], actions: %w[show index]
|
45
45
|
@v2 = FatFreeCRM::ViewFactory.new name: 'long', title: 'Long View', controllers: ['contacts'], actions: ['show']
|
46
46
|
@v3 = FatFreeCRM::ViewFactory.new name: 'full', title: 'Full View', controllers: ['accounts'], actions: ['show']
|
47
47
|
end
|
@@ -45,7 +45,7 @@ describe CustomField do
|
|
45
45
|
c = FactoryGirl.build(:custom_field, label: "Test Field", field_group: field_group)
|
46
46
|
|
47
47
|
columns = []
|
48
|
-
%w
|
48
|
+
%w[cf_test_field cf_test_field_2 cf_test_field_3 cf_test_field_4].each do |field|
|
49
49
|
expect(c.send(:generate_column_name)).to eq(field)
|
50
50
|
allow(Contact).to receive(:column_names).and_return(columns << field)
|
51
51
|
end
|
@@ -63,8 +63,8 @@ describe CustomField do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should return a safe list of types for the 'as' select options" do
|
66
|
-
{ "email" => %w
|
67
|
-
"integer" => %w
|
66
|
+
{ "email" => %w[check_boxes text string email url tel select radio_buttons],
|
67
|
+
"integer" => %w[integer float] }.each do |type, expected_arr|
|
68
68
|
c = FactoryGirl.build(:custom_field, as: type)
|
69
69
|
opts = c.available_as
|
70
70
|
expect(opts.map(&:first)).to match_array(expected_arr)
|
@@ -11,7 +11,7 @@ describe EntityObserver do
|
|
11
11
|
allow(PaperTrail).to receive(:whodunnit).and_return(assigner)
|
12
12
|
end
|
13
13
|
|
14
|
-
[
|
14
|
+
%i[account contact lead opportunity].each do |entity_type|
|
15
15
|
describe "on creation of #{entity_type}" do
|
16
16
|
let(:assignee) { FactoryGirl.create(:user) }
|
17
17
|
let(:assigner) { FactoryGirl.create(:user) }
|
@@ -34,7 +34,7 @@ describe Version, versioning: true do
|
|
34
34
|
before do
|
35
35
|
@lead = FactoryGirl.create(:lead)
|
36
36
|
|
37
|
-
%w
|
37
|
+
%w[create destroy update view].each do |event|
|
38
38
|
FactoryGirl.create(:version, event: event, item: @lead, whodunnit: PaperTrail.whodunnit)
|
39
39
|
FactoryGirl.create(:version, event: event, item: @lead, whodunnit: "1")
|
40
40
|
end
|
@@ -54,12 +54,12 @@ describe Version, versioning: true do
|
|
54
54
|
|
55
55
|
it "should include only destroy events" do
|
56
56
|
@versions = Version.for(current_user).include_events(:destroy)
|
57
|
-
expect(@versions.pluck(:event).uniq).to eq(
|
57
|
+
expect(@versions.pluck(:event).uniq).to eq(['destroy'])
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should include create and update events" do
|
61
61
|
@versions = Version.for(current_user).include_events(:create, :update)
|
62
|
-
expect(@versions.pluck(:event).uniq.sort).to eq(%w
|
62
|
+
expect(@versions.pluck(:event).uniq.sort).to eq(%w[create update])
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should select all versions for a given user" do
|
@@ -68,7 +68,7 @@ describe Version, versioning: true do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
%w
|
71
|
+
%w[account campaign contact lead opportunity task].each do |item|
|
72
72
|
describe "Create, update, and delete (#{item})" do
|
73
73
|
before :each do
|
74
74
|
@item = FactoryGirl.create(item.to_sym, user: current_user)
|
@@ -122,7 +122,7 @@ describe Version, versioning: true do
|
|
122
122
|
@task.update(name: 'New Name')
|
123
123
|
|
124
124
|
versions = Version.where(@conditions)
|
125
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
125
|
+
expect(versions.pluck(:event).sort).to eq(%w[create update]) # but not view
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -179,7 +179,7 @@ describe Version, versioning: true do
|
|
179
179
|
@item.update(name: 'New Name')
|
180
180
|
|
181
181
|
versions = Version.where(item_id: @item.id, item_type: @item.class.name)
|
182
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
182
|
+
expect(versions.pluck(:event).sort).to eq(%w[create update])
|
183
183
|
|
184
184
|
visible_versions = Version.visible_to(@user)
|
185
185
|
expect(visible_versions).to eq([])
|
@@ -190,7 +190,7 @@ describe Version, versioning: true do
|
|
190
190
|
@item.destroy
|
191
191
|
|
192
192
|
versions = Version.where(item_id: @item.id, item_type: @item.class.name)
|
193
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
193
|
+
expect(versions.pluck(:event).sort).to eq(%w[create destroy])
|
194
194
|
|
195
195
|
visible_versions = Version.visible_to(@user)
|
196
196
|
expect(visible_versions).to eq([])
|
@@ -205,7 +205,7 @@ describe Version, versioning: true do
|
|
205
205
|
@item.update(name: 'New Name')
|
206
206
|
|
207
207
|
versions = Version.where(item_id: @item.id, item_type: @item.class.name)
|
208
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
208
|
+
expect(versions.pluck(:event).sort).to eq(%w[create update])
|
209
209
|
|
210
210
|
visible_versions = Version.visible_to(@user)
|
211
211
|
expect(visible_versions).to eq([])
|
@@ -220,7 +220,7 @@ describe Version, versioning: true do
|
|
220
220
|
@item.destroy
|
221
221
|
|
222
222
|
versions = Version.where(item_id: @item.id, item_type: @item.class.name)
|
223
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
223
|
+
expect(versions.pluck(:event).sort).to eq(%w[create destroy])
|
224
224
|
|
225
225
|
visible_versions = Version.visible_to(@user)
|
226
226
|
expect(visible_versions).to eq([])
|
@@ -235,10 +235,10 @@ describe Version, versioning: true do
|
|
235
235
|
@item.update(name: 'New Name')
|
236
236
|
|
237
237
|
versions = Version.where(item_id: @item.id, item_type: @item.class.name)
|
238
|
-
expect(versions.pluck(:event).sort).to eq(%w
|
238
|
+
expect(versions.pluck(:event).sort).to eq(%w[create update])
|
239
239
|
|
240
240
|
visible_versions = Version.visible_to(@user)
|
241
|
-
expect(visible_versions.map(&:event).sort).to eq(%w
|
241
|
+
expect(visible_versions.map(&:event).sort).to eq(%w[create update])
|
242
242
|
end
|
243
243
|
end
|
244
244
|
end
|
@@ -1,8 +1,13 @@
|
|
1
|
+
# Copyright (c) 2008-2013 Michael Dvorkin and contributors.
|
2
|
+
#
|
3
|
+
# Fat Free CRM is freely distributable under the terms of MIT license.
|
4
|
+
# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
1
6
|
require 'spec_helper'
|
2
7
|
require 'cancan/matchers'
|
3
8
|
|
4
9
|
def all_actions
|
5
|
-
[
|
10
|
+
%i[index show create update destroy manage]
|
6
11
|
end
|
7
12
|
|
8
13
|
describe "User abilities" do
|
@@ -27,7 +32,7 @@ describe "User abilities" do
|
|
27
32
|
context "when another user, I" do
|
28
33
|
let(:user) { create :user }
|
29
34
|
let(:can) { [] }
|
30
|
-
let(:cannot) { [
|
35
|
+
let(:cannot) { %i[show create update index destroy manage] }
|
31
36
|
it do
|
32
37
|
can.each do |do_action|
|
33
38
|
is_expected.to be_able_to(do_action, subject_user)
|
@@ -43,7 +48,7 @@ describe "User abilities" do
|
|
43
48
|
context "when anonymous user, I" do
|
44
49
|
let(:user) { nil }
|
45
50
|
let(:can) { [] }
|
46
|
-
let(:cannot) { [
|
51
|
+
let(:cannot) { %i[show create update index destroy manage] }
|
47
52
|
it do
|
48
53
|
can.each do |do_action|
|
49
54
|
is_expected.to be_able_to(do_action, subject_user)
|
@@ -45,4 +45,12 @@ describe Permission do
|
|
45
45
|
expect(p.errors['user_id']).to eq(["can't be blank"])
|
46
46
|
expect(p.errors['group_id']).to eq(["can't be blank"])
|
47
47
|
end
|
48
|
+
|
49
|
+
it 'should not allow duplicate records with (user_id, group_id, asset_type, asset_ids) the same' do
|
50
|
+
permission1 = Permission.create(user_id: 1, group_id: 1, asset_id: 1, asset_type: 'UserWithPermission')
|
51
|
+
permission2 = Permission.new(user_id: 1, group_id: 1, asset_id: 1, asset_type: 'UserWithPermission')
|
52
|
+
|
53
|
+
expect(permission1).to be_valid
|
54
|
+
expect(permission2).not_to be_valid
|
55
|
+
end
|
48
56
|
end
|
@@ -60,7 +60,7 @@ describe User do
|
|
60
60
|
@user = FactoryGirl.build(:user)
|
61
61
|
end
|
62
62
|
|
63
|
-
%w
|
63
|
+
%w[account campaign lead contact opportunity].each do |asset|
|
64
64
|
it "should not destroy the user if she owns #{asset}" do
|
65
65
|
FactoryGirl.create(asset, user: @user)
|
66
66
|
|
data/spec/shared/controllers.rb
CHANGED
@@ -10,13 +10,13 @@ shared_examples "auto complete" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should do the search and find records that match autocomplete query" do
|
13
|
-
get :auto_complete, auto_complete_query: @query
|
13
|
+
get :auto_complete, params: { auto_complete_query: @query }
|
14
14
|
expect(assigns[:query]).to eq(@query)
|
15
15
|
expect(assigns[:auto_complete]).to eq(@auto_complete_matches) # Each controller must define it.
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should save current autocomplete controller in a session" do
|
19
|
-
get :auto_complete, auto_complete_query: @query
|
19
|
+
get :auto_complete, params: { auto_complete_query: @query }
|
20
20
|
|
21
21
|
# We don't save Admin/Users autocomplete controller in a session since Users are not
|
22
22
|
# exposed through the Jumpbox.
|
@@ -26,14 +26,14 @@ shared_examples "auto complete" do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should render application/_auto_complete template" do
|
29
|
-
post :auto_complete, auto_complete_query: @query
|
29
|
+
post :auto_complete, params: { auto_complete_query: @query }
|
30
30
|
expect(response).to render_template("application/_auto_complete")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
shared_examples "attach" do
|
35
35
|
it "should attach existing asset to the parent asset of different type" do
|
36
|
-
|
36
|
+
put :attach, params: { id: @model.id, assets: @attachment.class.name.tableize, asset_id: @attachment.id }, xhr: true
|
37
37
|
expect(@model.send(@attachment.class.name.tableize)).to include(@attachment)
|
38
38
|
expect(assigns[:attachment]).to eq(@attachment)
|
39
39
|
expect(assigns[:attached]).to eq([@attachment])
|
@@ -53,7 +53,7 @@ shared_examples "attach" do
|
|
53
53
|
@model.send(@attachment.class.name.tableize) << @attachment
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
put :attach, params: { id: @model.id, assets: @attachment.class.name.tableize, asset_id: @attachment.id }, xhr: true
|
57
57
|
expect(assigns[:attached]).to eq(nil)
|
58
58
|
expect(response).to render_template("entities/attach")
|
59
59
|
end
|
@@ -61,14 +61,14 @@ shared_examples "attach" do
|
|
61
61
|
it "should display flash warning when the model is no longer available" do
|
62
62
|
@model.destroy
|
63
63
|
|
64
|
-
|
64
|
+
put :attach, params: { id: @model.id, assets: @attachment.class.name.tableize, asset_id: @attachment.id }, xhr: true
|
65
65
|
expect(flash[:warning]).not_to eq(nil)
|
66
66
|
expect(response.body).to eq("window.location.reload();")
|
67
67
|
end
|
68
68
|
it "should display flash warning when the attachment is no longer available" do
|
69
69
|
@attachment.destroy
|
70
70
|
|
71
|
-
|
71
|
+
put :attach, params: { id: @model.id, assets: @attachment.class.name.tableize, asset_id: @attachment.id }, xhr: true
|
72
72
|
expect(flash[:warning]).not_to eq(nil)
|
73
73
|
expect(response.body).to eq("window.location.reload();")
|
74
74
|
end
|
@@ -76,7 +76,7 @@ end
|
|
76
76
|
|
77
77
|
shared_examples "discard" do
|
78
78
|
it "should discard the attachment without deleting it" do
|
79
|
-
|
79
|
+
post :discard, params: { id: @model.id, attachment: @attachment.class.name, attachment_id: @attachment.id }, xhr: true
|
80
80
|
expect(assigns[:attachment]).to eq(@attachment.reload) # The attachment should still exist.
|
81
81
|
expect(@model.reload.send(@attachment.class.name.tableize.to_s)).to eq([]) # But no longer associated with the model.
|
82
82
|
expect(assigns[:account]).to eq(@model) if @model.is_a?(Account)
|
@@ -88,7 +88,7 @@ shared_examples "discard" do
|
|
88
88
|
it "should display flash warning when the model is no longer available" do
|
89
89
|
@model.destroy
|
90
90
|
|
91
|
-
|
91
|
+
post :discard, params: { id: @model.id, attachment: @attachment.class.name, attachment_id: @attachment.id }, xhr: true
|
92
92
|
expect(flash[:warning]).not_to eq(nil)
|
93
93
|
expect(response.body).to eq("window.location.reload();")
|
94
94
|
end
|
@@ -96,7 +96,7 @@ shared_examples "discard" do
|
|
96
96
|
it "should display flash warning when the attachment is no longer available" do
|
97
97
|
@attachment.destroy
|
98
98
|
|
99
|
-
|
99
|
+
post :discard, params: { id: @model.id, attachment: @attachment.class.name, attachment_id: @attachment.id }, xhr: true
|
100
100
|
expect(flash[:warning]).not_to eq(nil)
|
101
101
|
expect(response.body).to eq("window.location.reload();")
|
102
102
|
end
|