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