alchemy_cms 3.2.0.rc1 → 3.2.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/README.md +2 -2
  5. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +5 -9
  6. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +0 -1
  7. data/app/assets/javascripts/alchemy/alchemy.windows.js.coffee +16 -4
  8. data/app/assets/stylesheets/alchemy/selects.scss +26 -2
  9. data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
  10. data/app/helpers/alchemy/elements_block_helper.rb +6 -6
  11. data/app/models/alchemy/language.rb +23 -11
  12. data/app/models/alchemy/page/page_naming.rb +29 -16
  13. data/app/views/alchemy/admin/elements/fold.js.erb +0 -1
  14. data/app/views/alchemy/admin/elements/order.js.erb +6 -4
  15. data/app/views/alchemy/admin/trash/index.html.erb +1 -0
  16. data/bin/alchemy +3 -3
  17. data/config/locales/alchemy.nl.yml +35 -35
  18. data/lib/alchemy/auth_accessors.rb +1 -1
  19. data/lib/alchemy/config.rb +3 -5
  20. data/lib/alchemy/errors.rb +14 -0
  21. data/lib/alchemy/modules.rb +1 -1
  22. data/lib/alchemy/mount_point.rb +1 -1
  23. data/lib/alchemy/tasks/helpers.rb +1 -1
  24. data/lib/alchemy/version.rb +1 -1
  25. data/lib/rails/generators/alchemy/base.rb +1 -1
  26. data/lib/rails/templates/alchemy.rb +1 -1
  27. data/spec/controllers/admin/elements_controller_spec.rb +1 -1
  28. data/spec/controllers/alchemy/api/contents_controller_spec.rb +41 -23
  29. data/spec/controllers/alchemy/api/elements_controller_spec.rb +49 -21
  30. data/spec/controllers/alchemy/api/pages_controller_spec.rb +50 -12
  31. data/spec/libraries/auth_accessors_spec.rb +3 -1
  32. data/spec/libraries/config_spec.rb +1 -3
  33. data/spec/libraries/modules_spec.rb +1 -1
  34. data/spec/libraries/mount_point_spec.rb +1 -1
  35. data/spec/models/content_spec.rb +2 -2
  36. data/spec/models/element_spec.rb +28 -26
  37. data/spec/models/language_spec.rb +3 -1
  38. data/spec/models/page_spec.rb +13 -1
  39. data/spec/tasks/helpers_spec.rb +15 -9
  40. data/vendor/assets/javascripts/tinymce/langs/de.js +3 -0
  41. data/vendor/assets/javascripts/tinymce/langs/es.js +5 -2
  42. data/vendor/assets/javascripts/tinymce/langs/fr.js +14 -11
  43. data/vendor/assets/javascripts/tinymce/langs/nl.js +6 -3
  44. data/vendor/assets/javascripts/tinymce/langs/ru.js +3 -0
  45. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.min.js +1 -1
  46. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.min.js +1 -1
  47. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.min.js +1 -1
  48. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.min.js +1 -1
  49. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  50. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  51. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  52. data/vendor/assets/javascripts/tinymce/tinymce.min.js +13 -11
  53. metadata +6 -5
@@ -66,7 +66,7 @@ module Alchemy
66
66
  if @@user_class_name.is_a?(String)
67
67
  @@user_class_name.constantize
68
68
  else
69
- raise 'Alchemy.user_class_name must be a String, not a Class.'
69
+ raise TypeError, 'Alchemy.user_class_name must be a String, not a Class.'
70
70
  end
71
71
  end
72
72
  rescue NameError => e
@@ -15,12 +15,12 @@ module Alchemy
15
15
  alias_method :parameter, :get
16
16
 
17
17
  # Returns a merged configuration of the following files
18
- #
18
+ #
19
19
  # Alchemy´s default config: +gems/../alchemy_cms/config/alchemy/config.yml+
20
20
  # Your apps default config: +your_app/config/alchemy/config.yml+
21
21
  # Environment specific config: +your_app/config/alchemy/development.config.yml+
22
22
  #
