tetadata 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 (84) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +28 -0
  3. data/Rakefile +22 -0
  4. data/app/controllers/concerns/exception_handlers.rb +19 -0
  5. data/app/controllers/concerns/jwt_payload.rb +19 -0
  6. data/app/controllers/concerns/response.rb +25 -0
  7. data/app/controllers/metadatastore/api/v2/admin/base_controller.rb +22 -0
  8. data/app/controllers/metadatastore/api/v2/admin/metadata_controller.rb +45 -0
  9. data/app/controllers/metadatastore/api/v2/public/base_controller.rb +13 -0
  10. data/app/controllers/metadatastore/api/v2/public/metadata_controller.rb +20 -0
  11. data/app/controllers/metadatastore/application_controller.rb +8 -0
  12. data/app/helpers/metadatastore/application_helper.rb +4 -0
  13. data/app/helpers/metadatastore/metadata_helper.rb +4 -0
  14. data/app/models/metadatastore/application_record.rb +5 -0
  15. data/app/models/metadatastore/metadata.rb +6 -0
  16. data/config/initializers/active_model.rb +13 -0
  17. data/config/routes.rb +22 -0
  18. data/db/migrate/20191120145404_create_metadatastore_metadata.rb +10 -0
  19. data/lib/metadatastore/engine.rb +17 -0
  20. data/lib/metadatastore/version.rb +3 -0
  21. data/lib/metadatastore.rb +5 -0
  22. data/lib/tasks/metadastore_tasks.rake +4 -0
  23. data/spec/controllers/metadatastore/api/v2/admin/metadata_controller_spec.rb +72 -0
  24. data/spec/controllers/metadatastore/api/v2/public/metadata_controller_spec.rb +49 -0
  25. data/spec/dummy/Rakefile +6 -0
  26. data/spec/dummy/app/assets/config/manifest.js +3 -0
  27. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  29. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  30. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  31. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  32. data/spec/dummy/app/javascript/packs/application.js +15 -0
  33. data/spec/dummy/app/jobs/application_job.rb +7 -0
  34. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  35. data/spec/dummy/app/models/application_record.rb +3 -0
  36. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  37. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  38. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  39. data/spec/dummy/bin/rails +4 -0
  40. data/spec/dummy/bin/rake +4 -0
  41. data/spec/dummy/bin/setup +33 -0
  42. data/spec/dummy/config/application.rb +30 -0
  43. data/spec/dummy/config/boot.rb +5 -0
  44. data/spec/dummy/config/cable.yml +10 -0
  45. data/spec/dummy/config/database.yml +17 -0
  46. data/spec/dummy/config/environment.rb +5 -0
  47. data/spec/dummy/config/environments/development.rb +62 -0
  48. data/spec/dummy/config/environments/production.rb +112 -0
  49. data/spec/dummy/config/environments/test.rb +48 -0
  50. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  51. data/spec/dummy/config/initializers/assets.rb +12 -0
  52. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  53. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  54. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  55. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  56. data/spec/dummy/config/initializers/inflections.rb +18 -0
  57. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  58. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/spec/dummy/config/locales/en.yml +33 -0
  60. data/spec/dummy/config/puma.rb +38 -0
  61. data/spec/dummy/config/routes.rb +3 -0
  62. data/spec/dummy/config/spring.rb +6 -0
  63. data/spec/dummy/config/storage.yml +34 -0
  64. data/spec/dummy/config.ru +5 -0
  65. data/spec/dummy/db/schema.rb +22 -0
  66. data/spec/dummy/log/development.log +1972 -0
  67. data/spec/dummy/log/test.log +1916 -0
  68. data/spec/dummy/public/404.html +67 -0
  69. data/spec/dummy/public/422.html +67 -0
  70. data/spec/dummy/public/500.html +66 -0
  71. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  72. data/spec/dummy/public/apple-touch-icon.png +0 -0
  73. data/spec/dummy/public/favicon.ico +0 -0
  74. data/spec/dummy/tmp/development_secret.txt +1 -0
  75. data/spec/factories/metadastore/metadata.rb +6 -0
  76. data/spec/factories/metadastore/sequences.rb +26 -0
  77. data/spec/models/metadastore/metadata_spec.rb +7 -0
  78. data/spec/rails_helper.rb +72 -0
  79. data/spec/routing/metadastore/metadata_routing_spec.rb +29 -0
  80. data/spec/spec_helper.rb +96 -0
  81. data/spec/support/api_helper.rb +46 -0
  82. data/spec/support/auth_helper.rb +15 -0
  83. data/spec/support/rspec_matchers.rb +17 -0
  84. metadata +270 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 01d95b1b040821a885b16f288d8d8959a2f49850177048324e829b84378ca0c9
