bscf-core 0.1.0

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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +8 -0
  5. data/app/controllers/bscf/core/application_controller.rb +6 -0
  6. data/app/jobs/bscf/core/application_job.rb +6 -0
  7. data/app/mailers/bscf/core/application_mailer.rb +8 -0
  8. data/app/models/bscf/core/application_record.rb +7 -0
  9. data/config/database.yml +17 -0
  10. data/config/routes.rb +2 -0
  11. data/lib/bscf/core/engine.rb +8 -0
  12. data/lib/bscf/core/version.rb +5 -0
  13. data/lib/bscf/core.rb +8 -0
  14. data/lib/tasks/bscf/core_tasks.rake +4 -0
  15. data/spec/dummy/Rakefile +6 -0
  16. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  17. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  18. data/spec/dummy/app/jobs/application_job.rb +7 -0
  19. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  20. data/spec/dummy/app/models/application_record.rb +3 -0
  21. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  22. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  23. data/spec/dummy/bin/dev +2 -0
  24. data/spec/dummy/bin/rails +4 -0
  25. data/spec/dummy/bin/rake +4 -0
  26. data/spec/dummy/bin/setup +34 -0
  27. data/spec/dummy/config/application.rb +43 -0
  28. data/spec/dummy/config/boot.rb +5 -0
  29. data/spec/dummy/config/cable.yml +10 -0
  30. data/spec/dummy/config/database.yml +17 -0
  31. data/spec/dummy/config/environment.rb +5 -0
  32. data/spec/dummy/config/environments/development.rb +67 -0
  33. data/spec/dummy/config/environments/production.rb +86 -0
  34. data/spec/dummy/config/environments/test.rb +53 -0
  35. data/spec/dummy/config/initializers/cors.rb +16 -0
  36. data/spec/dummy/config/initializers/filter_parameter_logging.rb +8 -0
  37. data/spec/dummy/config/initializers/inflections.rb +16 -0
  38. data/spec/dummy/config/locales/en.yml +31 -0
  39. data/spec/dummy/config/puma.rb +38 -0
  40. data/spec/dummy/config/routes.rb +3 -0
  41. data/spec/dummy/config/storage.yml +34 -0
  42. data/spec/dummy/config.ru +6 -0
  43. data/spec/dummy/log/development.log +17 -0
  44. data/spec/dummy/tmp/local_secret.txt +1 -0
  45. data/spec/examples.txt +3 -0
  46. data/spec/rails_helper.rb +46 -0
  47. data/spec/spec_helper.rb +34 -0
  48. data/spec/support/models/shared_examples.rb +49 -0
  49. data/spec/support/requests/shared_requests.rb +126 -0
  50. metadata +355 -0
