web47core 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fcbe8a6af006b83e043ed3a844a0204f2b48f1373c2403a3fbd823b20cadd8a
4
- data.tar.gz: 65d2aebcd8a3b59742f7d01ccbe6aeebb612df2d187f1eb9e07ae475c9027d33
3
+ metadata.gz: 2e82f9597abea49e585537bf7b37dd78220136b34e2f2bc0ade5592e4d70ae9d
4
+ data.tar.gz: 523f737ac0beae20e3203ba4188c66e4cf5c09b8749084bf67dfd07fb039a3e7
5
5
  SHA512:
6
- metadata.gz: e92b025b5e9d068db7a50c12af80081f131e71c5291853f6150ad0ed0ec0e9e4d1f4f172b197aa071068256a8226aaac42967377141dc3a8f571915102eff1a4
7
- data.tar.gz: 0c21a7924482f948f40511c4575971d81387a84c88f214e8df039ffe1c0aa7980e8a025fc8efb0587e470a9ca5186362b9f400cad668b0c252d3ee950c1d59ea
6
+ metadata.gz: e4a973a0840c34dc033b5f512e9e5bb62618afa44f20fc5b9e6993a59ef0cbde59befc204becd175dd15db7f02f4952f516af9d77dfb9cbb8fd70fd17991fc32
7
+ data.tar.gz: 6b2dff4fb23a286a60a0cccc2cd618d17b38379148aad5d385463df8a81ce55542ec9cde451516a52c6dfaf68204f585682849d546c6989800c4006fac95c091
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- web47core (0.0.7)
4
+ web47core (0.0.8)
5
5
  activesupport (~> 5.0)
6
6
  aws-sdk-ec2 (>= 1.60, <= 1.151)
7
7
  delayed_job_mongoid (~> 2.3)
data/README.md CHANGED
@@ -37,4 +37,47 @@ bundle exec rake test
37
37
  # Deployment
