web47core 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +44 -1
- data/lib/app/models/concerns/core_system_configuration.rb +23 -3
- data/lib/app/models/concerns/formable.rb +111 -0
- data/lib/app/models/concerns/standard_model.rb +22 -1
- data/lib/web47core.rb +1 -0
- data/test/models/concerns/formable_test.rb +74 -0
- data/web47core.gemspec +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e82f9597abea49e585537bf7b37dd78220136b34e2f2bc0ade5592e4d70ae9d
|
4
|
+
data.tar.gz: 523f737ac0beae20e3203ba4188c66e4cf5c09b8749084bf67dfd07fb039a3e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4a973a0840c34dc033b5f512e9e5bb62618afa44f20fc5b9e6993a59ef0cbde59befc204becd175dd15db7f02f4952f516af9d77dfb9cbb8fd70fd17991fc32
|
7
|
+
data.tar.gz: 6b2dff4fb23a286a60a0cccc2cd618d17b38379148aad5d385463df8a81ce55542ec9cde451516a52c6dfaf68204f585682849d546c6989800c4006fac95c091
|
data/Gemfile.lock
CHANGED
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
|
123
|
-
%i[smtp_password
|
124
|
-
|
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
|
-
|
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
@@ -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.
|
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.
|
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
|