23
- # An environment specific config overwrites the settings of your apps default config,
23
+ # An environment specific config overwrites the settings of your apps default config,
24
24
  # while your apps default config has precedence over Alchemy´s default config.
25
25
  #
26
26
  def show
@@ -53,15 +53,13 @@ module Alchemy
53
53
  end
54
54
 
55
55
  # Merges all given configs together
56
- #
56
+ #
57
57
  def merge_configs!(*config_files)
58
58
  raise LoadError, 'No Alchemy config file found!' if config_files.map(&:blank?).all?
59
59
  config = {}
60
60
  config_files.each {|h| config.merge!(h.stringify_keys!) }
61
61
  config
62
62
  end
63
-
64
63
  end
65
-
66
64
  end
67
65
  end
@@ -17,6 +17,13 @@ module Alchemy
17
17
  end
18
18
  end
19
19
 
20
+ class DefaultLanguageNotDeletable < StandardError
21
+ # Raised if one tries to delete the default language.
22
+ def message
23
+ "Default language is not deletable!"
24
+ end
25
+ end
26
+
20
27
  class ElementDefinitionError < StandardError
21
28
  # Raised if element definition can not be found.
22
29
  def initialize(attributes)
@@ -39,6 +46,13 @@ module Alchemy
39
46
  # Raised if calling +image_file+ on a Picture object returns nil.
40
47
  end
41
48
 
49
+ class NotMountedError < StandardError
50
+ # Raised if Alchemy is not properly mounted in the apps routes file.
51
+ def message
52
+ "Alchemy mount point not found! Please run `bin/rake alchemy:mount'"
53
+ end
54
+ end
55
+
42
56
  class PictureInUseError < StandardError
43
57
  # Raised if the picture is still in use and can not be deleted.
44
58
  end
@@ -39,7 +39,7 @@ module Alchemy
39
39
  definition_from_subnavi(alchemy_module, name.symbolize_keys)
40
40
  end
41
41
  else
42
- raise "Could not find module definition for #{name}"
42
+ raise ArgumentError, "Could not find module definition for #{name}"
43
43
  end
44
44
  end
45
45
 
@@ -27,7 +27,7 @@ module Alchemy
27
27
  def path
28
28
  match = File.read(routes_file_path).match(MOUNT_POINT_REGEXP)
29
29
  if match.nil?
30
- raise "Alchemy mount point not found! Please run `bin/rake alchemy:mount'"
30
+ raise NotMountedError
31
31
  else
32
32
  match[1]
33
33
  end
@@ -13,7 +13,7 @@ module Alchemy
13
13
  def database_config
14
14
  raise "Could not find #{database_config_file}!" if !File.exists?(database_config_file)
15
15
  @database_config ||= begin
16
- config_file = YAML.load_file(database_config_file)
16
+ config_file = YAML.load(ERB.new(File.read(database_config_file)).result)
17
17
  config_file.fetch(environment)
18
18
  rescue KeyError
19
19
  raise "Database configuration for #{environment} not found!"
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
- VERSION = "3.2.0.rc1"
2
+ VERSION = "3.2.0"
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -32,7 +32,7 @@ module Alchemy
32
32
  end
33
33
 
34
34
  def load_alchemy_yaml(name)
35
- YAML.load_file "#{Rails.root}/config/alchemy/#{name}"
35
+ YAML.load(ERB.new(File.read("#{Rails.root}/config/alchemy/#{name}")).result)
36
36
  rescue Errno::ENOENT
37
37
  puts "\nERROR: Could not read config/alchemy/#{name} file. Please run: rails generate alchemy:scaffold"
38
38
  end
@@ -2,6 +2,6 @@
2
2
  require File.expand_path("../../../alchemy/version", __FILE__)
3
3
 
4
4
  gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: "3.2-stable"
5
- gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: "master"
5
+ gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: "3.2-stable"
6
6
 
7
7
  gem "capistrano-alchemy", github: "AlchemyCMS/capistrano-alchemy", branch: "master", group: "development"
@@ -89,7 +89,7 @@ module Alchemy
89
89
 