38
38
  The `web47core` project is a gem that will be deployed via [Ruby Gems](https://rubygems.org). When an update is ready, the following steps should be followed
39
39
 
40
- 1. Build the gem `gem build`
40
+ 1. Build the gem `gem build web47core.gemspec`
41
+ 1. Push the new gem to [Ruby Gems](https://rubygems.org) `gem push web47core-<<version>>.gem`
42
+ 1. There may be a delay when using the gem file
43
+
44
+ # Usage
45
+ ## Importing the gem
46
+ To use the `app47core` gem in a project, first add the gem to your Gemfile in one of two ways
47
+
48
+ Using the gem from [Ruby Gems](https://rubygems.org)
49
+ ```
50
+ gem 'web47core'
51
+ ```
52
+
53
+ If you need the gem immediately or need to pull from development branch, you can use the git repo
54
+ ```
55
+ gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :master
56
+ ```
57
+ or from the develop branch
58
+ ```
59
+ gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :develop
60
+ ```
61
+
62
+ _Please do not ship to production code using the git repo, as the production servers will not have keys to pull from the web47core repo_
63
+
64
+ ## Features
65
+
66
+ ### Models
67
+ #### Concerns
68
+ 1. `StandardModel` - Includes the common set of includes, Mongoid, Auditable, AutoClearCache, etc.
69
+ 1. `CdnUrl` - Provide CDN URLs of your classes URLs when cdn_url is configured in system configuration
70
+ 1. `AutoClearCache` - Clears your objects cache out of Rails.cache using the object's id
71
+ #### System Configuration
72
+ Define a `SystemConfiguration` class in your project and import the core concern.
73
+
74
+ ```
75
+ class SystemConfiguration
76
+ include StandardModel
77
+ include CoreSystemConfiguration
78
+
79
+ # Include your additional system configuration fields and methods
80
+ field :google_sso_client_id, type: String
81
+ end
82
+ ```
83
+
@@ -64,6 +64,9 @@ module CoreSystemConfiguration
64
64
  # Validations
65
65
  #
66
66
  validates :environment, presence: true, uniqueness: true
67
+ validates :slack_support_channel, presence: true
68
+ validates :slack_sales_channel, presence: true
69
+ validates :default_time_zone, presence: true
67
70
  end
68
71
  base.extend ClassMethods
69
72
  end
@@ -116,12 +119,17 @@ module CoreSystemConfiguration
116
119
  end
117
120
  # rubocop:enable Style/MethodMissingSuper
118
121
  end
122
+
119
123
  #
120
124
  # Make sure the password doesn't get blanked out on an update
121
125
  #
122
- def update_attributes(params)
123
- %i[smtp_password aws_access_secret].each { |field| params[field] = send(field) if params[field].blank? }
124
- super(params)
126
+ def secure_fields
127
+ super + %i[smtp_password
128
+ aws_access_secret
129
+ mailgun_api_key
130
+ switchboard_stack_api_token
131
+ twilio_auth_token
132
+ zendesk_token]
125
133
  end
126
134
 
127
135
  #
@@ -247,6 +255,18 @@ module CoreSystemConfiguration
247
255
  [twilio_account_id.present?, twilio_auth_token.present?, twilio_phone_number.present?].all?
248
256
  end
249
257
 
258
+ #
259
+ # Determine if Slack is configured
260
+ #
261
+ # Examples
262
+ #
263
+ # switchboard_configured?
264
+ # # => true || false
265
+ #
266
+ def slack_configured?
267
+ slack_api_url.present?
268
+ end
269
+
250
270
  private
251
271
 
252
272
  #
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # For models that are updated via forms, we need an easy and consistent way to
5
+ # return a list of allowed parameters for a given model. While doing Model.attribute_names
6
+ # is working for most forms, it DOES NOT deal with relationships at all.
7
+ #
8
+ # This mix is should be included in those models, and the model then calls
9
+ # Model.allowed_param_names to retrieve a complete (dynamic) list of
10
+ # * Attribute names
11
+ # * Many to many relationships (has_many_and_belongs_to)
12
+ # * One to many relationships (belongs to)
13
+ #
14
+ module Formable
15
+ extend ActiveSupport::Concern
16
+ #
17
+ # Include the class methods into the model
18
+ #
19
+ def self.included(base)
20
+ base.class_eval do
21
+ base.extend ClassMethods
22
+ end
23
+ end
24
+
25
+ #
26
+ # Public: Add to class methods
27
+ #
28
+ module ClassMethods
29
+ #
30
+ # Return the complete list of key names that would appear in the form.
31
+ #
32
+ def allowed_param_names(filter_names = [])
33
+ # Always filter out the mongoid reserved items
34
+ filter_names += %w[created_at updated_at _type _id]
35
+ associations = all_associations
36
+ # filter out the relationship names so we don't have dups
37
+ associations.each { |association| filter_names << association.keys.first }
38
+ (field_names + associations).delete_if { |name| filter_names.include?(name) }
39
+ rescue StandardError
40
+ attribute_names.delete_if { |name| filter_names.include?(name) }
41
+ end
42
+
43
+ #
44
+ # allow the model to filter out a name if they want to, meaning the model
45
+ # can return a subset of attribute names
46
+ #
47
+ def field_names
48
+ attribute_names
49
+ end
50
+
51
+ #
52
+ # gather up the collections we care about and return them. For now, the
53
+ # many to many associations are the ones that need some extra help.
54
+ #
55
+ def all_associations
56
+ many_to_many_associations
57
+ end
58
+
59
+ #
60
+ # Return a collection of many to many assocations. We basically
61
+ # need to turn the current value returned by attribute names
62
+ #
63
+ # relationship_ids
64
+ #
65
+ # to
66
+ #
67
+ # { relationship_ids => [] }
68
+ #
69
+ # Telling the permit command to accept the value as an array of items.
70
+ #
71
+ def many_to_many_associations
72
+ associations = []
73
+ reflect_on_all_associations.each do |association|
74
+ next unless association.macro == :has_and_belongs_to_many
75
+
76
+ associations << { association.key => [] }
77
+ end
78
+ associations
79
+ end
80
+ end
81
+
82
+ #
83
+ # Remove updates for secure fields that come across as blank to start with and get removed on update
84
+ #
85
+ def update(params)
86
+ super(remove_blank_secure_fields(params))
87
+ end
88
+
89
+ alias :update_attributes :update
90
+
91
+ #
92
+ # Remove updates for secure fields that come across as blank to start with and get removed on update
93
+ #
94
+ def update!(params)
95
+ super(remove_blank_secure_fields(params))
96
+ end
97
+
98
+ alias :update_attributes! :update!
99
+
100
+ #
101
+ # List of secure fields, to add fields in concrete class, simply override this method
102
+ #
103
+ def secure_fields
104
+ []
105
+ end
106
+
107
+ def remove_blank_secure_fields(params)
108
+ secure_fields.each { |field| params.delete(field) if params[field].blank? }
109
+ params
110
+ end
111
+ end
@@ -13,8 +13,29 @@ module StandardModel
13
13
  include Mongoid::Timestamps
14
14
  # include App47Logger
15
15
  # include Auditable
16
- # include Formable
16
+ include Formable
17
17
  include AutoClearCache
18
18
  end
19
19
  end
20
+
21
+ #
22
+ # Mixin to add methods to the classes themselves
23
+ # Used by calling model.method_name
24
+ #
25
+ module ClassMethods
26
+ # Used by calling 'model.without_callback(*.args, &block) do'
27
+ def without_callback(*args, &_block)
28
+ skip_callback(*args)
29
+ result = yield
30
+ set_callback(*args)
31
+ result
32
+ end
33
+
34
+ #
35
+ # Turn the array into a list of options
36
+ #
37
+ def make_options(options)
38
+ options.collect { |t| [t, t.humanize] }
39
+ end
40
+ end
20
41
  end
data/lib/web47core.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'app/models/concerns/auto_clear_cache'
2
2
  require 'app/models/concerns/cdn_url'
3
+ require 'app/models/concerns/formable'
3
4
  require 'app/models/concerns/standard_model'
4
5
  require 'app/models/concerns/core_system_configuration'
@@ -0,0 +1,74 @@
1
+ require 'test_helper'
2
+
3
+ # TODO: CMS add tests for clearing by account id as well as id
4
+ class FormableTest < ActiveSupport::TestCase
5
+
6
+ context 'allowed_params' do
7
+ should 'return test form fields' do
8
+ allowed = TestForm.allowed_param_names
9
+ assert_equal 2, allowed.count
10
+ assert allowed.include?('name'), allowed.inspect
11
+ assert allowed.include?('password'), allowed.inspect
12
+ end
13
+ should 'return test input fields' do
14
+ allowed = TestInput.allowed_param_names
15
+ assert_equal 2, allowed.count
16
+ assert allowed.include?('input_type'), allowed.inspect
17
+ assert allowed.include?('test_form_id'), allowed.inspect
18
+ end
19
+ end
20
+ context 'update the model safely' do
21
+ setup do
22
+ @model = TestForm.create! name: 'name', password: 'abc123'
23
+ end
24
+ should 'update password' do
25
+ assert @model.update name: 'foo', password: 'bar'
26
+ assert_equal 'foo', @model.name
27
+ assert_equal 'bar', @model.password
28
+ end
29
+ should 'update not blank password' do
30
+ assert @model.update name: 'foo', password: ''
31
+ assert_equal 'foo', @model.name
32
+ assert_equal 'abc123', @model.password
33
+ end
34
+ should 'update not nil password' do
35
+ assert @model.update name: 'foo', password: nil
36
+ assert_equal 'foo', @model.name
37
+ assert_equal 'abc123', @model.password
38
+ end
39
+ should 'update! not blank password' do
40
+ assert @model.update! name: 'foo', password: ''
41
+ assert_equal 'foo', @model.name
42
+ assert_equal 'abc123', @model.password
43
+ end
44
+ should 'update_attributes! not blank password' do
45
+ assert @model.update_attributes! name: 'foo', password: ''
46
+ assert_equal 'foo', @model.name
47
+ assert_equal 'abc123', @model.password
48
+ end
49
+ should 'update_attributes not blank password' do
50
+ assert @model.update_attributes name: 'foo', password: ''
51
+ assert_equal 'foo', @model.name
52
+ assert_equal 'abc123', @model.password
53
+ end
54
+ end
55
+ end
56
+
57
+ class TestForm
58
+ include Mongoid::Document
59
+ include Formable
60
+ field :name
61
+ field :password
62
+ has_many :test_inputs
63
+
64
+ def secure_fields
65
+ super + %i[password]
66
+ end
67
+ end
68
+
69
+ class TestInput
70
+ include Mongoid::Document
71
+ include Formable
72
+ field :input_type
73
+ belongs_to :test_form
74
+ end
data/web47core.gemspec CHANGED
@@ -8,7 +8,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
8
8
  Gem::Specification.new do |spec|
9
9
  spec.required_ruby_version = '~> 2.4.1'
10
10
  spec.name = 'web47core'
11
- spec.version = '0.0.7'
11
+ spec.version = '0.0.8'
12
12
  spec.authors = ['Chris Schroeder']
13
13
  spec.email = ['chris@app47.com']
14
14
  spec.summary = 'App47 Web Core Library.'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web47core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schroeder
@@ -402,11 +402,13 @@ files:
402
402
  - lib/app/models/concerns/auto_clear_cache.rb
403
403
  - lib/app/models/concerns/cdn_url.rb
404
404
  - lib/app/models/concerns/core_system_configuration.rb
405
+ - lib/app/models/concerns/formable.rb
405
406
  - lib/app/models/concerns/standard_model.rb
406
407
  - lib/web47core.rb
407
408
  - test/fixtures/mongoid.yml
408
409
  - test/models/concerns/auto_clear_cache_test.rb
409
410
  - test/models/concerns/cdn_url_test.rb
411
+ - test/models/concerns/formable_test.rb
410
412
  - test/models/concerns/system_configuration_test.rb
411
413
  - test/rails_setup.rb
412
414
  - test/shoulda_macros/mongoid.rb
@@ -439,6 +441,7 @@ test_files:
439
441
  - test/fixtures/mongoid.yml
440
442
  - test/models/concerns/auto_clear_cache_test.rb
441
443
  - test/models/concerns/cdn_url_test.rb
444
+ - test/models/concerns/formable_test.rb
442
445
  - test/models/concerns/system_configuration_test.rb
443
446
  - test/rails_setup.rb
444
447
  - test/shoulda_macros/mongoid.rb