solidus_content 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 (89) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +72 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +20 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +38 -0
  8. data/Gemfile +38 -0
  9. data/LICENSE +26 -0
  10. data/README.md +439 -0
  11. data/Rakefile +6 -0
  12. data/app/assets/javascripts/spree/backend/solidus_content.js +2 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_content.js +2 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_content.css +4 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_content.css +4 -0
  16. data/app/controllers/solidus_content/resource_controller.rb +35 -0
  17. data/app/controllers/spree/admin/entries_controller.rb +25 -0
  18. data/app/controllers/spree/admin/entry_types_controller.rb +25 -0
  19. data/app/controllers/spree/solidus_content_controller.rb +13 -0
  20. data/app/models/solidus_content/application_record.rb +5 -0
  21. data/app/models/solidus_content/entry.rb +44 -0
  22. data/app/models/solidus_content/entry_type.rb +55 -0
  23. data/app/models/solidus_content/provider/fields.rb +20 -0
  24. data/app/views/spree/admin/entries/_form.html.erb +31 -0
  25. data/app/views/spree/admin/entries/_options_form.html.erb +18 -0
  26. data/app/views/spree/admin/entries/edit.html.erb +16 -0
  27. data/app/views/spree/admin/entries/index.html.erb +54 -0
  28. data/app/views/spree/admin/entries/new.html.erb +21 -0
  29. data/app/views/spree/admin/entry_types/_form.html.erb +30 -0
  30. data/app/views/spree/admin/entry_types/_options_form.html.erb +16 -0
  31. data/app/views/spree/admin/entry_types/edit.html.erb +16 -0
  32. data/app/views/spree/admin/entry_types/index.html.erb +54 -0
  33. data/app/views/spree/admin/entry_types/new.html.erb +21 -0
  34. data/app/views/spree/admin/shared/_solidus_content_sub_menu.html.erb +9 -0
  35. data/bin/console +17 -0
  36. data/bin/rails +7 -0
  37. data/bin/rails-engine +13 -0
  38. data/bin/rails-sandbox +16 -0
  39. data/bin/rake +7 -0
  40. data/bin/rspec +7 -0
  41. data/bin/sandbox +84 -0
  42. data/bin/setup +8 -0
  43. data/config/initializers/spree.rb +12 -0
  44. data/config/locales/en.yml +51 -0
  45. data/config/routes.rb +14 -0
  46. data/db/migrate/20200207135842_create_solidus_content_entries.rb +11 -0
  47. data/db/migrate/20200306110114_create_solidus_content_entry_types.rb +12 -0
  48. data/lib/generators/solidus_content/install/install_generator.rb +36 -0
  49. data/lib/generators/solidus_content/install/templates/initializer.rb +20 -0
  50. data/lib/solidus_content.rb +10 -0
  51. data/lib/solidus_content/active_record.rb +7 -0
  52. data/lib/solidus_content/configuration.rb +38 -0
  53. data/lib/solidus_content/engine.rb +19 -0
  54. data/lib/solidus_content/factories.rb +13 -0
  55. data/lib/solidus_content/providers.rb +23 -0
  56. data/lib/solidus_content/providers/contentful.rb +36 -0
  57. data/lib/solidus_content/providers/json.rb +27 -0
  58. data/lib/solidus_content/providers/prismic.rb +36 -0
  59. data/lib/solidus_content/providers/raw.rb +22 -0
  60. data/lib/solidus_content/providers/solidus_static_content.rb +23 -0
  61. data/lib/solidus_content/providers/yaml.rb +33 -0
  62. data/lib/solidus_content/version.rb +5 -0
  63. data/solidus_content.gemspec +36 -0
  64. data/spec/features/admin/content/create_entry_spec.rb +36 -0
  65. data/spec/features/admin/content/create_entry_type_spec.rb +36 -0
  66. data/spec/features/admin/content/delete_entry_spec.rb +20 -0
  67. data/spec/features/admin/content/delete_entry_type_spec.rb +20 -0
  68. data/spec/features/admin/content/edit_entry_spec.rb +45 -0
  69. data/spec/features/admin/content/edit_entry_type_spec.rb +44 -0
  70. data/spec/features/admin/content/list_entries_spec.rb +33 -0
  71. data/spec/features/admin/content/list_entry_types_spec.rb +33 -0
  72. data/spec/features/admin/sidebar_spec.rb +19 -0
  73. data/spec/features/render_content_with_views_spec.rb +41 -0
  74. data/spec/fixtures/content/example.json +1 -0
  75. data/spec/fixtures/content/example.yaml +1 -0
  76. data/spec/fixtures/content/example.yml +1 -0
  77. data/spec/fixtures/content/example_2.yaml +1 -0
  78. data/spec/models/solidus_content/entry_spec.rb +100 -0
  79. data/spec/models/solidus_content/entry_type_spec.rb +106 -0
  80. data/spec/solidus_content/configuration_spec.rb +37 -0
  81. data/spec/solidus_content/providers/contentful_spec.rb +56 -0
  82. data/spec/solidus_content/providers/json_spec.rb +33 -0
  83. data/spec/solidus_content/providers/prismic_spec.rb +82 -0
  84. data/spec/solidus_content/providers/solidus_static_content_spec.rb +34 -0
  85. data/spec/solidus_content/providers/yaml_spec.rb +51 -0
  86. data/spec/solidus_content_spec.rb +23 -0
  87. data/spec/spec_helper.rb +32 -0
  88. data/spec/support/warden.rb +5 -0
  89. metadata +206 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'solidus_core'