90
90
  it "sets a list of trashed element ids" do
91
91
  alchemy_xhr :post, :order, element_ids: [trashed_element.id]
92
- expect(assigns(:trashed_elements).to_a).to eq [trashed_element.id]
92
+ expect(assigns(:trashed_element_ids).to_a).to eq [trashed_element.id]
93
93
  end
94
94
 
95
95
  it "sets a new position to the element" do
@@ -2,22 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Api::ContentsController do
5
- # We need to be sure, that the timestamps are always the same,
6
- # while comparing json objects
7
- before do
8
- allow_any_instance_of(Alchemy::Content).
9
- to receive(:created_at).and_return(Time.now)
10
- allow_any_instance_of(Alchemy::Content).
11
- to receive(:updated_at).and_return(Time.now)
12
- allow_any_instance_of(Alchemy::EssenceText).
13
- to receive(:created_at).and_return(Time.now)
14
- allow_any_instance_of(Alchemy::EssenceText).
15
- to receive(:updated_at).and_return(Time.now)
16
- allow_any_instance_of(Alchemy::EssenceRichtext).
17
- to receive(:created_at).and_return(Time.now)
18
- allow_any_instance_of(Alchemy::EssenceRichtext).
19
- to receive(:updated_at).and_return(Time.now)
20
- end
21
5
 
22
6
  describe '#index' do
23
7
  let!(:page) { create(:page) }
@@ -26,9 +10,14 @@ module Alchemy
26
10
 
27
11
  it "returns all public contents as json objects" do
28
12
  alchemy_get :index, format: :json
13
+
29
14
  expect(response.status).to eq(200)
30
15
  expect(response.content_type).to eq('application/json')
31
- expect(response.body).to eq("{\"contents\":[#{ContentSerializer.new(content).to_json}]}")
16
+
17
+ result = JSON.parse(response.body)
18
+
19
+ expect(result).to have_key("contents")
20
+ expect(result['contents'].size).to eq(Alchemy::Content.count)
32
21
  end
33
22
 
34
23
  context 'with element_id' do
@@ -37,18 +26,29 @@ module Alchemy
37
26
 
38
27
  it "returns only contents from this element" do
39
28
  alchemy_get :index, element_id: other_element.id, format: :json
29
+
40
30
  expect(response.status).to eq(200)
41
31
  expect(response.content_type).to eq('application/json')
42
- expect(response.body).to eq("{\"contents\":[#{ContentSerializer.new(other_content).to_json}]}")
32
+
33
+ result = JSON.parse(response.body)
34
+
35
+ expect(result).to have_key("contents")
36
+ expect(result['contents'].size).to eq(1)
37
+ expect(result['contents'][0]['element_id']).to eq(other_element.id)
43
38
  end
44
39
  end
45
40
 
46
41
  context 'with empty element_id' do
47
42
  it "returns all contents" do
48
43
  alchemy_get :index, element_id: element.id, format: :json
44
+
49
45
  expect(response.status).to eq(200)
50
46
  expect(response.content_type).to eq('application/json')
51
- expect(response.body).to eq("{\"contents\":[#{ContentSerializer.new(content).to_json}]}")
47
+
48
+ result = JSON.parse(response.body)
49
+
50
+ expect(result).to have_key("contents")
51
+ expect(result['contents'].size).to eq(Alchemy::Content.count)
52
52
  end
53
53
  end
54
54
  end
@@ -65,9 +65,13 @@ module Alchemy
65
65
 
66
66
  it "returns content as json" do
67
67
  alchemy_get :show, id: content.id, format: :json
68
+
68
69
  expect(response.status).to eq(200)
69
70
  expect(response.content_type).to eq('application/json')
70
- expect(response.body).to eq(ContentSerializer.new(content).to_json)
71
+
72
+ result = JSON.parse(response.body)
73
+
74
+ expect(result['id']).to eq(content.id)
71
75
  end
72
76
 
73
77
  context 'requesting an restricted content' do
@@ -75,9 +79,14 @@ module Alchemy
75
79
 
