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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +72 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +38 -0
- data/Gemfile +38 -0
- data/LICENSE +26 -0
- data/README.md +439 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_content.js +2 -0
- data/app/assets/javascripts/spree/frontend/solidus_content.js +2 -0
- data/app/assets/stylesheets/spree/backend/solidus_content.css +4 -0
- data/app/assets/stylesheets/spree/frontend/solidus_content.css +4 -0
- data/app/controllers/solidus_content/resource_controller.rb +35 -0
- data/app/controllers/spree/admin/entries_controller.rb +25 -0
- data/app/controllers/spree/admin/entry_types_controller.rb +25 -0
- data/app/controllers/spree/solidus_content_controller.rb +13 -0
- data/app/models/solidus_content/application_record.rb +5 -0
- data/app/models/solidus_content/entry.rb +44 -0
- data/app/models/solidus_content/entry_type.rb +55 -0
- data/app/models/solidus_content/provider/fields.rb +20 -0
- data/app/views/spree/admin/entries/_form.html.erb +31 -0
- data/app/views/spree/admin/entries/_options_form.html.erb +18 -0
- data/app/views/spree/admin/entries/edit.html.erb +16 -0
- data/app/views/spree/admin/entries/index.html.erb +54 -0
- data/app/views/spree/admin/entries/new.html.erb +21 -0
- data/app/views/spree/admin/entry_types/_form.html.erb +30 -0
- data/app/views/spree/admin/entry_types/_options_form.html.erb +16 -0
- data/app/views/spree/admin/entry_types/edit.html.erb +16 -0
- data/app/views/spree/admin/entry_types/index.html.erb +54 -0
- data/app/views/spree/admin/entry_types/new.html.erb +21 -0
- data/app/views/spree/admin/shared/_solidus_content_sub_menu.html.erb +9 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/rspec +7 -0
- data/bin/sandbox +84 -0
- data/bin/setup +8 -0
- data/config/initializers/spree.rb +12 -0
- data/config/locales/en.yml +51 -0
- data/config/routes.rb +14 -0
- data/db/migrate/20200207135842_create_solidus_content_entries.rb +11 -0
- data/db/migrate/20200306110114_create_solidus_content_entry_types.rb +12 -0
- data/lib/generators/solidus_content/install/install_generator.rb +36 -0
- data/lib/generators/solidus_content/install/templates/initializer.rb +20 -0
- data/lib/solidus_content.rb +10 -0
- data/lib/solidus_content/active_record.rb +7 -0
- data/lib/solidus_content/configuration.rb +38 -0
- data/lib/solidus_content/engine.rb +19 -0
- data/lib/solidus_content/factories.rb +13 -0
- data/lib/solidus_content/providers.rb +23 -0
- data/lib/solidus_content/providers/contentful.rb +36 -0
- data/lib/solidus_content/providers/json.rb +27 -0
- data/lib/solidus_content/providers/prismic.rb +36 -0
- data/lib/solidus_content/providers/raw.rb +22 -0
- data/lib/solidus_content/providers/solidus_static_content.rb +23 -0
- data/lib/solidus_content/providers/yaml.rb +33 -0
- data/lib/solidus_content/version.rb +5 -0
- data/solidus_content.gemspec +36 -0
- data/spec/features/admin/content/create_entry_spec.rb +36 -0
- data/spec/features/admin/content/create_entry_type_spec.rb +36 -0
- data/spec/features/admin/content/delete_entry_spec.rb +20 -0
- data/spec/features/admin/content/delete_entry_type_spec.rb +20 -0
- data/spec/features/admin/content/edit_entry_spec.rb +45 -0
- data/spec/features/admin/content/edit_entry_type_spec.rb +44 -0
- data/spec/features/admin/content/list_entries_spec.rb +33 -0
- data/spec/features/admin/content/list_entry_types_spec.rb +33 -0
- data/spec/features/admin/sidebar_spec.rb +19 -0
- data/spec/features/render_content_with_views_spec.rb +41 -0
- data/spec/fixtures/content/example.json +1 -0
- data/spec/fixtures/content/example.yaml +1 -0
- data/spec/fixtures/content/example.yml +1 -0
- data/spec/fixtures/content/example_2.yaml +1 -0
- data/spec/models/solidus_content/entry_spec.rb +100 -0
- data/spec/models/solidus_content/entry_type_spec.rb +106 -0
- data/spec/solidus_content/configuration_spec.rb +37 -0
- data/spec/solidus_content/providers/contentful_spec.rb +56 -0
- data/spec/solidus_content/providers/json_spec.rb +33 -0
- data/spec/solidus_content/providers/prismic_spec.rb +82 -0
- data/spec/solidus_content/providers/solidus_static_content_spec.rb +34 -0
- data/spec/solidus_content/providers/yaml_spec.rb +51 -0
- data/spec/solidus_content_spec.rb +23 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/warden.rb +5 -0
- metadata +206 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Delete entry type', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
login_as admin_user
|
10
|
+
|
11
|
+
create(:entry_type)
|
12
|
+
visit spree.admin_entry_types_path
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'deletes entry type' do
|
16
|
+
expect {
|
17
|
+
accept_confirm { find('.delete-entry-type').click }
|
18
|
+
}.to change(SolidusContent::EntryType, :count).from(1).to(0)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Edit entry', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
let(:entry_type) { create(:entry_type, provider_name: :raw) }
|
9
|
+
let(:entry) { create(:entry, entry_type: entry_type) }
|
10
|
+
|
11
|
+
before { login_as admin_user }
|
12
|
+
|
13
|
+
describe 'Edit entry type' do
|
14
|
+
context 'when the entry type provides has fields' do
|
15
|
+
let(:fields) { %i[date bar foo] }
|
16
|
+
|
17
|
+
before do
|
18
|
+
allow(SolidusContent::Providers::RAW)
|
19
|
+
.to receive(:entry_fields).and_return(fields)
|
20
|
+
|
21
|
+
visit spree.edit_admin_entry_path(entry)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'changes the option types fields' do
|
25
|
+
fields.each do |field|
|
26
|
+
fill_in "solidus_content_entry_#{field}", with: 'foo'
|
27
|
+
end
|
28
|
+
|
29
|
+
expect {
|
30
|
+
click_on 'Update'
|
31
|
+
}.to change { SolidusContent::Entry.last.options }.from({}).to(
|
32
|
+
'date' => 'foo', 'bar' => 'foo', 'foo' => 'foo'
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when the entry type provides has not fields' do
|
38
|
+
before { visit spree.edit_admin_entry_path(entry) }
|
39
|
+
|
40
|
+
it 'does not show the option types fields' do
|
41
|
+
expect(page).not_to have_selector('.options-form')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Edit entry type', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
let(:entry_type) { create(:entry_type, provider_name: :raw) }
|
9
|
+
|
10
|
+
before { login_as admin_user }
|
11
|
+
|
12
|
+
describe 'Edit entry type' do
|
13
|
+
context 'when the entry type provides has fields' do
|
14
|
+
let(:fields) { %i[date bar foo] }
|
15
|
+
|
16
|
+
before do
|
17
|
+
allow(SolidusContent::Providers::RAW).to receive(:entry_type_fields)
|
18
|
+
.and_return(fields)
|
19
|
+
|
20
|
+
visit spree.edit_admin_entry_type_path(entry_type)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'changes the option types fields' do
|
24
|
+
fields.each do |field|
|
25
|
+
fill_in "solidus_content_entry_type_#{field}", with: 'foo'
|
26
|
+
end
|
27
|
+
|
28
|
+
expect {
|
29
|
+
click_on 'Update'
|
30
|
+
}.to change { SolidusContent::EntryType.last.options }.from({}).to(
|
31
|
+
'date' => 'foo', 'bar' => 'foo', 'foo' => 'foo'
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the entry type provides has not fields' do
|
37
|
+
before { visit spree.edit_admin_entry_type_path(entry_type) }
|
38
|
+
|
39
|
+
it 'does not show the option types fields' do
|
40
|
+
expect(page).not_to have_selector('.options-form')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'List entries', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
before { login_as admin_user }
|
9
|
+
|
10
|
+
context 'when there are not entries' do
|
11
|
+
before { visit spree.admin_entries_path }
|
12
|
+
|
13
|
+
it 'shows empty message' do
|
14
|
+
expect(page).to have_selector('.no-objects-found')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when there are entries' do
|
19
|
+
before do
|
20
|
+
create_list(:entry, 30)
|
21
|
+
|
22
|
+
visit spree.admin_entries_path
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'shows pagination' do
|
26
|
+
expect(page).to have_selector('.pagination', count: 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'shows the list of entries' do
|
30
|
+
expect(page).to have_selector('[data-hook="admin_entries_index_rows"]', count: 25)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'List entry types', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
before { login_as admin_user }
|
9
|
+
|
10
|
+
context 'when there are not entries' do
|
11
|
+
before { visit spree.admin_entry_types_path }
|
12
|
+
|
13
|
+
it 'shows empty message' do
|
14
|
+
expect(page).to have_selector('.no-objects-found')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when there are entries' do
|
19
|
+
before do
|
20
|
+
create_list(:entry_type, 30)
|
21
|
+
|
22
|
+
visit spree.admin_entry_types_path
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'shows pagination' do
|
26
|
+
expect(page).to have_selector('.pagination', count: 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'shows the list of entries' do
|
30
|
+
expect(page).to have_selector('[data-hook="admin_entry_types_index_rows"]', count: 25)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Sidebar', :js do
|
6
|
+
let(:admin_user) { create(:admin_user) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
login_as admin_user
|
10
|
+
|
11
|
+
visit spree.admin_path
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'shows Content menu item in the sidebar' do
|
15
|
+
within '[data-hook="admin_tabs"]' do
|
16
|
+
expect(page).to have_text(I18n.t(:content, scope: %i[spree admin tab]))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Render content with views' do
|
6
|
+
let(:post) { create(:entry_type, name: :post, provider_name: :raw) }
|
7
|
+
let(:view_path) { Rails.root.join('app/views/spree/solidus_content/post.html.erb') }
|
8
|
+
|
9
|
+
before do
|
10
|
+
view_path.dirname.mkpath
|
11
|
+
|
12
|
+
create(:entry, slug: 'one', options: { title: 'first post' }, entry_type: post)
|
13
|
+
create(:entry, slug: 'two', options: { title: 'second post' }, entry_type: post)
|
14
|
+
|
15
|
+
view_path.write(%{<main><h1><%= @entry.data[:title] %></h1></main>})
|
16
|
+
end
|
17
|
+
|
18
|
+
after { view_path.delete }
|
19
|
+
|
20
|
+
it 'rendering posts as views' do
|
21
|
+
visit '/c/post/one'
|
22
|
+
expect(page.find(:css, 'main h1')).to have_content 'first post'
|
23
|
+
|
24
|
+
visit '/c/post/two'
|
25
|
+
expect(page.find(:css, 'main h1')).to have_content 'second post'
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the default route is disabled' do
|
29
|
+
it 'gives 404 when the default route is disabled' do
|
30
|
+
SolidusContent.config.skip_default_route = true
|
31
|
+
Rails.application.reload_routes!
|
32
|
+
|
33
|
+
expect { visit '/c/post/one' }.to raise_error(ActionController::RoutingError)
|
34
|
+
|
35
|
+
SolidusContent.config.skip_default_route = false
|
36
|
+
Rails.application.reload_routes!
|
37
|
+
|
38
|
+
expect { visit '/c/post/one' }.not_to raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"foo": "json_bar"}
|
@@ -0,0 +1 @@
|
|
1
|
+
foo: yaml_bar
|
@@ -0,0 +1 @@
|
|
1
|
+
foo: yml_bar
|
@@ -0,0 +1 @@
|
|
1
|
+
foo: yaml_bar
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe SolidusContent::Entry do
|
6
|
+
let(:entry) { build(:entry) }
|
7
|
+
|
8
|
+
let(:post) { create(:entry_type, name: :post, provider_name: :raw) }
|
9
|
+
let(:home) { create(:entry_type, name: :home, provider_name: :raw) }
|
10
|
+
|
11
|
+
let!(:post_one) do
|
12
|
+
create(
|
13
|
+
:entry,
|
14
|
+
slug: "one",
|
15
|
+
options: { title: "first post" },
|
16
|
+
entry_type: post
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
let!(:home_default) do
|
21
|
+
create(
|
22
|
+
:entry,
|
23
|
+
slug: :default,
|
24
|
+
options: { title: "Homepage" },
|
25
|
+
entry_type: home
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a valid factory" do
|
30
|
+
expect(entry).to be_valid
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".data_for" do
|
34
|
+
context "with using correct type and slug" do
|
35
|
+
it "returns the stored data" do
|
36
|
+
expect(
|
37
|
+
described_class.data_for(:post, "one")
|
38
|
+
).to eq(title: "first post")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with using invalid type" do
|
43
|
+
it "will raise an ActiveRecord::RecordNotFound exception" do
|
44
|
+
expect{
|
45
|
+
described_class.data_for(:foo, "one")
|
46
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with using an invalid slug" do
|
51
|
+
it "will raise an ActiveRecord::RecordNotFound exception" do
|
52
|
+
expect{
|
53
|
+
described_class.data_for(:post, "foo")
|
54
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe ".by_type" do
|
60
|
+
context "with entry_type present" do
|
61
|
+
context "with symbol passed in for type" do
|
62
|
+
it "returns the correct Entries" do
|
63
|
+
expect(described_class.by_type(:post)).to include post_one
|
64
|
+
expect(described_class.by_type(:post)).not_to include home_default
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with EntryType instance passed in for type" do
|
69
|
+
it "returns the correct Entries" do
|
70
|
+
expect(described_class.by_type(post)).to include post_one
|
71
|
+
expect(described_class.by_type(post)).not_to include home_default
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "with using invalid type" do
|
77
|
+
it "will raise an ActiveRecord::RecordNotFound exception" do
|
78
|
+
expect{
|
79
|
+
described_class.by_type(:foo)
|
80
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
specify "#data" do
|
86
|
+
expect(entry.entry_type)
|
87
|
+
.to receive(:content_for).with(entry).and_return(data: :foo)
|
88
|
+
|
89
|
+
expect(entry.data).to eq(:foo)
|
90
|
+
end
|
91
|
+
|
92
|
+
specify "#content" do
|
93
|
+
content = instance_double(Hash)
|
94
|
+
|
95
|
+
expect(entry.entry_type)
|
96
|
+
.to receive(:content_for).with(entry).and_return(content)
|
97
|
+
|
98
|
+
expect(entry.content).to eq(content)
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe SolidusContent::EntryType do
|
6
|
+
it 'has a valid factory' do
|
7
|
+
expect(build(:entry_type)).to be_valid
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#content_for' do
|
11
|
+
let(:entry_options) { {} }
|
12
|
+
let(:entry_type_options) { {} }
|
13
|
+
let(:entry_type) { create(:entry_type, provider_name: provider_name) }
|
14
|
+
let(:entry) { create(:entry, slug: :example, entry_type: entry_type, options: entry_options) }
|
15
|
+
|
16
|
+
shared_examples 'a content provider' do
|
17
|
+
it 'calls the content-provider call method' do
|
18
|
+
expect(
|
19
|
+
SolidusContent.config.providers[provider_name.to_sym]
|
20
|
+
).to receive(:call).with(
|
21
|
+
slug: entry.slug,
|
22
|
+
type: entry_type.name,
|
23
|
+
provider: provider_name,
|
24
|
+
options: entry.options.symbolize_keys,
|
25
|
+
type_options: entry_type.options.symbolize_keys,
|
26
|
+
).and_return(content)
|
27
|
+
|
28
|
+
entry_type.content_for(entry)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with the JSON provider' do
|
33
|
+
let(:provider_name) { 'json' }
|
34
|
+
let(:entry_type_options) { { path: "#{FIXTURES_PATH}/content" } }
|
35
|
+
let(:content) { { foo: 'bar' } }
|
36
|
+
|
37
|
+
it_behaves_like 'a content provider'
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with the RAW provider' do
|
41
|
+
let(:provider_name) { 'raw' }
|
42
|
+
let(:entry_options) { { foo: 'bar' } }
|
43
|
+
let(:content) { { foo: 'bar' } }
|
44
|
+
|
45
|
+
it_behaves_like 'a content provider'
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with the solidus static content provider' do
|
49
|
+
let(:provider_name) { 'solidus_static_content' }
|
50
|
+
let(:content) { { foo: 'bar' } }
|
51
|
+
|
52
|
+
it_behaves_like 'a content provider'
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'with the Prismic provider' do
|
56
|
+
let(:provider_name) { 'prismic' }
|
57
|
+
let(:content) { { foo: 'bar' } }
|
58
|
+
|
59
|
+
it_behaves_like 'a content provider'
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with an unknown provider' do
|
63
|
+
let(:provider_name) { 'unknown' }
|
64
|
+
|
65
|
+
it 'raises an unknow provider error' do
|
66
|
+
expect { entry_type.content_for(entry_options) }
|
67
|
+
.to raise_error(SolidusContent::Configuration::UnknownProvider)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '.by_name' do
|
73
|
+
let!(:home) { create(:entry_type, name: :home, provider_name: :raw) }
|
74
|
+
|
75
|
+
context 'with existing name' do
|
76
|
+
it 'returns the entry_type' do
|
77
|
+
expect(described_class.by_name(:home)).to eql home
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with non-existing name' do
|
82
|
+
it 'will raise an ActiveRecord::RecordNotFound exception' do
|
83
|
+
expect{
|
84
|
+
described_class.by_name(:post)
|
85
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#provider_name_readonly?' do
|
91
|
+
subject(:entry_type) { build(:entry_type) }
|
92
|
+
|
93
|
+
it 'ensures is not changed after creation' do
|
94
|
+
expect(subject.provider_name_readonly?).to eq(false)
|
95
|
+
expect(subject.valid?).to eq(true)
|
96
|
+
|
97
|
+
subject.save!
|
98
|
+
expect(subject.provider_name_readonly?).to eq(true)
|
99
|
+
expect(subject.valid?).to eq(true)
|
100
|
+
|
101
|
+
subject.provider_name = 'foo'
|
102
|
+
expect(subject.provider_name_readonly?).to eq(true)
|
103
|
+
expect(subject.valid?).to eq(false)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|