4
+ data.tar.gz: 92895f5ad1eb193a896d63948b5f077609c6916fab113e674f0e8b6495ebb985
5
+ SHA512:
6
+ metadata.gz: 9ae99df7f8a94e9e4db8c9f1ad3801fe3d0cdfb263dc89660d87abb3cec360bddd3f140f6b8a1532d7437430187b801ac3899c67cb4a62e7f50c499ff15b3785
7
+ data.tar.gz: 70e7c28638e5b6c998d7e3c634508ce219d26fb0221c35a8b296e47324981a6e7aff3ae63076ad6b5601565a5b53a815e73635c896aec1cef0b562854a49dbfa
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Metadatastore
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'metadatastore'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install metadatastore
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Metadatastore'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExceptionHandlers
4
+ def self.included(base)
5
+ base.instance_eval do
6
+
7
+ rescue_from ActiveRecord::RecordInvalid do |e|
8
+ record = e.record
9
+ class_name = record.model_name.singular
10
+ errors = record.errors.api_messages.map { |err| "#{class_name}.#{err}" }
11
+ errors_response(errors)
12
+ end
13
+
14
+ rescue_from ActiveRecord::RecordNotFound do |_e|
15
+ error_response("record.not_found", 404)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTPayload
4
+ def jwt_payload
5
+ @jwt_payload ||= request.env.fetch("jwt.payload", {}).symbolize_keys
6
+ end
7
+
8
+ def uid
9
+ jwt_payload[:uid]
10
+ end
11
+
12
+ def email
13
+ jwt_payload[:email]
14
+ end
15
+
16
+ def role
17
+ jwt_payload[:role]
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Response
4
+ def json_response(object, status=:ok)
5
+ render json: object, status: status
6
+ end
7
+
8
+ def error_response(error, status=422)
9
+ data = "#{controller_namespace}.#{error}"
10
+ json_response({errors: [data]}, status)
11
+ end
12
+
13
+ def errors_response(errors, status=422)
14
+ data = errors.map { |error| "#{controller_namespace}.#{error}" }
15
+ json_response({errors: data}, status)
16
+ end
17
+
18
+ def not_found
19
+ render plain: "404 Not Found", status: 404
20
+ end
21
+
22
+ def controller_namespace
23
+ self.class.module_parent.name.split("::").last.underscore
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Metadatastore
5
+ module API
6
+ module V2
7
+ module Admin
8
+ class BaseController < ApplicationController
9
+ include JWTPayload
10
+
11
+ ADMIN_ROLES = %w[superadmin admin accountant compliance support technical].freeze
12
+
13
+ before_action :authorize_admin!
14
+
15
+ def authorize_admin!
16
+ not_found unless role.to_s.in?(ADMIN_ROLES)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Metadatastore
5
+ module API
6
+ module V2
7
+ module Admin
8
+ class MetadataController < BaseController
9
+ def index
10
+ json_response(Metadata.all, 200)
11
+ end
12
+
13
+ def search
14
+ json_response(Metadata.find_by!(key: params[:key]))
15
+ end
16
+
17
+ def create
18
+ metadata = Metadata.new(key: params[:key], value: JSON.parse(params[:value]))
19
+ metadata.save!
20
+
21
+ json_response(metadata, 201)
22
+ rescue JSON::ParserError => _e
23
+ json_response(error_response("metadata.invalid_metadata_value"), 422)
24
+ end
25
+
26
+ def update
27
+ metadata = Metadata.find_by!(key: params[:key])
28
+
29
+ metadata.update!(value: JSON.parse(sale_params['value']))
30
+
31
+ json_response(metadata, 200)
32
+ rescue JSON::ParserError => _e
33
+ json_response(error_response("metadata.invalid_metadata_value"), 422)
34
+ end
35
+
36
+ private
37
+
38
+ def sale_params
39
+ params.permit(:key, :value)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Metadatastore
5
+ module API
6
+ module V2
7
+ module Public
8
+ class BaseController < ApplicationController
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Metadatastore
5
+ module API
6
+ module V2
7
+ module Public
8
+ class MetadataController < BaseController
9
+ def index
10
+ json_response(Metadata.all, 200)
11
+ end
12
+
13
+ def search
14
+ json_response(Metadata.find_by!(key: params[:key]))
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ module Metadatastore
2
+ class ApplicationController < ActionController::Base
3
+ include Response
4
+ include ExceptionHandlers
5
+
6
+ skip_before_action :verify_authenticity_token
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module Metadatastore
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Metadatastore
2
+ module MetadataHelper
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Metadatastore
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Metadatastore
2
+ class Metadata < ApplicationRecord
3
+ validates :key, :value, presence: { message: "missing_" }
4
+ validates :key, uniqueness: { message: "_is_duplicated" }
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ Module.new do
4
+ def api_messages
5
+ map do |attr, err|
6
+ if err.start_with?("_")
7
+ [attr, err]
8
+ else
9
+ [err, attr]
10
+ end.join
11
+ end
12
+ end
13
+ end.tap { |m| ActiveSupport.on_load(:active_record) { ActiveModel::Errors.include(m) } }
data/config/routes.rb ADDED
@@ -0,0 +1,22 @@
1
+ Rails.application.routes.draw do
2
+ scope module: 'metadatastore' do
3
+ namespace :api do
4
+ namespace :v2 do
5
+ namespace :public do
6
+ resources :metadata, only: :index, param: :key do
7
+ collection do
8
+ get 'search'
9
+ end
10
+ end
11
+ end
12
+ namespace :admin do
13
+ resources :metadata, only: %i[index create update], param: :key do
14
+ collection do
15
+ get 'search'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ class CreateMetadatastoreMetadata < ActiveRecord::Migration[6.0]
2
+ def change
3
+ create_table :metadatastore_metadata do |t|
4
+ t.string :key
5
+ t.json :value
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Metadatastore
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Metadatastore
6
+
7
+ config.generators do |generators|
8
+ generators.test_framework :rspec
9
+ generators.fixture_replacement :factory_bot
10
+ generators.factory_bot dir: "spec/factories"
11
+ end
12
+
13
+ initializer "metadata.factories", after: "factory_bot.set_factory_paths" do
14
+ FactoryBot.definition_file_paths << File.expand_path("../../spec/factories", __dir__) if defined?(FactoryBot)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Metadatastore
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,5 @@
1
+ require "metadatastore/engine"
2
+
3
+ module Metadatastore
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :metadatastore do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe Metadatastore::API::V2::Admin::MetadataController, type: :controller do
6
+ let(:valid_attributes) do
7
+ {
8
+ key: "IEO.BTC.1",
9
+ value: JSON.dump(
10
+ "summary": "Summary of IEO"
11
+ )
12
+ }
13
+ end
14
+
15
+ let(:invalid_attributes) do
16
+ {
17
+ key: "IEO.BTC.1",
18
+ value: JSON.dump(nil)
19
+ }
20
+ end
21
+
22
+ let(:admin_jwt_payload) { generate(:admin_jwt_payload) }
23
+
24
+ before { inject_jwt_payload!(admin_jwt_payload) }
25
+
26
+ describe "GET #index" do
27
+ it "returns a success response" do
28
+ Metadatastore::Metadata.create! valid_attributes
29
+ get :index, params: {}
30
+ expect(response).to be_successful
31
+ end
32
+ end
33
+
34
+ describe "GET #search" do
35
+ it "returns a metadata by key" do
36
+ Metadatastore::Metadata.create! valid_attributes
37
+ get :search, params: {key: "IEO.BTC.1"}
38
+
39
+ result = JSON.parse(response.body)
40
+ expect(response).to be_successful
41
+ expect(result["key"]).to eq("IEO.BTC.1")
42
+ end
43
+ end
44
+
45
+ describe "POST #create" do
46
+ context "with valid params" do
47
+ it "creates a new Metadata" do
48
+ expect do
49
+ post :create, params: valid_attributes
50
+ end.to change(Metadatastore::Metadata, :count).by(1)
51
+ end
52
+ end
53
+
54
+ context "with invalid params" do
55
+ it "returns a success response" do
56
+ post :create, params: invalid_attributes
57
+ expect(response).to have_http_status 422
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "PUT #update" do
63
+ it "returns a metadata by key" do
64
+ Metadatastore::Metadata.create! valid_attributes
65
+ put :update, params: {key: "IEO.BTC.1", value: JSON.dump("link": "link")}
66
+
67
+ result = JSON.parse(response.body)
68
+ expect(response).to be_successful
69
+ expect(result["key"]).to eq("IEO.BTC.1")
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ RSpec.describe Metadatastore::API::V2::Public::MetadataController, type: :controller do
6
+
7
+ let(:valid_attributes) do
8
+ {
9
+ key: "IEO.BTC.1",
10
+ value: {
11
+ summary: "Summary of IEO"
12
+ }
13
+ }
14
+ end
15
+
16
+ let(:invalid_attributes) do
17
+ {
18
+ key: "IEO.BTC.1",
19
+ value: nil
20
+ }
21
+ end
22
+
23
+ describe "GET #index" do
24
+ it "returns a success response" do
25
+ Metadatastore::Metadata.create! valid_attributes
26
+ get :index, params: {}
27
+ expect(response).to be_successful
28
+ end
29
+ end
30
+
31
+ describe "GET #search" do
32
+ it "returns a metadata by key" do
33
+ Metadatastore::Metadata.create! valid_attributes
34
+ get :search, params: {key: "IEO.BTC.1"}
35
+
36
+ result = JSON.parse(response.body)
37
+ expect(response).to be_successful
38
+ expect(result["key"]).to eq("IEO.BTC.1")
39
+ end
40
+ end
41
+
42
+ describe "GET #serch" do
43
+ it "returns a success response" do
44
+ Metadatastore::Metadata.create! valid_attributes
45
+ get :index, params: {key: "IEO.BTC.1"}
46
+ expect(response).to be_successful
47
+ end
48
+ end
49
+ end