stockpot 0.2.1 → 0.4.2

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: 2683178878bc312393087331178faa1770530da412e17fdfbf17df3a25b11d38
4
- data.tar.gz: de6f99f3fb93c4679d752ea699fd5be7110caf2a9d1de5963670435f9285bd49
3
+ metadata.gz: 35586181cc1a1e03a7ca543171ea6d05fa572e403d8c17604619088e8642744b
4
+ data.tar.gz: dc6f55274b50b51586b26f822d65b562deaa6307009d5b8d53c06127ba1faf7c
5
5
  SHA512:
6
- metadata.gz: 71a3938561c28cf45fc99e7a90fdb452be47660978269677f41e369b4881c06b5a1c376845a7fce24b73bf8e0e77abe3be7dc250336f305552de5b192dc7e492
7
- data.tar.gz: e28cc6b970e452adf4b3a311ffa33b2a0cff9e5cf7f4183919d4b21f6620f169c73fbc85eb1d8104c7594a458290b261fb29922e9cc5b51d8860c24d914500aa
6
+ metadata.gz: a26a25b375412d81355095f6ce82804024b2843f5353ad66456e061b83639d4ead3327073b893a1be9c8c46094a0cd351240ef1e882ab2a37e73703cf61fc9a8
7
+ data.tar.gz: '098249ae8ae84a52a5067f25b2fab86b93c8db6cc6dc91e880271455b5a166fc4ee41137f962d6619b233f4fdd1d0da05e1c51a7d773ca43060428a84ffe59ad'
data/README.md CHANGED
@@ -79,7 +79,7 @@ Query for data. Accepts a array of objects that require at least a model name, b
79
79
 
80
80
  #### POST
81
81
 
82
- Create new data. Accepts an object specifying a single model with additional qualifiers.
82
+ Create new data. Accepts an an array of objects specifying a single model with additional qualifiers.
83
83
 
84
84
  * factory (required) - Specify which factory to create a record with.
85
85
  * list (optional) - Specify a count of items to create, default: 1
@@ -87,7 +87,7 @@ Create new data. Accepts an object specifying a single model with additional qua
87
87
  * attributes (optional) - An array of objects allowing for the specification of data to be used when creating records. Array position matches with list order if multiple records are desired.
88
88
 
89
89
  ```javascript
90
- {
90
+ [{
91
91
  factory: "user",
92
92
  traits: ["having_address"],
93
93
  attributes: [{
@@ -96,7 +96,7 @@ Create new data. Accepts an object specifying a single model with additional qua
96
96
  first_name: "Foo",
97
97
  last_name: "Bar"
98
98
  }]
99
- }
99
+ }]
100
100
  ```
101
101
 
102
102
  #### DELETE
@@ -129,7 +129,7 @@ Clears Rails & Redis caches and truncates Active Records databases. No body requ
129
129
  ### `/stockpot/redis`
130
130
 
131
131
  #### GET
132
-
132
+
133
133
  Query for data. Accepts key or field to use to search cache for record.
134
134
 
135
135
  ```javascript
@@ -139,6 +139,10 @@ Query for data. Accepts key or field to use to search cache for record.
139
139
  }
140
140
  ```
141
141
 
142
+ #### GET - Keys
143
+
144
+ Query for all keys within data. No body or argument required.
145
+
142
146
  #### POST - Create new data
143
147
 
144
148
  Accepts an object specifying a key, field, and value to be inserted into Redis cache.