76
80
  it "responds with 403" do
77
81
  alchemy_get :show, id: content.id, format: :json
82
+
78
83
  expect(response.content_type).to eq('application/json')
79
84
  expect(response.status).to eq(403)
80
- expect(response.body).to eq('{"error":"Not authorized"}')
85
+
86
+ result = JSON.parse(response.body)
87
+
88
+ expect(result).to have_key("error")
89
+ expect(result['error']).to eq("Not authorized")
81
90
  end
82
91
  end
83
92
  end
@@ -89,18 +98,27 @@ module Alchemy
89
98
 
90
99
  it 'returns the named content from element with given id.' do
91
100
  alchemy_get :show, element_id: element.id, name: content.name, format: :json
101
+
92
102
  expect(response.status).to eq(200)
93
103
  expect(response.content_type).to eq('application/json')
94
- expect(response.body).to eq(ContentSerializer.new(content).to_json)
104
+
105
+ result = JSON.parse(response.body)
106
+
107
+ expect(result['id']).to eq(content.id)
95
108
  end
96
109
  end
97
110
 
98
111
  context 'with empty element_id or name param' do
99
112
  it 'returns 404 error.' do
100
113
  alchemy_get :show, element_id: '', name: '', format: :json
114
+
101
115
  expect(response.status).to eq(404)
102
116
  expect(response.content_type).to eq('application/json')
103
- expect(response.body).to eq("{\"error\":\"Record not found\"}")
117
+
118
+ result = JSON.parse(response.body)
119
+
120
+ expect(result).to have_key("error")
121
+ expect(result['error']).to eq("Record not found")
104
122
  end
105
123
  end
106
124
  end
@@ -2,25 +2,24 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Api::ElementsController do
5
- # We need to be sure, that the timestamps are always the same,
6
- # while comparing json objects
7
- before do
8
- allow_any_instance_of(Alchemy::Element).
9
- to receive(:created_at).and_return(Time.now)
10
- allow_any_instance_of(Alchemy::Element).
11
- to receive(:updated_at).and_return(Time.now)
12
- end
13
5
 
14
6
  describe '#index' do
15
- let!(:page) { create(:public_page) }
16
- let!(:element) { create(:element, page: page) }
7
+ let(:page) { create(:public_page) }
8
+
9
+ before do
10
+ 2.times { create(:element, page: page) }
11
+ end
17
12
 
18
13
  it "returns all public elements as json objects" do
19
14
  alchemy_get :index, format: :json
15
+
20
16
  expect(response.status).to eq(200)
21
17
  expect(response.content_type).to eq('application/json')
22
- expect(response.body).to_not eq('{"elements:[]"}')
23
- expect(response.body).to eq("{\"elements\":[#{ElementSerializer.new(element).to_json}]}")
18
+
19
+ result = JSON.parse(response.body)
20
+
21
+ expect(result).to have_key('elements')
22
+ expect(result['elements'].size).to eq(Alchemy::Element.count)
24
23
  end
25
24
 
26
25
  context 'with page_id param' do
@@ -29,19 +28,29 @@ module Alchemy
29
28
 
30
29
  it "returns only elements from this page" do
31
30
  alchemy_get :index, page_id: other_page.id, format: :json
31
+
32
32
  expect(response.status).to eq(200)
33
33
  expect(response.content_type).to eq('application/json')
34
- expect(response.body).to eq("{\"elements\":[#{ElementSerializer.new(other_element).to_json}]}")
34
+
35
+ result = JSON.parse(response.body)
36
+
37
+ expect(result).to have_key('elements')
38
+ expect(result['elements'].size).to eq(1)
39
+ expect(result['elements'][0]['page_id']).to eq(other_page.id)
35
40
  end
36
41
  end
37
42
 
38
43
  context 'with empty page_id param' do
39
44
  it "returns all elements" do
40
45
  alchemy_get :index, page_id: '', format: :json
46
+
41
47
  expect(response.status).to eq(200)
42
48
  expect(response.content_type).to eq('application/json')