4
+ require 'solidus_support'
5
+
6
+ require 'solidus_content/version'
7
+ require 'solidus_content/engine'
8
+ require 'solidus_content/configuration'
9
+ require 'solidus_content/providers'
10
+ require 'solidus_content/active_record'
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ def self.table_name_prefix
5
+ 'solidus_content_'
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/inflections'
4
+
5
+ module SolidusContent
6
+ class Configuration
7
+ UnknownProvider = Class.new(StandardError)
8
+
9
+ # Register of content-providers, use symbols for keys and callables as
10
+ # values. Each content-provider will be called passing the `entry_options:`
11
+ # and `entry_type_options:`.
12
+ def providers
13
+ @providers ||= Hash.new do |_hash, key|
14
+ raise UnknownProvider, "Can't find a provider for #{key.inspect}"
15
+ end
16
+ end
17
+
18
+ # Set to true to prevent SolidusContent from adding the default route.
19
+ # See also the README and config/routes.rb.
20
+ attr_accessor :skip_default_route
21
+
22
+ def register_provider(name, provider)
23
+ if provider.is_a? Symbol
24
+ require "solidus_content/providers/#{provider.to_s.underscore}"
25
+ provider = SolidusContent::Providers.const_get(provider)
26
+ end
27
+ providers[name.to_sym] = provider
28
+ end
29
+ end
30
+
31
+ def self.config
32
+ @config ||= Configuration.new
33
+ end
34
+
35
+ def self.configure
36
+ yield config
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spree/core'
4
+ require 'solidus_content'
5
+
6
+ module SolidusContent
7
+ class Engine < Rails::Engine
8
+ include SolidusSupport::EngineExtensions
9
+
10
+ isolate_namespace ::Spree
11
+
12
+ engine_name 'solidus_content'
13
+
14
+ # use rspec for tests
15
+ config.generators do |g|
16
+ g.test_framework :rspec
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :entry_type, class: SolidusContent::EntryType do
5
+ sequence(:name) { |n| "entry_type_#{n}" }
6
+ options { {} }
7
+ provider_name { :json }
8
+ end
9
+
10
+ factory :entry, class: SolidusContent::Entry do
11
+ entry_type
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ # This module will be the namespace for default providers
5
+ module Providers
6
+ end
7
+
8
+ def self.provider_names
9
+ SolidusContent.config.providers.keys
10
+ end
11
+
12
+ def self.human_provider_name(name)
13
+ I18n.t("solidus_content.providers.#{name}")
14
+ end
15
+
16
+ # Register all the default providers
17
+ config.register_provider :json, :JSON
18
+ config.register_provider :raw, :RAW
19
+ config.register_provider :yaml, :YAML
20
+ config.register_provider :contentful, :Contentful
21
+ config.register_provider :prismic, :Prismic
22
+ config.register_provider :solidus_static_content, :SolidusStaticContent
23
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ module Providers
5
+ class Contentful
6
+ class << self
7
+ def call(input)
8
+ require 'contentful' unless defined?(::Contentful)
9
+
10
+ type_options = input.dig(:type_options)
11
+
12
+ client = ::Contentful::Client.new(
13
+ space: type_options[:contentful_space_id],
14
+ access_token: type_options[:contentful_access_token],
15
+ )
16
+
17
+ entry = client.entry(input.dig(:options, :entry_id))
18
+
19
+ input.merge(
20
+ data: entry.fields,
21
+ provider_client: client,
22
+ provider_entry: entry,
23
+ )
24
+ end
25
+
26
+ def entry_type_fields
27
+ %i[contentful_space_id contentful_access_token]
28
+ end
29
+
30
+ def entry_fields
31
+ %i[entry_id]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module SolidusContent
6
+ module Providers
7
+ class JSON
8
+ class << self
9
+ def call(input)
10
+ dir = Rails.root.join(input.dig(:type_options, :path))
11
+ file = dir.join(input[:slug] + '.json')
12
+ data = ::JSON.parse(file.read, symbolize_names: true)
13
+
14
+ input.merge(data: data)
15
+ end
16
+
17
+ def entry_type_fields
18
+ %i[path]
19
+ end
20
+
21
+ def entry_fields
22
+ []
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ module Providers
5
+ class Prismic
6
+ class << self
7
+ def call(input)
8
+ require 'prismic' unless defined?(::Prismic)
9
+
10
+ type_options = input.dig(:type_options)
11
+
12
+ client = ::Prismic.api(
13
+ type_options[:api_entry_point],
14
+ type_options.dig(:api_token)
15
+ )
16
+
17
+ entry = client.getByID(input.dig(:options, :id))
18
+
19
+ input.merge(
20
+ data: entry.fields,
21
+ provider_client: client,
22
+ provider_entry: entry,
23
+ )
24
+ end
25
+
26
+ def entry_type_fields
27
+ %i[api_entry_point api_token]
28
+ end
29
+
30
+ def entry_fields
31
+ %i[id]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Let the content come from the entry itself.
4
+ module SolidusContent
5
+ module Providers
6
+ class RAW
7
+ class << self
8
+ def call(input)
9
+ input.merge(data: input[:options])
10
+ end
11
+
12
+ def entry_type_fields
13
+ []
14
+ end
15
+
16
+ def entry_fields
17
+ []
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ module Providers
5
+ class SolidusStaticContent
6
+ class << self
7
+ def call(input)
8
+ slug = input.dig(:options, :slug) || input[:slug]
9
+
10
+ input.merge(data: Spree::Page.find_by!(slug: slug).attributes.symbolize_keys)
11
+ end
12
+
13
+ def entry_type_fields
14
+ []
15
+ end
16
+
17
+ def entry_fields
18
+ %i[slug]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module SolidusContent
6
+ module Providers
7
+ class YAML
8
+ class << self
9
+ def call(input)
10
+ dir = Rails.root.join(input.dig(:type_options, :path))
11
+ file = dir.join(input[:slug] + '.yml')
12
+ file = dir.join(input[:slug] + '.yaml') unless file.exist?
13
+
14
+ data = load(file)
15
+
16
+ input.merge(data: data)
17
+ end
18
+
19
+ def load(file)
20
+ ::YAML.load_file(file).symbolize_keys
21
+ end
22
+
23
+ def entry_type_fields
24
+ %i[path]
25
+ end
26
+
27
+ def entry_fields
28
+ []
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusContent
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/solidus_content/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'solidus_content'
7
+ spec.version = SolidusContent::VERSION
8
+ spec.authors = ['Andrea Vassallo', 'Elia Schito']
9
+ spec.email = 'contact@solidus.io'
10
+
11
+ spec.summary = 'Manage your Solidus content sources'
12
+ spec.description = ''
13
+ spec.homepage = 'https://github.com/nebulab/solidus_content#readme'
14
+ spec.license = 'BSD-3-Clause'
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/nebulab/solidus_content#readme'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/nebulab/solidus_content/releases'
19
+
20
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.5')
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
25
+
26
+ spec.files = files.grep_v(%r{^(test|spec|features)/})
27
+ spec.test_files = files.grep(%r{^(test|spec|features)/})
28
+ spec.bindir = "exe"
29
+ spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_dependency 'solidus_core', ['>= 2.0.0', '< 3']
33
+ spec.add_dependency 'solidus_support', '~> 0.5'
34
+
35
+ spec.add_development_dependency 'solidus_dev_support'
36
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Create entry', :js do
6
+ let(:admin_user) { create(:admin_user) }
7
+ let!(:entry_type) { create(:entry_type, provider_name: :raw) }
8
+
9
+ before do
10
+ login_as admin_user
11
+
12
+ visit spree.new_admin_entry_path
13
+ end
14
+
15
+ context 'with the correct information' do
16
+ it 'creates the entry type' do
17
+ expect {
18
+ click_on 'Create'
19
+ }.to change(SolidusContent::Entry, :count).by(1)
20
+ expect(SolidusContent::Entry.last.entry_type).to eq(entry_type)
21
+ end
22
+ end
23
+
24
+ context 'with the incorrect information' do
25
+ it 'shows error messages' do
26
+ expect {
27
+ fill_in 'solidus_content_entry_slug', with: ''
28
+ click_on 'Create'
29
+ }.not_to change(SolidusContent::EntryType, :count)
30
+
31
+ within '#errorExplanation' do
32
+ expect(page).to have_text("Slug can't be blank")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Create entry type', :js do
6
+ let(:admin_user) { create(:admin_user) }
7
+
8
+ before do
9
+ login_as admin_user
10
+
11
+ visit spree.new_admin_entry_type_path
12
+ end
13
+
14
+ context 'with the correct information' do
15
+ it 'creates the entry type' do
16
+ fill_in 'solidus_content_entry_type_name', with: 'Entry name'
17
+ find('#solidus_content_entry_type_provider_name').find(:xpath, 'option[2]').select_option
18
+
19
+ expect {
20
+ click_on 'Create'
21
+ }.to change(SolidusContent::EntryType, :count).by(1)
22
+ end
23
+ end
24
+
25
+ context 'with the incorrect information' do
26
+ it 'shows error messages' do
27
+ expect {
28
+ click_on 'Create'
29
+ }.not_to change(SolidusContent::EntryType, :count)
30
+
31
+ within '#errorExplanation' do
32
+ expect(page).to have_text("Name can't be blank")
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Delete entry', :js do
6
+ let(:admin_user) { create(:admin_user) }
7
+
8
+ before do
9
+ login_as admin_user
10
+
11
+ create(:entry)
12
+ visit spree.admin_entries_path
13
+ end
14
+
15
+ it 'deletes entry' do
16
+ expect {
17
+ accept_confirm { find('.delete-entry').click }
18
+ }.to change(SolidusContent::Entry, :count).from(1).to(0)
19
+ end
20
+ end