ninetails 0.0.1
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/MIT-LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +19 -0
- data/app/components/ninetails/element.rb +55 -0
- data/app/components/ninetails/element_definition.rb +67 -0
- data/app/components/ninetails/property.rb +11 -0
- data/app/components/ninetails/property_store.rb +22 -0
- data/app/components/ninetails/property_type.rb +27 -0
- data/app/components/ninetails/section_template.rb +66 -0
- data/app/controllers/ninetails/application_controller.rb +4 -0
- data/app/controllers/ninetails/page_revisions_controller.rb +31 -0
- data/app/controllers/ninetails/pages_controller.rb +14 -0
- data/app/controllers/ninetails/section_templates_controller.rb +17 -0
- data/app/models/ninetails/page.rb +37 -0
- data/app/models/ninetails/page_revision.rb +28 -0
- data/app/models/ninetails/page_revision_section.rb +6 -0
- data/app/models/ninetails/section.rb +30 -0
- data/config/initializers/error_classes.rb +4 -0
- data/config/initializers/json_stuff.rb +9 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20151006093040_create_pages.rb +10 -0
- data/db/migrate/20151006093559_create_page_revisions.rb +8 -0
- data/db/migrate/20151006093754_create_sections.rb +11 -0
- data/db/migrate/20151006094337_create_page_revision_sections.rb +8 -0
- data/db/migrate/20151111085201_add_message_to_page_revisions.rb +5 -0
- data/db/schema.rb +53 -0
- data/lib/ninetails.rb +4 -0
- data/lib/ninetails/engine.rb +37 -0
- data/lib/ninetails/version.rb +3 -0
- data/lib/tasks/ninetails_tasks.rake +8 -0
- data/spec/components/element_definition_spec.rb +104 -0
- data/spec/components/element_spec.rb +92 -0
- data/spec/components/property_spec.rb +34 -0
- data/spec/components/property_store_spec.rb +64 -0
- data/spec/components/property_type_spec.rb +69 -0
- data/spec/components/section_spec.rb +72 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/components/element/button.rb +7 -0
- data/spec/dummy/app/components/element/button_icon.rb +8 -0
- data/spec/dummy/app/components/element/figure.rb +7 -0
- data/spec/dummy/app/components/element/meta.rb +7 -0
- data/spec/dummy/app/components/element/text.rb +7 -0
- data/spec/dummy/app/components/property/icon.rb +8 -0
- data/spec/dummy/app/components/property/image.rb +10 -0
- data/spec/dummy/app/components/property/link.rb +11 -0
- data/spec/dummy/app/components/property/text.rb +8 -0
- data/spec/dummy/app/components/section_template/billboard.rb +14 -0
- data/spec/dummy/app/components/section_template/document_head.rb +10 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +35 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +12 -0
- data/spec/dummy/config/database.yml.travis +4 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/schema.rb +53 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/page_revisions.rb +8 -0
- data/spec/factories/pages.rb +25 -0
- data/spec/factories/sections.rb +15 -0
- data/spec/models/page_revision_spec.rb +5 -0
- data/spec/models/page_spec.rb +26 -0
- data/spec/models/section_spec.rb +113 -0
- data/spec/rails_helper.rb +60 -0
- data/spec/requests/page_revisions_spec.rb +117 -0
- data/spec/requests/pages_spec.rb +68 -0
- data/spec/requests/section_templates_spec.rb +17 -0
- data/spec/spec_helper.rb +98 -0
- data/spec/support/factory_girl.rb +5 -0
- data/spec/support/request_helpers.rb +9 -0
- data/spec/support/shared_examples.rb +34 -0
- metadata +378 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<style>
|
|
7
|
+
body {
|
|
8
|
+
background-color: #EFEFEF;
|
|
9
|
+
color: #2E2F30;
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-family: arial, sans-serif;
|
|
12
|
+
margin: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
div.dialog {
|
|
16
|
+
width: 95%;
|
|
17
|
+
max-width: 33em;
|
|
18
|
+
margin: 4em auto 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
div.dialog > div {
|
|
22
|
+
border: 1px solid #CCC;
|
|
23
|
+
border-right-color: #999;
|
|
24
|
+
border-left-color: #999;
|
|
25
|
+
border-bottom-color: #BBB;
|
|
26
|
+
border-top: #B00100 solid 4px;
|
|
27
|
+
border-top-left-radius: 9px;
|
|
28
|
+
border-top-right-radius: 9px;
|
|
29
|
+
background-color: white;
|
|
30
|
+
padding: 7px 12% 0;
|
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
h1 {
|
|
35
|
+
font-size: 100%;
|
|
36
|
+
color: #730E15;
|
|
37
|
+
line-height: 1.5em;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
div.dialog > p {
|
|
41
|
+
margin: 0 0 1em;
|
|
42
|
+
padding: 1em;
|
|
43
|
+
background-color: #F7F7F7;
|
|
44
|
+
border: 1px solid #CCC;
|
|
45
|
+
border-right-color: #999;
|
|
46
|
+
border-left-color: #999;
|
|
47
|
+
border-bottom-color: #999;
|
|
48
|
+
border-bottom-left-radius: 4px;
|
|
49
|
+
border-bottom-right-radius: 4px;
|
|
50
|
+
border-top-color: #DADADA;
|
|
51
|
+
color: #666;
|
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
|
53
|
+
}
|
|
54
|
+
</style>
|
|
55
|
+
</head>
|
|
56
|
+
|
|
57
|
+
<body>
|
|
58
|
+
<!-- This file lives in public/500.html -->
|
|
59
|
+
<div class="dialog">
|
|
60
|
+
<div>
|
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
|
62
|
+
</div>
|
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
|
64
|
+
</div>
|
|
65
|
+
</body>
|
|
66
|
+
</html>
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
# Default page revision factory has no sections... They're complicated to mock and make valid
|
|
4
|
+
# and all the tests which currently use them, build them manually anyway...
|
|
5
|
+
factory :page_revision, class: Ninetails::PageRevision do
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
sequence :url do |n|
|
|
4
|
+
"/foo/#{n}"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
factory :page, class: Ninetails::Page do
|
|
8
|
+
association :current_revision, factory: :page_revision
|
|
9
|
+
name "Home"
|
|
10
|
+
url
|
|
11
|
+
|
|
12
|
+
factory :page_with_revisions do
|
|
13
|
+
transient do
|
|
14
|
+
revisions_count 5
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
after :create do |page, evaluator|
|
|
18
|
+
# -1 because the page is created with a 'current_revision', so when you say revisions_count: 10,
|
|
19
|
+
# you'll only end up with 10 revisions instead of 11..
|
|
20
|
+
create_list :page_revision, evaluator.revisions_count - 1, page: page
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
FactoryGirl.define do
|
|
2
|
+
|
|
3
|
+
factory :document_head_section, class: Ninetails::Section do
|
|
4
|
+
type "DocumentHead"
|
|
5
|
+
tags SectionTemplate::DocumentHead.new.tags
|
|
6
|
+
elements SectionTemplate::DocumentHead.new.serialize_elements
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
factory :billboard_section, class: Ninetails::Section do
|
|
10
|
+
type "Billboard"
|
|
11
|
+
tags SectionTemplate::Billboard.new.tags
|
|
12
|
+
elements SectionTemplate::Billboard.new.serialize_elements
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Ninetails::Page, type: :model do
|
|
4
|
+
|
|
5
|
+
describe "building json" do
|
|
6
|
+
|
|
7
|
+
let(:page) { create :page }
|
|
8
|
+
let(:json) do
|
|
9
|
+
{
|
|
10
|
+
page: {
|
|
11
|
+
id: page.id,
|
|
12
|
+
name: page.name,
|
|
13
|
+
url: page.url,
|
|
14
|
+
revisionId: page.revision.id,
|
|
15
|
+
sections: page.sections_to_builder
|
|
16
|
+
}
|
|
17
|
+
}.to_json
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should build the page into json" do
|
|
21
|
+
expect(page.to_builder.target!).to eq json
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
module SectionTemplate
|
|
4
|
+
class TestSection < Ninetails::SectionTemplate
|
|
5
|
+
located_in :body
|
|
6
|
+
has_element :headline, Element::Text
|
|
7
|
+
has_element :button, Element::Button
|
|
8
|
+
has_many_elements :messages, Element::Text
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
RSpec.describe Ninetails::Section, type: :model do
|
|
13
|
+
|
|
14
|
+
describe "deserializing a json blob" do
|
|
15
|
+
let(:headline) { "Hello world!" }
|
|
16
|
+
let(:first_message) { "this is the first message" }
|
|
17
|
+
let(:second_message) { "and this is the second" }
|
|
18
|
+
|
|
19
|
+
let(:json) do
|
|
20
|
+
{
|
|
21
|
+
"name" => "",
|
|
22
|
+
"type" => "TestSection",
|
|
23
|
+
"tags" => { "position" => "body" },
|
|
24
|
+
"elements" => {
|
|
25
|
+
"headline" => {
|
|
26
|
+
"type" => "Text",
|
|
27
|
+
"content" => { "text" => headline }
|
|
28
|
+
},
|
|
29
|
+
"button" => {
|
|
30
|
+
"type" => "Button",
|
|
31
|
+
"link" => {
|
|
32
|
+
"url" => "/foo",
|
|
33
|
+
"title" => "Hello",
|
|
34
|
+
"text" => "world"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"messages" => [
|
|
38
|
+
{
|
|
39
|
+
"type" => "Text",
|
|
40
|
+
"content" => { "text" => first_message }
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type" => "Text",
|
|
44
|
+
"content" => { "text" => second_message }
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
let(:section) { Ninetails::Section.new(json) }
|
|
52
|
+
|
|
53
|
+
it "should create a SectionTemplate instance" do
|
|
54
|
+
section.deserialize
|
|
55
|
+
expect(section.template).to be_a SectionTemplate::TestSection
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should have an array of elements_instances" do
|
|
59
|
+
section.deserialize
|
|
60
|
+
expect(section.template.elements_instances.size).to eq 3
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should include an element for 'text', 'button', and 'link'" do
|
|
64
|
+
section.deserialize
|
|
65
|
+
expect(section.template.elements_instances[0].name).to eq :headline
|
|
66
|
+
expect(section.template.elements_instances[1].name).to eq :button
|
|
67
|
+
expect(section.template.elements_instances[2].name).to eq :messages
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "should be the correct type for 'text', 'button', and 'link'" do
|
|
71
|
+
section.deserialize
|
|
72
|
+
expect(section.template.elements_instances[0].type).to eq Element::Text
|
|
73
|
+
expect(section.template.elements_instances[1].type).to eq Element::Button
|
|
74
|
+
expect(section.template.elements_instances[2].type).to eq Element::Text
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should call deserialize on each element" do
|
|
78
|
+
expect(SectionTemplate::TestSection.find_element("headline")).to receive(:deserialize).with(json["elements"]["headline"])
|
|
79
|
+
expect(SectionTemplate::TestSection.find_element("button")).to receive(:deserialize).with(json["elements"]["button"])
|
|
80
|
+
expect(SectionTemplate::TestSection.find_element("messages")).to receive(:deserialize).with(json["elements"]["messages"])
|
|
81
|
+
section.deserialize
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should be possible to reserialize into json" do
|
|
85
|
+
section.deserialize
|
|
86
|
+
serialized = section.template.serialize.with_indifferent_access
|
|
87
|
+
expect(serialized[:elements][:headline][:content][:text]).to eq headline
|
|
88
|
+
expect(serialized[:elements][:messages][0][:content][:text]).to eq first_message
|
|
89
|
+
expect(serialized[:elements][:messages][1][:content][:text]).to eq second_message
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe "building json" do
|
|
95
|
+
|
|
96
|
+
let(:section) { build :document_head_section }
|
|
97
|
+
let(:json) do
|
|
98
|
+
{
|
|
99
|
+
id: section.id,
|
|
100
|
+
name: section.name,
|
|
101
|
+
type: section.type,
|
|
102
|
+
tags: section.tags,
|
|
103
|
+
elements: section.elements
|
|
104
|
+
}.to_json
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should build the section into json" do
|
|
108
|
+
expect(section.to_builder.target!).to eq json
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
ENV['RAILS_ENV'] ||= 'test'
|
|
3
|
+
# require File.expand_path('../../config/environment', __FILE__)
|
|
4
|
+
|
|
5
|
+
require File.expand_path("./../dummy/config/environment.rb", __FILE__)
|
|
6
|
+
ActiveRecord::Migrator.migrations_paths = [File.expand_path("./../dummy/db/migrate", __FILE__)]
|
|
7
|
+
ActiveRecord::Migrator.migrations_paths << [File.expand_path('./../../db/migrate', __FILE__)]
|
|
8
|
+
|
|
9
|
+
# Prevent database truncation if the environment is production
|
|
10
|
+
abort("The Rails environment is running in production mode!") if Rails.env.production?
|
|
11
|
+
require 'spec_helper'
|
|
12
|
+
require 'rspec/rails'
|
|
13
|
+
# Add additional requires below this line. Rails is not loaded until this point!
|
|
14
|
+
|
|
15
|
+
require 'factory_girl'
|
|
16
|
+
FactoryGirl.find_definitions
|
|
17
|
+
|
|
18
|
+
# Requires supporting ruby files with custom matchers and macros, etc, in
|
|
19
|
+
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
|
20
|
+
# run as spec files by default. This means that files in spec/support that end
|
|
21
|
+
# in _spec.rb will both be required and run as specs, causing the specs to be
|
|
22
|
+
# run twice. It is recommended that you do not name files matching this glob to
|
|
23
|
+
# end with _spec.rb. You can configure this pattern with the --pattern
|
|
24
|
+
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
|
25
|
+
#
|
|
26
|
+
# The following line is provided for convenience purposes. It has the downside
|
|
27
|
+
# of increasing the boot-up time by auto-requiring all files in the support
|
|
28
|
+
# directory. Alternatively, in the individual `*_spec.rb` files, manually
|
|
29
|
+
# require only the support files necessary.
|
|
30
|
+
#
|
|
31
|
+
# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
|
|
32
|
+
|
|
33
|
+
# Checks for pending migrations before tests are run.
|
|
34
|
+
# If you are not using ActiveRecord, you can remove this line.
|
|
35
|
+
ActiveRecord::Migration.maintain_test_schema!
|
|
36
|
+
|
|
37
|
+
RSpec.configure do |config|
|
|
38
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
|
39
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
|
40
|
+
|
|
41
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
|
42
|
+
# examples within a transaction, remove the following line or assign false
|
|
43
|
+
# instead of true.
|
|
44
|
+
config.use_transactional_fixtures = true
|
|
45
|
+
|
|
46
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
|
47
|
+
# based on their file location, for example enabling you to call `get` and
|
|
48
|
+
# `post` in specs under `spec/controllers`.
|
|
49
|
+
#
|
|
50
|
+
# You can disable this behaviour by removing the line below, and instead
|
|
51
|
+
# explicitly tag your specs with their type, e.g.:
|
|
52
|
+
#
|
|
53
|
+
# RSpec.describe UsersController, :type => :controller do
|
|
54
|
+
# # ...
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# The different available types are documented in the features, such as in
|
|
58
|
+
# https://relishapp.com/rspec/rspec-rails/docs
|
|
59
|
+
config.infer_spec_type_from_file_location!
|
|
60
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
describe "Page Revisions API" do
|
|
4
|
+
|
|
5
|
+
let(:page) { create :page_with_revisions, revisions_count: 5 }
|
|
6
|
+
|
|
7
|
+
describe "listing revisions" do
|
|
8
|
+
describe "with a valid page_id" do
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
get "/pages/#{page.id}/revisions"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should list the revisions which belong to that page" do
|
|
15
|
+
expect(response).to be_success
|
|
16
|
+
expect(json["revisions"].size).to eq 5
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "creating a revision" do
|
|
23
|
+
let(:valid_revision_params) do
|
|
24
|
+
{
|
|
25
|
+
"page_revision": {
|
|
26
|
+
"message": "",
|
|
27
|
+
"sections":[
|
|
28
|
+
{
|
|
29
|
+
"name": "",
|
|
30
|
+
"type": "DocumentHead",
|
|
31
|
+
"tags": {
|
|
32
|
+
"position": "head"
|
|
33
|
+
},
|
|
34
|
+
"elements": {
|
|
35
|
+
"title": {
|
|
36
|
+
"type": "Text",
|
|
37
|
+
"content": {
|
|
38
|
+
"text": "iZettle – Accept credit card payments with your iPhone, iPad or Android"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"description": {
|
|
42
|
+
"type": "Meta",
|
|
43
|
+
"content": {
|
|
44
|
+
"text": "Accept credit card payments on the go with iZettle. All you need is a smartphone or a tablet and our free app."
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
let(:invalid_revision_params) do
|
|
55
|
+
{
|
|
56
|
+
"page_revision": {
|
|
57
|
+
"message": "",
|
|
58
|
+
"sections":[
|
|
59
|
+
{
|
|
60
|
+
"name": "",
|
|
61
|
+
"type": "DocumentHead",
|
|
62
|
+
"tags": {
|
|
63
|
+
"position": "head"
|
|
64
|
+
},
|
|
65
|
+
"elements": {
|
|
66
|
+
"title": {
|
|
67
|
+
"type": "Text",
|
|
68
|
+
"content": {
|
|
69
|
+
"text": ""
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"description": {
|
|
73
|
+
"type": "Meta",
|
|
74
|
+
"content": {
|
|
75
|
+
"text": ""
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe "with valid sections" do
|
|
86
|
+
it "should create a revision" do
|
|
87
|
+
expect {
|
|
88
|
+
post "/pages/#{page.id}/revisions", valid_revision_params
|
|
89
|
+
}.to change { page.revisions.count }.by(1)
|
|
90
|
+
|
|
91
|
+
expect(response).to be_success
|
|
92
|
+
expect(json["page"]["revisionId"]).to_not be_nil
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should have created the correct number of sections" do
|
|
96
|
+
post "/pages/#{page.id}/revisions", valid_revision_params
|
|
97
|
+
expect(page.revisions.last.sections.size).to eq 1
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "with invalid sections" do
|
|
102
|
+
it "should not create a revision" do
|
|
103
|
+
expect {
|
|
104
|
+
post "/pages/#{page.id}/revisions", invalid_revision_params
|
|
105
|
+
}.not_to change { page.revisions.count }
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "should show error messages in the revision params" do
|
|
109
|
+
post "/pages/#{page.id}/revisions", invalid_revision_params
|
|
110
|
+
|
|
111
|
+
errors = json["page"]["sections"][0]["elements"]["title"]["content"]["errors"]
|
|
112
|
+
expect(errors).to eq({ "text"=>["can't be blank"] })
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|