43
- expect(response.body).to_not eq('{"elements:[]"}')
44
- expect(response.body).to eq("{\"elements\":[#{ElementSerializer.new(element).to_json}]}")
49
+
50
+ result = JSON.parse(response.body)
51
+
52
+ expect(result).to have_key('elements')
53
+ expect(result['elements'].size).to eq(Alchemy::Element.count)
45
54
  end
46
55
  end
47
56
 
@@ -50,19 +59,29 @@ module Alchemy
50
59
 
51
60
  it "returns only elements named like this." do
52
61
  alchemy_get :index, named: 'news', format: :json
62
+
53
63
  expect(response.status).to eq(200)
54
64
  expect(response.content_type).to eq('application/json')
55
- expect(response.body).to eq("{\"elements\":[#{ElementSerializer.new(other_element).to_json}]}")
65
+
66
+ result = JSON.parse(response.body)
67
+
68
+ expect(result).to have_key('elements')
69
+ expect(result['elements'].size).to eq(1)
70
+ expect(result['elements'][0]['name']).to eq('news')
56
71
  end
57
72
  end
58
73
 
59
74
  context 'with empty named param' do
60
75
  it "returns all elements" do
61
76
  alchemy_get :index, named: '', format: :json
77
+
62
78
  expect(response.status).to eq(200)
63
79
  expect(response.content_type).to eq('application/json')
64
- expect(response.body).to_not eq('{"elements:[]"}')
65
- expect(response.body).to eq("{\"elements\":[#{ElementSerializer.new(element).to_json}]}")
80
+
81
+ result = JSON.parse(response.body)
82
+
83
+ expect(result).to have_key('elements')
84
+ expect(result['elements'].size).to eq(Alchemy::Element.count)
66
85
  end
67
86
  end
68
87
  end
@@ -77,9 +96,13 @@ module Alchemy
77
96
 
78
97
  it "returns element as json" do
79
98
  alchemy_get :show, id: element.id, format: :json
99
+
80
100
  expect(response.status).to eq(200)
81
101
  expect(response.content_type).to eq('application/json')
82
- expect(response.body).to eq(ElementSerializer.new(element).to_json)
102
+
103
+ result = JSON.parse(response.body)
104
+
105
+ expect(result['id']).to eq(element.id)
83
106
  end
84
107
 
85
108
  context 'requesting an restricted element' do
@@ -87,9 +110,14 @@ module Alchemy
87
110
 
88
111
  it "responds with 403" do
89
112
  alchemy_get :show, id: element.id, format: :json
90
- expect(response.content_type).to eq('application/json')
113
+
91
114
  expect(response.status).to eq(403)
92
- expect(response.body).to eq('{"error":"Not authorized"}')
115
+ expect(response.content_type).to eq('application/json')
116
+
117
+ result = JSON.parse(response.body)
118
+
119
+ expect(result).to have_key('error')
120
+ expect(result['error']).to eq("Not authorized")
93
121
  end
94
122
  end
95
123
  end
@@ -8,28 +8,43 @@ module Alchemy
8
8
 
9
9
  it "returns all public pages as json objects" do
10
10
  alchemy_get :index, format: :json
11
+
11
12
  expect(response.status).to eq(200)
12
13
  expect(response.content_type).to eq('application/json')
13
- expect(response.body).to eq("{\"pages\":[#{PageSerializer.new(page.parent).to_json},#{PageSerializer.new(page).to_json}]}")
14
+
15
+ result = JSON.parse(response.body)
16
+
17
+ expect(result).to have_key('pages')
18
+ expect(result['pages'].size).to eq(2)
14
19
  end
15
20
 
16
21
  context 'with page_layout' do
17
22
  let!(:other_page) { create(:public_page, page_layout: 'news') }
18
23
 
19
- it "returns only pages with this page layout" do
24
+ it "returns only page with this page layout" do
20
25
  alchemy_get :index, {page_layout: 'news', format: :json}
26
+
21
27
  expect(response.status).to eq(200)
22
28
  expect(response.content_type).to eq('application/json')