@@ -168,7 +172,7 @@ Cypress.Commands.add("getRecords", args => {
168
172
  ```
169
173
 
170
174
  Our tests can then call this command like this
171
-
175
+
172
176
  ```javascript
173
177
  cy.getRecords([{ model: "user", id: user.id }])
174
178
  .then(res => {
@@ -2,10 +2,8 @@
2
2
 
3
3
  require "database_cleaner"
4
4
 
5
- require_dependency "stockpot/application_controller"
6
-
7
5
  module Stockpot
8
- class DatabaseCleanerController < ApplicationController
6
+ class DatabaseCleanerController < MainController
9
7
  # Clean database before, between, and after tests by clearing Rails
10
8
  # and REDIS caches and truncating the active record database.
11
9
  def index
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
-
3
- require_dependency "stockpot/application_controller"
4
-
5
2
  module Stockpot
6
- class HealthzController < ApplicationController
3
+ class HealthzController < MainController
7
4
  def index
8
5
  render json: { "message": "success" }, status: :ok
9
6
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ module Stockpot
3
+ module Helper
4
+ module Errors
5
+ def rescue_error(error)
6
+ logger = Logger.new(STDERR)
7
+ logger.warn(error)
8
+
9
+ case error
10
+ when NameError
11
+ return_error(error.message, error.backtrace.first(5), :bad_request)
12
+ when PG::Error
13
+ return_error("Postgres error: #{error.message}", error.backtrace.first(5), :internal_server_error)
14
+ when ActiveRecord::RecordInvalid, ActiveRecord::Validations, ActiveRecord::RecordNotDestroyed
15
+ return_error("In #{error.record.class} class, #{error.message}", error.backtrace.first(5), :expectation_failed)
16
+ else
17
+ return_error(error.message, error.backtrace.first(5),:internal_server_error)
18
+ end
19
+ end
20
+
21
+ def return_error(message, backtrace, status)
22
+ render json: { error: { status: status, backtrace: backtrace, message: message }}, status: status
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module Stockpot
3
+ class MainController < ActionController::API
4
+ include ActiveSupport::Rescuable
5
+ include Helper::Errors
6
+
7
+ rescue_from StandardError do |exception|
8
+ rescue_error(exception)
9
+ end
10
+ end
11
+ end
@@ -1,91 +1,115 @@
1
1
  # frozen_string_literal: true
2
-
3
- require_dependency "stockpot/application_controller"
4
-
5
2
  require "factory_bot_rails"
3
+ require "active_record/persistence"
6
4
 
7
5
  module Stockpot
8
- class RecordsController < ApplicationController
6
+ class RecordsController < MainController
9
7
  include ActiveSupport::Inflector
8
+ include ActiveRecord::Transactions
10
9
 
11
- def index
12
- return_error("You need to provide at least one model name as an argument", 400) && return if params.dig(:models).blank?
10
+ before_action only: %i[index destroy update] do
11
+ return_error("You need to provide at least one model name as an argument", 400) if params.dig(:models).blank?
12
+ end
13
+ before_action only: %i[create] do
14
+ return_error("You need to provide at least one factory name as an argument", 400) if params.dig(:factories).blank?
15
+ end
16
+ before_action do
17
+ @response_data = {}
18
+ end
13
19
 
14
- obj = {}
20
+ def index
15
21
  models.each_with_index do |element, i|
16
- model = element[:model].to_s
17
- obj[pluralize(model).camelize(:lower)] = model.camelize.constantize.where(models[i].except(:model))
18
- end
22
+ model = element[:model]
23
+ class_name = find_correct_class_name(model)
24
+ formatted_model = pluralize(model).camelize(:lower).gsub("::", "")
19
25
 
20
- render json: obj, status: :ok
26
+ @response_data[formatted_model] = [] unless @response_data.key?(formatted_model)
27
+ @response_data[formatted_model].concat(class_name.constantize.where(models[i].except(:model)))
28
+ @response_data[formatted_model].reverse!.uniq! { |obj| obj["id"] }
29
+ end
30
+ render json: @response_data, status: :ok
21
31
  end
22
32
 
23
33
  def create
24
- return_error("You need to provide at least one factory name as an argument", 400) && return if params.dig(:factory).blank?
25
-
26
- list = params[:list] || 1
27
- list.times do |n|
28
- if params[:traits].present? && params[:attributes].present?
29
- FactoryBot.create(factory, *traits, attributes[n])
30
- elsif params[:traits].blank? && params[:attributes].blank?
31
- # rubocop:disable Rails/SaveBang
32
- FactoryBot.create(factory)
33
- # rubocop:enable Rails/SaveBang
34
- elsif params[:attributes].blank?
35
- FactoryBot.create(factory, *traits)
36
- elsif params[:traits].blank?
37
- FactoryBot.create(factory, attributes[n])
34
+ ActiveRecord::Base.transaction do
35
+ factories.each do |element|
36
+ ids = []
37
+ list = element[:list] || 1
38
+ factory = element[:factory]
39
+ traits = element[:traits].map(&:to_sym) if element[:traits].present?
40
+
41
+ list.times do |n|
42
+ attributes = element[:attributes][n].to_h if element[:attributes].present?
43
+ factory_arguments = [ factory, *traits, attributes ].compact
44
+ @factory_instance = FactoryBot.create(*factory_arguments)
45
+ ids << @factory_instance.id
46
+ end
47
+
48
+ factory_name = pluralize(factory).camelize(:lower)
49
+
50
+ @response_data[factory_name] = [] unless @response_data.key?(factory_name)
51
+ @response_data[factory_name].concat(@factory_instance.class.name.constantize.where(id: ids))
38
52
  end
39
53
  end
40
- obj = factory.to_s.camelize.constantize.last(list)
41
- render json: obj, status: :created
54
+ render json: @response_data, status: :accepted
42
55
  end
43
56
 
44
57
  def destroy
45
- return_error("You need to provide at least one model name as an argument", 400) && return if params.dig(:models).blank?
46
-
47
- obj = {}
48
- models.each_with_index do |element, i|
49
- model = element[:model].to_s
50
- obj[pluralize(model).camelize(:lower)] = model.camelize.constantize.where(models[i].except(:model)).destroy_all
58
+ ActiveRecord::Base.transaction do
59
+ models.each_with_index do |element, i|
60
+ model = element[:model]
61
+ class_name = find_correct_class_name(model)
62
+ formatted_model = pluralize(model).camelize(:lower).gsub("::", "")
63
+
64
+ class_name.constantize.where(models[i].except(:model)).each do |record|
65
+ record.destroy!
66
+ @response_data[formatted_model] = [] unless @response_data.key?(formatted_model)
67
+ @response_data[formatted_model] << record
68
+ end
69
+ end
51
70
  end
52
-
53
- render json: obj, status: :accepted
71
+ render json: @response_data, status: :accepted
54
72
  end
55
73
 
56
74
  def update
57
- return_error("You need to provide at least one model name as an argument", 400) && return if params.dig(:models).blank?
58
-
59
- obj = {}
60
- models.each_with_index do |element, i|
61
- model = element[:model].to_s
62
- update_params = params.permit![:models][i][:update].to_h
63
- obj[pluralize(model).camelize(:lower)] = model.camelize.constantize.where(models[i].except(:model, :update)).update(update_params)
75
+ ActiveRecord::Base.transaction do
76
+ models.each_with_index do |element, i|
77
+ model = element[:model]
78
+ class_name = find_correct_class_name(model)
79
+ update_params = params.permit![:models][i][:update].to_h
80
+ attributes_to_search = models[i].except(:model, :update)
81
+ formatted_model = pluralize(model).camelize(:lower).gsub("::", "")
82
+
83
+ class_name.constantize.where(attributes_to_search).each do |record|
84
+ record.update!(update_params)
85
+ @response_data[formatted_model] = [] unless @response_data.key?(formatted_model)
86
+ @response_data[formatted_model] << class_name.constantize.find(record.id)
87
+ @response_data[formatted_model].reverse!.uniq! { |obj| obj["id"] }
88
+ end
89
+ end
64
90
  end
65
-
66
- render json: obj, status: :accepted
91
+ render json: @response_data, status: :accepted
67
92
  end
68
93
 
69
94
  private
70
95
 
71
- def return_error(message, status)
72
- render json: { "error": { "status": status, "message": message }}.to_json, status: status
73
- end
74
-
75
- def traits
76
- params[:traits].map(&:to_sym)
77
- end
78
-
79
- def factory
80
- params[:factory].to_sym
81
- end
82
-
83
- def attributes
84
- params.permit![:attributes].map(&:to_h)
96
+ def find_correct_class_name(model)
97
+ # We are getting the class name from the factory or we default to whatever we send in.
98
+ # Something to keep in mind "module/class_name".camelize will translate into "Module::ClassName"
99
+ # which is perfect for namespaces in case there is no factory associated with a specific model
100
+ if FactoryBot.factories.registered?(model)
101
+ FactoryBot.factories.find(model).build_class.to_s
102
+ else
103
+ model.camelize
104
+ end
85
105
  end
86
106
 
87
107
  def models
88
108
  params.permit![:models].map(&:to_h)
89
109
  end
110
+
111
+ def factories
112
+ params.permit![:factories].map(&:to_h)
113
+ end
90
114
  end
91
115
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module Stockpot
4
- class RedisController < ActionController::Base
3
+ class RedisController < MainController
5
4
  def index
6
5
  if params[:field].present?
7
6
  # Returns the value associated with :field in the hash stored at :key
@@ -25,5 +24,11 @@ module Stockpot
25
24
 
26
25
  render json: { status: 201 }
27
26
  end
27
+
28
+ def keys
29
+ record = REDIS.keys
30
+
31
+ render json: record.to_json, status: :ok
32
+ end
28
33
  end
29
34
  end
@@ -8,8 +8,9 @@ Stockpot::Engine.routes.draw do
8
8
 
9
9
  delete "/clean_database", to: "database_cleaner#index"
10
10
 
11
- get "/redis", to: "redis#index"
12
11
  post "/redis", to: "redis#create"
12
+ get "/redis", to: "redis#index"
13
+ get "/redis/keys", to: "redis#keys"
13
14
 
14
15
  get "/healthz", to: "healthz#index"
15
16
  end
@@ -2,6 +2,4 @@
2
2
 
3
3
  require "stockpot/engine"
4
4
 
5
- module Stockpot
6
- # Your code goes here...
7
- end
5
+ module Stockpot; end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stockpot
4
- VERSION = "0.2.1"
4
+ VERSION = "0.4.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stockpot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jayson Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-04 00:00:00.000000000 Z
11
+ date: 2020-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -100,61 +100,55 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '12.3'
103
+ version: '13.0'
104
104
  - - ">="
105
105
  - !ruby/object:Gem::Version
106
- version: 12.3.3
106
+ version: 13.0.1
107
107
  type: :development
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - "~>"
112
112
  - !ruby/object:Gem::Version
113
- version: '12.3'
113
+ version: '13.0'
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: 12.3.3
116
+ version: 13.0.1
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: rspec
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: '3.8'
123
+ version: '3.9'
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '3.8'
130
+ version: '3.9'
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: rspec-rails
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '3.8'
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- version: 3.8.2
137
+ version: '3.9'
141
138
  type: :development
142
139
  prerelease: false
143
140
  version_requirements: !ruby/object:Gem::Requirement
144
141
  requirements:
145
142
  - - "~>"
146
143
  - !ruby/object:Gem::Version
147
- version: '3.8'
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- version: 3.8.2
144
+ version: '3.9'
151
145
  - !ruby/object:Gem::Dependency
152
146
  name: spicerack-styleguide
153
147
  requirement: !ruby/object:Gem::Requirement
154
148
  requirements:
155
149
  - - ">="
156
150
  - !ruby/object:Gem::Version
157
- version: 0.16.2
151
+ version: 0.21.0
158
152
  - - "<"
159
153
  - !ruby/object:Gem::Version
160
154
  version: '1.0'
@@ -164,7 +158,7 @@ dependencies:
164
158
  requirements:
165
159
  - - ">="
166
160
  - !ruby/object:Gem::Version
167
- version: 0.16.2
161
+ version: 0.21.0
168
162
  - - "<"
169
163
  - !ruby/object:Gem::Version
170
164
  version: '1.0'
@@ -213,9 +207,10 @@ extra_rdoc_files: []
213
207
  files:
214
208
  - README.md
215
209
  - Rakefile
216
- - app/controllers/stockpot/application_controller.rb
217
210
  - app/controllers/stockpot/database_cleaner_controller.rb
218
211
  - app/controllers/stockpot/healthz_controller.rb
212
+ - app/controllers/stockpot/helper/errors.rb
213
+ - app/controllers/stockpot/main_controller.rb
219
214
  - app/controllers/stockpot/records_controller.rb
220
215
  - app/controllers/stockpot/redis_controller.rb
221
216
  - config/routes.rb
@@ -245,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
240
  - !ruby/object:Gem::Version
246
241
  version: '0'
247
242
  requirements: []
248
- rubygems_version: 3.0.6
243
+ rubygems_version: 3.0.3
249
244
  signing_key:
250
245
  specification_version: 4
251
246
  summary: Makes setting up test data in your Rails database from an external resource
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Stockpot
4
- class ApplicationController < ActionController::API
5
- # protect_from_forgery with: :exception
6
- end
7
- end