solidus_content 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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