23
- expect(response.body).to eq("{\"pages\":[#{PageSerializer.new(other_page).to_json}]}")
29
+
30
+ result = JSON.parse(response.body)
31
+
32
+ expect(result).to have_key('pages')
33
+ expect(result['pages'].size).to eq(1)
24
34
  end
25
35
  end
26
36
 
27
37
  context 'with empty string as page_layout' do
28
38
  it "returns all pages" do
29
39
  alchemy_get :index, {page_layout: '', format: :json}
40
+
30
41
  expect(response.status).to eq(200)
31
42
  expect(response.content_type).to eq('application/json')
32
- expect(response.body).to eq("{\"pages\":[#{PageSerializer.new(page.parent).to_json},#{PageSerializer.new(page).to_json}]}")
43
+
44
+ result = JSON.parse(response.body)
45
+
46
+ expect(result).to have_key('pages')
47
+ expect(result['pages'].size).to eq(2)
33
48
  end
34
49
  end
35
50
  end
@@ -44,9 +59,13 @@ module Alchemy
44
59
 
45
60
  it "returns page as json" do
46
61
  alchemy_get :show, {urlname: page.urlname, format: :json}
62
+
47
63
  expect(response.status).to eq(200)
48
64
  expect(response.content_type).to eq('application/json')
49
- expect(response.body).to eq(PageSerializer.new(page).to_json)
65
+
66
+ result = JSON.parse(response.body)
67
+
68
+ expect(result['id']).to eq(page.id)
50
69
  end
51
70
 
52
71
  context 'requesting an restricted page' do
@@ -54,9 +73,14 @@ module Alchemy
54
73
 
55
74
  it "responds with 403" do
56
75
  alchemy_get :show, {urlname: page.urlname, format: :json}
57
- expect(response.content_type).to eq('application/json')
76
+
58
77
  expect(response.status).to eq(403)
59
- expect(response.body).to eq('{"error":"Not authorized"}')
78
+ expect(response.content_type).to eq('application/json')
79
+
80
+ result = JSON.parse(response.body)
81
+
82
+ expect(result).to have_key('error')
83
+ expect(result['error']).to eq("Not authorized")
60
84
  end
61
85
  end
62
86
 
@@ -65,9 +89,14 @@ module Alchemy
65
89
 
66
90
  it "responds with 403" do
67
91
  alchemy_get :show, {urlname: page.urlname, format: :json}
68
- expect(response.content_type).to eq('application/json')
92
+
69
93
  expect(response.status).to eq(403)
70
- expect(response.body).to eq('{"error":"Not authorized"}')
94
+ expect(response.content_type).to eq('application/json')
95
+
96
+ result = JSON.parse(response.body)
97
+
98
+ expect(result).to have_key('error')
99
+ expect(result['error']).to eq("Not authorized")
71
100
  end
72
101
  end
73
102
  end
@@ -75,9 +104,14 @@ module Alchemy
75
104
  context 'requesting an unknown page' do
76
105
  it "responds with 404" do
77
106
  alchemy_get :show, {urlname: 'not-existing', format: :json}
78
- expect(response.content_type).to eq('application/json')
107
+
79
108
  expect(response.status).to eq(404)
80
- expect(response.body).to eq('{"error":"Record not found"}')
109
+ expect(response.content_type).to eq('application/json')
110
+
111
+ result = JSON.parse(response.body)
112
+
113
+ expect(result).to have_key('error')
114
+ expect(result['error']).to eq("Record not found")
81
115
  end
82
116
  end
83
117
 
@@ -86,9 +120,13 @@ module Alchemy
86
120
 
87
121
  it "responds with json" do
88
122
  alchemy_get :show, {id: page.id, format: :json}
123
+
89
124
  expect(response.status).to eq(200)
90
125
  expect(response.content_type).to eq('application/json')
91
- expect(response.body).to eq(PageSerializer.new(page).to_json)
126
+
127
+ result = JSON.parse(response.body)
128
+
129
+ expect(result['id']).to eq(page.id)
92
130
  end
93
131
  end
94
132
  end