@@ -0,0 +1,38 @@
1
+ # This configuration file will be evaluated by Puma. The top-level methods that
2
+ # are invoked here are part of Puma's configuration DSL. For more information
3
+ # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
4
+ #
5
+ # Puma starts a configurable number of processes (workers) and each process
6
+ # serves each request in a thread from an internal thread pool.
7
+ #
8
+ # You can control the number of workers using ENV["WEB_CONCURRENCY"]. You
9
+ # should only set this value when you want to run 2 or more workers. The
10
+ # default is already 1.
11
+ #
12
+ # The ideal number of threads per worker depends both on how much time the
13
+ # application spends waiting for IO operations and on how much you wish to
14
+ # prioritize throughput over latency.
15
+ #
16
+ # As a rule of thumb, increasing the number of threads will increase how much
17
+ # traffic a given process can handle (throughput), but due to CRuby's
18
+ # Global VM Lock (GVL) it has diminishing returns and will degrade the
19
+ # response time (latency) of the application.
20
+ #
21
+ # The default is set to 3 threads as it's deemed a decent compromise between
22
+ # throughput and latency for the average Rails application.
23
+ #
24
+ # Any libraries that use a connection pool or another resource pool should
25
+ # be configured to provide at least as many connections as the number of
26
+ # threads. This includes Active Record's `pool` parameter in `database.yml`.
27
+ threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
28
+ threads threads_count, threads_count
29
+
30
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
31
+ port ENV.fetch("PORT", 3000)
32
+
33
+ # Allow puma to be restarted by `bin/rails restart` command.
34
+ plugin :tmp_restart
35
+
36
+ # Specify the PID file. Defaults to tmp/pids/server.pid in development.
37
+ # In other environments, only set the PID file if requested.
38
+ pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ mount Bscf::Core::Engine => "/bscf-core"
3
+ end
@@ -0,0 +1,34 @@
1
+ test:
2
+ service: Disk
3
+ root: <%= Rails.root.join("tmp/storage") %>
4
+
5
+ local:
6
+ service: Disk
7
+ root: <%= Rails.root.join("storage") %>
8
+
9
+ # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
10
+ # amazon:
11
+ # service: S3
12
+ # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
13
+ # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
14
+ # region: us-east-1
15
+ # bucket: your_own_bucket-<%= Rails.env %>
16
+
17
+ # Remember not to checkin your GCS keyfile to a repository
18
+ # google:
19
+ # service: GCS
20
+ # project: your_project
21
+ # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
22
+ # bucket: your_own_bucket-<%= Rails.env %>
23
+
24
+ # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
25
+ # microsoft:
26
+ # service: AzureStorage
27
+ # storage_account_name: your_account_name
28
+ # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
29
+ # container: your_container_name-<%= Rails.env %>
30
+
31
+ # mirror:
32
+ # service: Mirror
33
+ # primary: local
34
+ # mirrors: [ amazon, google, microsoft ]
@@ -0,0 +1,6 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require_relative "config/environment"
4
+
5
+ run Rails.application
6
+ Rails.application.load_server
@@ -0,0 +1,17 @@
1
+ SQL (10.8ms) SET search_path TO public /*application='Dummy'*/
2
+  (722.5ms) CREATE DATABASE "bscf_dev" ENCODING = 'unicode' /*application='Dummy'*/
3
+ SQL (0.1ms) SET search_path TO public /*application='Dummy'*/
4
+  (105.0ms) CREATE DATABASE "bscf_test" ENCODING = 'unicode' /*application='Dummy'*/
5
+  (26.1ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY) /*application='Dummy'*/
6
+  (4.5ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL) /*application='Dummy'*/
7
+  (0.2ms) SELECT pg_try_advisory_lock(7136077842679658775) /*application='Dummy'*/
8
+ ActiveRecord::SchemaMigration Load (1.0ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC /*application='Dummy'*/
9
+ ActiveRecord::InternalMetadata Load (3.4ms) SELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = 'environment' ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1 /*application='Dummy'*/
10
+ ActiveRecord::InternalMetadata Create (1.7ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ('environment', 'development', '2025-03-24 13:19:53.793527', '2025-03-24 13:19:53.793529') RETURNING "key" /*application='Dummy'*/
11
+ Migrating to CreateBscfCorePeople (20250324131935)
12
+ TRANSACTION (0.1ms) BEGIN /*application='Dummy'*/
13
+  (9.7ms) CREATE TABLE "bscf_core_people" ("id" bigserial primary key, "name" character varying, "created_at" timestamp(6) NOT NULL, "updated_at" timestamp(6) NOT NULL) /*application='Dummy'*/
14
+ ActiveRecord::SchemaMigration Create (0.5ms) INSERT INTO "schema_migrations" ("version") VALUES ('20250324131935') RETURNING "version" /*application='Dummy'*/
15
+ TRANSACTION (1.4ms) COMMIT /*application='Dummy'*/
16
+  (0.6ms) SELECT pg_advisory_unlock(7136077842679658775) /*application='Dummy'*/
17
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC /*application='Dummy'*/
@@ -0,0 +1 @@
1
+ 3a22c82420f040930f412554d7919569ed231f0c16026a0795faffcbd126ec78eccdd546cacca4a594cfb3770ba0380c4da0352d5af1c3b7483f2f35bdff4ed0
data/spec/examples.txt ADDED
@@ -0,0 +1,3 @@
1
+ example_id | status | run_time |
2
+ -------------------------- | ------ | --------------- |
3
+ ./spec/sample_spec.rb[1:1] | passed | 0.00068 seconds |
@@ -0,0 +1,46 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ require "spec_helper"
3
+ ENV["RAILS_ENV"] ||= "test"
4
+ require_relative "../spec/dummy/config/environment"
5
+ abort("The Rails environment is running in production mode!") if Rails.env.production?
6
+
7
+ require "rspec/rails"
8
+ require "database_cleaner/active_record"
9
+ require "factory_bot_rails"
10
+ require "faker"
11
+ require "shoulda-matchers"
12
+
13
+ begin
14
+ ActiveRecord::Migration.maintain_test_schema!
15
+ rescue ActiveRecord::PendingMigrationError => e
16
+ abort e.to_s.strip
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.before(:suite) do
21
+ DatabaseCleaner.strategy = :transaction
22
+ DatabaseCleaner.clean_with(:truncation)
23
+ end
24
+
25
+ config.before do
26
+ DatabaseCleaner.strategy = :transaction
27
+ DatabaseCleaner.start
28
+ end
29
+
30
+ config.append_after do
31
+ DatabaseCleaner.clean
32
+ end
33
+
34
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
35
+ config.use_transactional_fixtures = true
36
+ config.infer_spec_type_from_file_location!
37
+ config.filter_rails_from_backtrace!
38
+ config.include FactoryBot::Syntax::Methods
39
+ end
40
+
41
+ Shoulda::Matchers.configure do |config|
42
+ config.integrate do |with|
43
+ with.test_framework(:rspec)
44
+ with.library(:rails)
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ require "simplecov"
2
+ # require "./spec/support/models/shared_examples"
3
+ # require "./spec/support/requests/shared_requests"
4
+ require "rspec/retry"
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with :rspec do |expectations|
8
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
9
+ end
10
+
11
+ config.mock_with :rspec do |mocks|
12
+ mocks.verify_partial_doubles = true
13
+ end
14
+
15
+ config.shared_context_metadata_behavior = :apply_to_host_groups
16
+ config.example_status_persistence_file_path = "spec/examples.txt"
17
+ config.disable_monkey_patching!
18
+ config.profile_examples = 10
19
+ config.order = :random
20
+ Kernel.srand config.seed
21
+
22
+ config.verbose_retry = true
23
+ config.display_try_failure_messages = true
24
+ config.around :each, :js do |ex|
25
+ ex.run_with_retry retry: 3
26
+ end
27
+ end
28
+
29
+ SimpleCov.start("rails") do
30
+ add_filter("/lib/")
31
+ add_filter("/bin/")
32
+ add_filter("/db/")
33
+ add_filter("/spec/")
34
+ end
@@ -0,0 +1,49 @@
1
+ module Bscf
2
+ module Core
3
+ VALIDATIONS = {
4
+ presence: "validate_presence_of",
5
+ uniqueness: "validate_uniqueness_of",
6
+ numericality: "validate_numericality_of",
7
+ inclusion: "validate_inclusion_of",
8
+ belong_to: "belong_to",
9
+ have_many: "have_many",
10
+ have_and_belong_to_many: "have_and_belong_to_many",
11
+ have_one: "have_one",
12
+ delegate: "delegate_method"
13
+ }.freeze
14
+
15
+ RSpec.shared_examples "model_shared_spec" do |factory, attribs, subj = true|
16
+ subject { create(factory) } if subj
17
+
18
+ it "has a valid factory" do
19
+ expect(create(factory)).to be_valid
20
+ end
21
+
22
+ attribs.each do |attr|
23
+ attr.each do |k, v|
24
+ if v.instance_of?(Array)
25
+ v.each do |validation|
26
+ if validation.instance_of?(Hash)
27
+ method = validation.keys[0]
28
+ options = validation.values[0]
29
+ it {
30
+ expect(subject).to(
31
+ options.inject(
32
+ send(VALIDATIONS[method], k)
33
+ ) do |o, p|
34
+ p[1].nil? ? o.send(p[0]) : o.send(p[0], p[1])
35
+ end
36
+ )
37
+ }
38
+ else
39
+ it { is_expected.to(send(VALIDATIONS[validation], k)) }
40
+ end
41
+ end
42
+ else
43
+ it { is_expected.to(send(VALIDATIONS[v], k)) }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,126 @@
1
+ module Bscf
2
+ module Core
3
+ RSpec.shared_examples "request_shared_spec" do |controller, field_count, exclude = []|
4
+ include Comee::Core::Engine.routes.url_helpers
5
+
6
+ let(:factory) { controller.classify.underscore.to_sym }
7
+ let(:clazz) { "Bscf::Core::#{controller.classify}".constantize }
8
+
9
+ unless exclude.include?(:index)
10
+ describe "GET /index" do
11
+ it "returns success response" do
12
+ count = clazz.count
13
+ 3.times { create(factory) }
14
+ get(send("#{controller}_url"), headers: headers)
15
+ expect(response).to be_successful
16
+ result = JSON(response.body)
17
+
18
+ expect(result["success"]).to be_truthy
19
+ expect(result["data"].count - count).to eq 3
20
+ end
21
+ end
22
+ end
23
+
24
+ unless exclude.include?(:show)
25
+ describe "GET /show" do
26
+ it "returns a success response" do
27
+ obj = create(factory)
28
+ get(send("#{controller.singularize}_url", obj), headers: headers)
29
+ expect(response).to be_successful
30
+ result = JSON(response.body)
31
+ expect(result["success"]).to be_truthy
32
+ expect(result["data"].count).to eq field_count
33
+ expect(result["data"]["id"]).to eq obj.id
34
+ end
35
+ end
36
+ end
37
+
38
+ unless exclude.include?(:create)
39
+ describe "POST /create" do
40
+ context "with valid params" do
41
+ it "creates a new object" do
42
+ params = {payload: valid_attributes}
43
+ expect do
44
+ post(
45
+ send("#{controller}_url"),
46
+ headers: headers,
47
+ params: params,
48
+ as: :json
49
+ )
50
+ end.to change(clazz, :count).by(1)
51
+ expect(response).to have_http_status(:created)
52
+ expect(response.content_type).to eq("application/json; charset=utf-8")
53
+
54
+ result = JSON(response.body)
55
+ expect(result["success"]).to be_truthy
56
+ end
57
+ end
58
+
59
+ context "with invalid params" do
60
+ it "renders a JSON response with errors for the new object" do
61
+ params = {payload: invalid_attributes}
62
+ post(
63
+ send("#{controller}_url"),
64
+ params: params,
65
+ headers: headers,
66
+ as: :json
67
+ )
68
+
69
+ expect(response).to have_http_status(422)
70
+ expect(response.content_type).to eq("application/json; charset=utf-8")
71
+
72
+ result = JSON(response.body)
73
+ expect(result["success"]).to be_falsey
74
+ expect(result["error"]).not_to be_blank
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ unless exclude.include?(:update)
81
+ describe "PUT /update" do
82
+ context "with valid params" do
83
+ it "updates the requested object" do
84
+ obj = create(factory)
85
+ params = {id: obj.to_param, payload: new_attributes}
86
+ put(
87
+ send("#{controller.singularize}_url", obj),
88
+ headers: headers,
89
+ params: params, as: :json
90
+ )
91
+ obj.reload
92
+
93
+ expect(response).to have_http_status(:ok)
94
+ expect(obj.send(new_attributes.keys[0])).to eq new_attributes.values[0]
95
+ expect(response.content_type).to eq("application/json; charset=utf-8")
96
+
97
+ result = JSON(response.body)
98
+ expect(result["success"]).to be_truthy
99
+ expect(result["data"]["id"]).to eq obj.id
100
+ end
101
+ end
102
+
103
+ context "with invalid params" do
104
+ it "renders a JSON response with errors for the object" do
105
+ obj = create(factory)
106
+ params = {id: obj.to_param, payload: invalid_attributes}
107
+ put(
108
+ send("#{controller.singularize}_url", obj),
109
+ headers: headers,
110
+ params: params,
111
+ as: :json
112
+ )
113
+
114
+ expect(response).to have_http_status(422)
115
+ expect(response.content_type).to eq("application/json; charset=utf-8")
116
+
117
+ result = JSON(response.body)
118
+ expect(result["success"]).to be_falsey
119
+ expect(result["error"]).not_to be_blank
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end