constructor-pages 0.5.6 → 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/controllers/constructor_pages/pages_controller.rb +1 -1
- data/app/helpers/constructor_pages/code_name_uniq.rb +9 -0
- data/app/models/constructor_pages/field.rb +7 -10
- data/app/models/constructor_pages/page.rb +86 -43
- data/app/models/constructor_pages/template.rb +10 -10
- data/config/locales/en.yml +1 -0
- data/config/locales/ru.yml +1 -1
- data/spec/models/constructor_pages/field_model_spec.rb +22 -0
- data/spec/models/constructor_pages/page_model_spec.rb +224 -196
- data/spec/models/constructor_pages/template_model_spec.rb +0 -10
- data/spec/requests/constructor_pages/pages_controller_spec.rb +13 -0
- metadata +23 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2baa47a4688a68e29dcf737f3b12bb3f1eb7b758
|
4
|
+
data.tar.gz: 0e041e904853abf666db195b27a49b97c80ab332
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 18a6b01b23863c4b7f98db5613de1afab43cb9b71184bb3f789c8b9f5384da01deb50ad3dd6b07d06c87eb66e9c06856d9788ce5b34818eb336b43f4a54a9744
|
7
|
+
data.tar.gz: 550592c690084f29051ff33e4e2b07fe61f47b80dbd4feccb5db53c235805fafdfcebf3ae7e103537a6f608ab9ca4ce2d25e5bb605a715db61306d13829e8bc6
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
module ConstructorPages
|
4
4
|
class Field < ActiveRecord::Base
|
5
|
+
include CodeNameUniq
|
6
|
+
|
5
7
|
TYPES = %w{string integer float boolean text date html image}
|
6
8
|
|
7
9
|
attr_accessible :name, :code_name, :type_value, :template_id, :template
|
8
10
|
validates_presence_of :name
|
9
11
|
validates_uniqueness_of :code_name, :scope => :template_id
|
10
|
-
validate :
|
12
|
+
validate :code_name_uniqueness
|
11
13
|
|
12
14
|
after_create :create_page_fields
|
13
15
|
after_destroy :destroy_all_page_fields
|
@@ -57,15 +59,10 @@ module ConstructorPages
|
|
57
59
|
|
58
60
|
private
|
59
61
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
or template.self_and_ancestors.map{|t| t.code_name unless t.code_name == code_name}.include?(code_name.pluralize) \
|
65
|
-
or template.self_and_ancestors.map{|t| t.code_name unless t.code_name == code_name}.include?(code_name.singularize) \
|
66
|
-
or template.descendants.map{|t| t.code_name unless t.code_name == code_name}.include?(code_name.pluralize) \
|
67
|
-
or template.descendants.map{|t| t.code_name unless t.code_name == code_name}.include?(code_name.singularize)
|
68
|
-
errors.add(:base, 'Такой метод уже используется')
|
62
|
+
def check_code_name(code_name)
|
63
|
+
[code_name.pluralize, code_name.singularize].each do |name|
|
64
|
+
template.self_and_ancestors.map{|t| t.code_name unless t.code_name == code_name}.include?(name)
|
65
|
+
template.descendants.map{|t| t.code_name unless t.code_name == code_name}.include?(name)
|
69
66
|
end
|
70
67
|
end
|
71
68
|
|
@@ -28,25 +28,80 @@ module ConstructorPages
|
|
28
28
|
acts_as_nested_set
|
29
29
|
|
30
30
|
# Used for find page by request. It return first page if no request given
|
31
|
+
# @param request for example <tt>'/conditioners/split-systems/zanussi'</tt>
|
31
32
|
def self.find_by_request_or_first(request = nil)
|
32
|
-
request.nil? ? Page.first : Page.find_by_full_url(
|
33
|
+
request.nil? ? Page.first : Page.find_by_full_url(request)
|
33
34
|
end
|
34
35
|
|
35
|
-
# Generate full_url from parent
|
36
|
+
# Generate full_url from parent id and url
|
37
|
+
# @param parent_id integer
|
38
|
+
# @param url should looks like <tt>'hello-world-page'</tt> without leading slash
|
36
39
|
def self.full_url_generate(parent_id, url = '')
|
37
|
-
Page.find(parent_id).self_and_ancestors.map {|c| c.url}.append(url).join('/')
|
40
|
+
'/' + Page.find(parent_id).self_and_ancestors.map {|c| c.url}.append(url).join('/')
|
38
41
|
end
|
39
42
|
|
43
|
+
# Check code_name for field and template.
|
44
|
+
# When missing method Page find field or page in branch with plural and singular code_name so
|
45
|
+
# field and template code_name should be uniqueness for page methods
|
46
|
+
def self.check_code_name(code_name)
|
47
|
+
[code_name, code_name.pluralize, code_name.singularize].each do |name|
|
48
|
+
if Page.first.respond_to?(name)
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
# Get field by code_name
|
40
57
|
def field(code_name)
|
41
58
|
Field.find_by_code_name_and_template_id code_name, template_id
|
42
59
|
end
|
43
60
|
|
61
|
+
# Get value of field by code_name
|
44
62
|
def get_field_value(code_name)
|
45
63
|
field = field(code_name)
|
46
64
|
field.get_value_for(self) if field
|
47
65
|
end
|
48
66
|
|
49
|
-
|
67
|
+
# Set value of field by code_name and value
|
68
|
+
def set_field_value(code_name, value)
|
69
|
+
field = field(code_name)
|
70
|
+
field.set_value_for(self, value) if field
|
71
|
+
end
|
72
|
+
|
73
|
+
# Update all fields values with given params.
|
74
|
+
# @param params should looks like <tt>{price: 500, content: 'Hello'}</tt>
|
75
|
+
# @param reset_booleans reset all boolean fields to false before assign params
|
76
|
+
def update_fields_values(params, reset_booleans = true)
|
77
|
+
fields.each do |field|
|
78
|
+
value = params[field.code_name.to_sym]
|
79
|
+
|
80
|
+
_type_object = field.find_or_create_type_object(self)
|
81
|
+
_type_object.value = 0 if field.type_value == 'boolean' and reset_booleans
|
82
|
+
|
83
|
+
if value
|
84
|
+
_type_object.value = field.type_value == 'date' ? parse_date(value).to_s : value
|
85
|
+
end
|
86
|
+
|
87
|
+
_type_object.save
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Remove all fields values
|
92
|
+
def remove_fields_values
|
93
|
+
fields.each {|f| f.remove_values_for self}
|
94
|
+
end
|
95
|
+
|
96
|
+
# Search page by template code_name in same branch of pages and templates.
|
97
|
+
# It allows to call page.category.brand.series.model etc.
|
98
|
+
#
|
99
|
+
# Return one page if founded in ancestors,
|
100
|
+
# and return array of pages if founded in descendants
|
101
|
+
#
|
102
|
+
# It determines if code_name is singular or nor
|
103
|
+
# @param code_name template code name
|
104
|
+
def find_page_in_branch(code_name)
|
50
105
|
_template = Template.find_by_code_name code_name.singularize
|
51
106
|
|
52
107
|
if _template
|
@@ -57,54 +112,40 @@ module ConstructorPages
|
|
57
112
|
end
|
58
113
|
end
|
59
114
|
|
60
|
-
alias_method :
|
115
|
+
alias_method :find_pages_in_branch, :find_page_in_branch
|
61
116
|
|
62
|
-
def
|
63
|
-
field = field(code_name)
|
64
|
-
field.set_value_for(self, value) if field
|
65
|
-
end
|
117
|
+
def published?; active end
|
66
118
|
|
67
|
-
|
119
|
+
alias_method :active?, :published?
|
68
120
|
|
121
|
+
# Returns page hash attributes with fields.
|
122
|
+
#
|
123
|
+
# Default attributes are name and title. Options param allows to add more.
|
124
|
+
# @param options default merge name and title page attributes
|
69
125
|
def as_json(options = {})
|
70
126
|
options = {name: self.name, title: self.title}.merge options
|
71
127
|
|
72
|
-
|
73
|
-
options
|
128
|
+
fields.each do |field|
|
129
|
+
options.merge!({field.code_name.to_sym => field.get_value_for(self)})
|
74
130
|
end
|
75
131
|
|
76
132
|
options
|
77
133
|
end
|
78
134
|
|
79
|
-
#
|
80
|
-
def
|
81
|
-
fields.each {|f| f.remove_values_for self}
|
82
|
-
end
|
83
|
-
|
84
|
-
# update all type fields
|
85
|
-
def update_fields_values(params, reset_booleans = true)
|
86
|
-
fields.each do |field|
|
87
|
-
value = params[field.code_name.to_sym]
|
88
|
-
|
89
|
-
_type_object = field.find_or_create_type_object(self)
|
90
|
-
_type_object.value = 0 if field.type_value == 'boolean' and reset_booleans
|
91
|
-
|
92
|
-
if value
|
93
|
-
_type_object.value = field.type_value == 'date' ? parse_date(value).to_s : value
|
94
|
-
end
|
95
|
-
|
96
|
-
_type_object.save
|
97
|
-
end
|
98
|
-
end
|
135
|
+
# Check if link specified
|
136
|
+
def redirect?; url != link && !link.empty? end
|
99
137
|
|
138
|
+
# When method missing it get/set field value or get page in branch
|
139
|
+
#
|
140
|
+
# Examples:
|
141
|
+
# page.content = 'Hello world'
|
142
|
+
# puts page.price
|
143
|
+
# page.brand.models.each do...
|
100
144
|
def method_missing(name, *args, &block)
|
101
145
|
name = name.to_s
|
102
|
-
name[-1] == '=' ? set_field_value(name[0..-2], args[0]) : get_field_value(name) ||
|
146
|
+
name[-1] == '=' ? set_field_value(name[0..-2], args[0]) : get_field_value(name) || find_pages_in_branch(name)
|
103
147
|
end
|
104
148
|
|
105
|
-
# check if link specified
|
106
|
-
def redirect?; url != link && !link.empty? end
|
107
|
-
|
108
149
|
private
|
109
150
|
|
110
151
|
# if url has been changed by manually or url is empty
|
@@ -112,34 +153,36 @@ module ConstructorPages
|
|
112
153
|
self.url = ((auto_url || url.empty?) ? translit(name) : url).parameterize
|
113
154
|
end
|
114
155
|
|
156
|
+
# TODO: move out
|
115
157
|
def parse_date(value)
|
116
158
|
Date.new(value['date(1i)'].to_i, value['date(2i)'].to_i, value['date(3i)'].to_i)
|
117
159
|
end
|
118
160
|
|
119
161
|
# TODO: add more languages
|
120
|
-
#
|
162
|
+
# Translit to english
|
121
163
|
def translit(str)
|
122
164
|
Russian.translit(str)
|
123
165
|
end
|
124
166
|
|
125
|
-
#
|
167
|
+
# Page is not valid if there is no template
|
126
168
|
def template_check
|
127
169
|
errors.add_on_empty(:template_id) if Template.count == 0
|
128
170
|
end
|
129
171
|
|
130
|
-
#
|
172
|
+
# If template_id is nil then get first template
|
131
173
|
def template_assign
|
132
174
|
self.template_id = Template.first.id unless template_id
|
133
175
|
end
|
134
176
|
|
177
|
+
# Update full_url
|
135
178
|
def full_url_update
|
136
|
-
self.full_url =
|
179
|
+
self.full_url = (parent_id ? Page.full_url_generate(parent_id, url) : '/' + url)
|
137
180
|
end
|
138
181
|
|
182
|
+
# Reload all descendants
|
139
183
|
def descendants_update; descendants.map(&:save) end
|
140
184
|
|
141
|
-
|
142
|
-
|
143
|
-
end
|
185
|
+
# Create fields values
|
186
|
+
def create_fields; fields.each {|field| field.create_type_object(self) } end
|
144
187
|
end
|
145
188
|
end
|
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
module ConstructorPages
|
4
4
|
class Template < ActiveRecord::Base
|
5
|
+
include CodeNameUniq
|
6
|
+
|
5
7
|
attr_accessible :name, :code_name, :child_id, :parent_id, :parent
|
6
8
|
|
7
9
|
validates_presence_of :name, :code_name
|
8
10
|
validates_uniqueness_of :code_name
|
9
|
-
|
10
|
-
validate :method_uniqueness
|
11
|
+
validate :code_name_uniqueness
|
11
12
|
|
12
13
|
default_scope order(:lft)
|
13
14
|
|
@@ -27,15 +28,14 @@ module ConstructorPages
|
|
27
28
|
|
28
29
|
private
|
29
30
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
or root.descendants.map{|t| t.code_name unless t.code_name == code_name}.include?(code_name.singularize) \
|
36
|
-
|
37
|
-
errors.add(:base, "Такой метод уже используется")
|
31
|
+
def check_code_name(code_name)
|
32
|
+
[code_name.pluralize, code_name.singularize].each do |name|
|
33
|
+
if root.descendants.map{|t| t.code_name unless t.code_name == code_name}.include?(name)
|
34
|
+
return false
|
35
|
+
end
|
38
36
|
end
|
37
|
+
|
38
|
+
true
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
data/config/locales/en.yml
CHANGED
@@ -11,6 +11,7 @@ en:
|
|
11
11
|
|
12
12
|
new_field: 'New field'
|
13
13
|
|
14
|
+
code_name_already_in_use: 'This code name is already in use.'
|
14
15
|
field_success_added: 'Field «%{name}» added successfully.'
|
15
16
|
field_success_updated: 'Field «%{name}» updated successfully.'
|
16
17
|
field_success_removed: 'Field «%{name}» removed successfully.'
|
data/config/locales/ru.yml
CHANGED
@@ -18,7 +18,7 @@ ru:
|
|
18
18
|
delete_template: 'Удалить шаблон'
|
19
19
|
|
20
20
|
new_field: 'Добавить поле'
|
21
|
-
|
21
|
+
code_name_already_in_use: 'Такое имя уже используется.'
|
22
22
|
field_success_added: 'Поле «%{name}» успешно добавлено.'
|
23
23
|
field_success_updated: 'Поле «%{name}» успешно обновлено.'
|
24
24
|
field_success_removed: 'Поле «%{name}» успешно удалено.'
|
@@ -3,4 +3,26 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
module ConstructorPages
|
6
|
+
describe Field do
|
7
|
+
before :each do
|
8
|
+
Template.delete_all
|
9
|
+
@template = Template.create name: 'Page', code_name: 'page'
|
10
|
+
|
11
|
+
Field.delete_all
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.create' do
|
15
|
+
it 'should be valid' do
|
16
|
+
_field = Field.create name: 'Content', code_name: 'content', template: @template, type_value: 'text'
|
17
|
+
_field.valid?.should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should validate uniqueness' do
|
21
|
+
Field.create name: 'Content', code_name: 'content', template: @template, type_value: 'text'
|
22
|
+
_field = Field.create name: 'Content', code_name: 'content', template: @template, type_value: 'text'
|
23
|
+
|
24
|
+
_field.valid?.should_not be_true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
6
28
|
end
|
@@ -6,277 +6,305 @@ module ConstructorPages
|
|
6
6
|
describe Page do
|
7
7
|
before :each do
|
8
8
|
Template.delete_all
|
9
|
-
Template.create name: 'Page', code_name: 'page'
|
9
|
+
@template = Template.create name: 'Page', code_name: 'page'
|
10
10
|
|
11
11
|
Page.delete_all
|
12
12
|
Field.delete_all
|
13
13
|
Types::TextType.delete_all
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
context 'CLASS METHODS' do
|
17
|
+
describe '.create' do
|
18
|
+
it 'should be valid' do
|
19
|
+
Page.create.valid?.should be_true
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
22
|
+
it 'should create type_fields after' do
|
23
|
+
field = Field.create name: 'Content', code_name: 'content', template: @template, type_value: 'text'
|
24
|
+
page = Page.create name: 'New page', template: @template
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
field.get_value_for(page).should == ''
|
27
|
+
end
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
describe '.find_by_request_or_first' do
|
31
|
+
before :each do
|
32
|
+
@page = Page.create name: 'New page', url: 'new-page'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should return page by given request path' do
|
36
|
+
Page.find_by_request_or_first('/new-page').should == @page
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should return first page if no given request' do
|
40
|
+
Page.find_by_request_or_first.should == @page
|
41
|
+
end
|
31
42
|
end
|
32
|
-
end
|
33
43
|
|
34
|
-
|
35
|
-
|
44
|
+
describe '.full_url_generate' do
|
45
|
+
it 'should generate full_url from parent_id and url' do
|
46
|
+
first_page = Page.create name: 'First page', url: 'first-page'
|
47
|
+
second_page = Page.create name: 'Second page', url: 'second-page', parent: first_page
|
48
|
+
Page.full_url_generate(second_page.id, 'third-page').should == '/first-page/second-page/third-page'
|
49
|
+
end
|
36
50
|
end
|
37
51
|
end
|
38
52
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
53
|
+
context 'INSTANCE METHODS' do
|
54
|
+
context 'Getting and setting field value' do
|
55
|
+
before :each do
|
56
|
+
@template = Template.create name: 'Page template', code_name: 'page_template'
|
57
|
+
@page = Page.create name: 'Home page', template: @template
|
58
|
+
@field = Field.create name: 'Desc', code_name: 'desc', template: @template, type_value: 'text'
|
59
|
+
end
|
44
60
|
|
45
|
-
|
61
|
+
describe '#get_field' do
|
62
|
+
it 'should get value from type_field' do
|
63
|
+
@field.set_value_for(@page, 'Hello world')
|
64
|
+
@page.get_field_value('desc').should == 'Hello world'
|
65
|
+
end
|
66
|
+
end
|
46
67
|
|
47
|
-
|
68
|
+
describe '#set_field' do
|
69
|
+
it 'should set value for type_field' do
|
70
|
+
@page.set_field_value('desc', 'my world')
|
71
|
+
@field.get_value_for(@page).should == 'my world'
|
72
|
+
end
|
73
|
+
end
|
48
74
|
end
|
49
|
-
end
|
50
75
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
76
|
+
context 'Updating and removing fields values' do
|
77
|
+
before :each do
|
78
|
+
@template = Template.create name: 'New template', code_name: 'brand'
|
79
|
+
@field = Field.create name: 'Price', code_name: 'price', template: @template, type_value: 'float'
|
80
|
+
@page = Page.create name: 'New page', template: @template
|
81
|
+
@page.price = 500
|
82
|
+
end
|
56
83
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
84
|
+
describe '#update_fields_values' do
|
85
|
+
it 'should update fields values with params' do
|
86
|
+
Field.create name: 'Count', code_name: 'count', template: @template, type_value: 'integer'
|
87
|
+
@page.reload
|
61
88
|
|
62
|
-
|
63
|
-
it 'should find page in one branch template by code_name' do
|
64
|
-
brand_template = Template.create name: 'Brand', code_name: 'brand'
|
65
|
-
series_template = Template.create name: 'Series', code_name: 'series', parent: brand_template
|
89
|
+
@page.count = 10
|
66
90
|
|
67
|
-
|
68
|
-
series_page = Page.create name: 'Fresco', template: series_template, parent: brand_page
|
91
|
+
@page.update_fields_values({price: 1000, count: 20})
|
69
92
|
|
70
|
-
|
71
|
-
|
72
|
-
|
93
|
+
@page.price.should == 1000
|
94
|
+
@page.count.should == 20
|
95
|
+
end
|
73
96
|
|
74
|
-
|
75
|
-
|
76
|
-
template = Template.create name: 'JSON', code_name: 'json_template'
|
77
|
-
page = Page.create name: 'Hi json', template: template
|
78
|
-
Field.create name: 'Content', code_name: 'content', template: template, type_value: 'text'
|
79
|
-
page.content = 'Hello world'
|
80
|
-
page.as_json.should == {content: 'Hello world', name: page.name, title: page.title}
|
81
|
-
end
|
82
|
-
end
|
97
|
+
it 'should reset boolean fields' do
|
98
|
+
Field.create name: 'Check', code_name: 'check', template: @template, type_value: 'boolean'
|
83
99
|
|
84
|
-
|
85
|
-
it 'should check if link specified or not' do
|
86
|
-
page = Page.create name: 'Test redirection'
|
87
|
-
page.redirect?.should be_false
|
100
|
+
@page.check = true
|
88
101
|
|
89
|
-
|
90
|
-
page.save
|
102
|
+
@page.update_fields_values({price: 1000})
|
91
103
|
|
92
|
-
|
104
|
+
@page.price.should == 1000
|
105
|
+
@page.check.should be_false
|
106
|
+
end
|
107
|
+
end
|
93
108
|
|
94
|
-
|
95
|
-
|
109
|
+
describe '#remove_fields_values' do
|
110
|
+
it 'should destroy all type_values fields' do
|
111
|
+
@field.find_type_object(@page).value.should == 500
|
96
112
|
|
97
|
-
|
113
|
+
@page.remove_fields_values
|
114
|
+
@field.find_type_object(@page).should be_nil
|
115
|
+
end
|
116
|
+
end
|
98
117
|
end
|
99
|
-
end
|
100
118
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|
119
|
+
describe '#find_page_in_branch' do
|
120
|
+
it 'should find page(s) in same branch pages and templates by template_code_name' do
|
121
|
+
brand_template = Template.create name: 'Brand', code_name: 'brand'
|
122
|
+
series_template = Template.create name: 'Series', code_name: 'series', parent: brand_template
|
107
123
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
Template.delete_all
|
112
|
-
page = Page.create
|
113
|
-
page.valid?.should_not be_true
|
114
|
-
Template.create name: 'Page', code_name: 'page'
|
115
|
-
end
|
116
|
-
end
|
124
|
+
brand_page = Page.create name: 'Zanussi', template: brand_template
|
125
|
+
series_page = Page.create name: 'Fresco', template: series_template, parent: brand_page
|
126
|
+
brand_page.reload
|
117
127
|
|
118
|
-
|
119
|
-
|
120
|
-
page = Page.create
|
121
|
-
page.template.should == Template.first
|
128
|
+
series_page.find_page_in_branch('brand').should == brand_page
|
129
|
+
brand_page.find_pages_in_branch('series').should == [series_page]
|
122
130
|
end
|
123
131
|
end
|
124
|
-
end
|
125
132
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
133
|
+
describe '#as_json' do
|
134
|
+
context 'should return page hash attributes with fields' do
|
135
|
+
before :each do
|
136
|
+
@template = Template.create name: 'Json', code_name: 'json_template'
|
137
|
+
@page = Page.create name: 'Test json', template: @template
|
138
|
+
end
|
133
139
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
page.url.should == 'hello'
|
140
|
+
it 'should return defaults name and title attrs' do
|
141
|
+
@page.as_json.should == {name: @page.name, title: @page.title}
|
142
|
+
end
|
138
143
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
144
|
+
it 'should add fields to hash' do
|
145
|
+
Field.create name: 'Content', code_name: 'content', template: @template, type_value: 'text'
|
146
|
+
@page.content = 'Hello world'
|
147
|
+
@page.reload
|
143
148
|
|
144
|
-
|
145
|
-
|
146
|
-
page.url = 'world-two'
|
147
|
-
page.save
|
148
|
-
page.url.should == 'another-world'
|
149
|
+
@page.as_json.should == {name: @page.name, title: @page.title, content: 'Hello world'}
|
150
|
+
end
|
149
151
|
end
|
150
152
|
end
|
151
|
-
end
|
152
153
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Field.create name: 'Check', code_name: 'check', template: template, type_value: 'boolean'
|
154
|
+
describe '#redirect?' do
|
155
|
+
it 'should check if link specified or not' do
|
156
|
+
page = Page.create name: 'Test redirection'
|
157
|
+
page.redirect?.should be_false
|
158
158
|
|
159
|
-
|
159
|
+
page.link = ''
|
160
|
+
page.save
|
160
161
|
|
161
|
-
|
162
|
-
page.check.should be_true
|
162
|
+
page.redirect?.should be_false
|
163
163
|
|
164
|
-
|
164
|
+
page.link = '/hello-redirect'
|
165
|
+
page.save
|
165
166
|
|
166
|
-
|
167
|
-
|
167
|
+
page.redirect?.should be_true
|
168
|
+
end
|
168
169
|
end
|
169
170
|
end
|
170
171
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
page.price = 500
|
178
|
-
field.find_type_object(page).value.should == 500
|
179
|
-
|
180
|
-
page.remove_fields_values
|
181
|
-
field.find_type_object(page).should be_nil
|
172
|
+
context 'ATTRIBUTES' do
|
173
|
+
describe '#auto_url' do
|
174
|
+
it 'should be true by default' do
|
175
|
+
page = Page.create
|
176
|
+
page.auto_url.should be_true
|
177
|
+
end
|
182
178
|
end
|
183
|
-
end
|
184
179
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
180
|
+
describe '#template' do
|
181
|
+
context 'if there is no template' do
|
182
|
+
it 'should not be valid' do
|
183
|
+
Template.delete_all
|
189
184
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
context 'if parent or url has been changed' do
|
195
|
-
it 'should update full_url' do
|
196
|
-
page = Page.create name: 'Change url', url: 'change-url', auto_url: false
|
197
|
-
page.full_url.should == '/change-url'
|
185
|
+
page = Page.create
|
186
|
+
page.valid?.should_not be_true
|
187
|
+
end
|
188
|
+
end
|
198
189
|
|
199
|
-
|
200
|
-
|
201
|
-
|
190
|
+
context 'if template_id is nil' do
|
191
|
+
it 'should be first template' do
|
192
|
+
page = Page.create
|
193
|
+
page.template.should == Template.first
|
194
|
+
end
|
202
195
|
end
|
203
196
|
end
|
204
197
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
198
|
+
describe '#url' do
|
199
|
+
context 'if url is empty or if auto_url is true' do
|
200
|
+
it 'should be generated from name' do
|
201
|
+
page = Page.create name: 'Hello world'
|
202
|
+
page.url.should == 'hello-world'
|
203
|
+
end
|
209
204
|
|
210
|
-
|
211
|
-
|
212
|
-
|
205
|
+
it 'should translit utf-8' do
|
206
|
+
page = Page.create name: 'Проверка'
|
207
|
+
page.full_url.should == '/proverka'
|
213
208
|
|
214
|
-
|
209
|
+
page_two = Page.create name: 'Тест', parent: page
|
210
|
+
page_two.full_url.should == '/proverka/test'
|
211
|
+
end
|
212
|
+
end
|
215
213
|
|
216
|
-
|
217
|
-
|
218
|
-
|
214
|
+
context 'else' do
|
215
|
+
it 'should get url field value' do
|
216
|
+
page = Page.create name: 'Hello', auto_url: true
|
217
|
+
page.url.should == 'hello'
|
218
|
+
|
219
|
+
page.auto_url = false
|
220
|
+
page.url = 'world'
|
221
|
+
page.save
|
222
|
+
page.url.should == 'world'
|
223
|
+
|
224
|
+
page.auto_url = true
|
225
|
+
page.name = 'Another world'
|
226
|
+
page.url = 'world-two'
|
227
|
+
page.save
|
228
|
+
page.url.should == 'another-world'
|
229
|
+
end
|
219
230
|
end
|
220
231
|
end
|
221
|
-
end
|
222
232
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
233
|
+
describe '#full_url' do
|
234
|
+
it 'should be generated from url and ancestors' do
|
235
|
+
page = Page.create name: 'Hello'
|
236
|
+
page.full_url.should == '/hello'
|
227
237
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
end
|
238
|
+
page_two = Page.create name: 'World', parent: page
|
239
|
+
page_two.full_url.should == '/hello/world'
|
240
|
+
end
|
232
241
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
242
|
+
context 'if parent or url has been changed' do
|
243
|
+
it 'should update full_url' do
|
244
|
+
page = Page.create name: 'Change url', url: 'change-url', auto_url: false
|
245
|
+
child_page = Page.create name: 'Child page', url: 'child', auto_url: false, parent: page
|
246
|
+
page.reload
|
238
247
|
|
239
|
-
|
240
|
-
|
241
|
-
page.save
|
248
|
+
page.full_url.should == '/change-url'
|
249
|
+
child_page.full_url.should == '/change-url/child'
|
242
250
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
end
|
251
|
+
page.url = 'another-change-url'
|
252
|
+
page.save
|
253
|
+
page.full_url.should == '/another-change-url'
|
247
254
|
|
248
|
-
|
249
|
-
|
250
|
-
|
255
|
+
child_page.reload
|
256
|
+
child_page.full_url.should == '/another-change-url/child'
|
257
|
+
end
|
258
|
+
end
|
251
259
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
field = Field.create name: 'Content', code_name: 'desc', template: template, type_value: 'text'
|
257
|
-
field.set_value_for(page, 'my world')
|
260
|
+
context 'if parent is root or nil' do
|
261
|
+
it 'should be as /self.url' do
|
262
|
+
page = Page.create name: 'Page', url: 'page', auto_url: false, parent_id: nil
|
263
|
+
page.full_url.should == '/page'
|
258
264
|
|
259
|
-
|
260
|
-
|
265
|
+
parent = Page.create name: 'Parent'
|
266
|
+
page.parent = parent
|
267
|
+
page.save
|
261
268
|
|
262
|
-
|
263
|
-
template = Template.create name: 'Page', code_name: 'page_templ'
|
264
|
-
page = Page.create name: 'No method', template: template
|
265
|
-
field = Field.create name: 'Content', code_name: 'desc', template: template, type_value: 'text'
|
269
|
+
page.full_url.should == '/parent/page'
|
266
270
|
|
267
|
-
|
268
|
-
|
271
|
+
page.parent = nil
|
272
|
+
page.save
|
273
|
+
page.full_url.should == '/page'
|
274
|
+
end
|
275
|
+
end
|
269
276
|
end
|
270
277
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
278
|
+
describe 'method_missing' do
|
279
|
+
context 'Getting and setting field value' do
|
280
|
+
before :each do
|
281
|
+
@template = Template.create name: 'Page', code_name: 'page_template'
|
282
|
+
@page = Page.create name: 'No method', template: @template
|
283
|
+
@field = Field.create name: 'Content', code_name: 'desc', template: @template, type_value: 'text'
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'should return value of type_value for missing method' do
|
287
|
+
@field.set_value_for(@page, 'my world')
|
288
|
+
@page.desc.should == 'my world'
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should set value for type_value for missing method' do
|
292
|
+
@page.desc = 'my world 2'
|
293
|
+
@field.get_value_for(@page).should == 'my world 2'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'should find page in branch template if no field found' do
|
298
|
+
brand_template = Template.create name: 'Brand', code_name: 'brand'
|
299
|
+
series_template = Template.create name: 'Series', code_name: 'series', parent: brand_template
|
275
300
|
|
276
|
-
|
277
|
-
|
301
|
+
brand_page = Page.create name: 'Zanussi', template: brand_template
|
302
|
+
series_page = Page.create name: 'Fresco', template: series_template, parent: brand_page
|
303
|
+
brand_page.reload
|
278
304
|
|
279
|
-
|
305
|
+
series_page.brand.should == brand_page
|
306
|
+
brand_page.series.should == [series_page]
|
307
|
+
end
|
280
308
|
end
|
281
309
|
end
|
282
310
|
end
|
@@ -8,15 +8,5 @@ module ConstructorPages
|
|
8
8
|
template = Template.create name: 'Page template', code_name: 'page_template'
|
9
9
|
template.valid?.should be_true
|
10
10
|
end
|
11
|
-
|
12
|
-
describe '#name' do
|
13
|
-
it 'should convert russian suffix'
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#code_name' do
|
17
|
-
context 'validation' do
|
18
|
-
it 'should be uniqueness'
|
19
|
-
end
|
20
|
-
end
|
21
11
|
end
|
22
12
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: constructor-pages
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
5
|
-
prerelease:
|
4
|
+
version: 0.5.7
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Ivan Zotov
|
@@ -14,55 +13,48 @@ dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: constructor-core
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - '='
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.5.
|
19
|
+
version: 0.5.7
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - '='
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.5.
|
26
|
+
version: 0.5.7
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: dragonfly
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rack-cache
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: awesome_nested_set
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,65 +69,57 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: haml-rails
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: acts_as_list
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :runtime
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rspec-rails
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: capybara
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- -
|
115
|
+
- - '>='
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: '0'
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- -
|
122
|
+
- - '>='
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0'
|
142
125
|
description: Pages for Constructor CMS
|
@@ -155,6 +138,7 @@ files:
|
|
155
138
|
- app/controllers/constructor_pages/fields_controller.rb
|
156
139
|
- app/controllers/constructor_pages/pages_controller.rb
|
157
140
|
- app/controllers/constructor_pages/templates_controller.rb
|
141
|
+
- app/helpers/constructor_pages/code_name_uniq.rb
|
158
142
|
- app/helpers/constructor_pages/fields_helper.rb
|
159
143
|
- app/helpers/constructor_pages/move_helper.rb
|
160
144
|
- app/helpers/constructor_pages/pages_helper.rb
|
@@ -217,33 +201,33 @@ files:
|
|
217
201
|
- spec/models/constructor_pages/field_model_spec.rb
|
218
202
|
- spec/models/constructor_pages/page_model_spec.rb
|
219
203
|
- spec/models/constructor_pages/template_model_spec.rb
|
204
|
+
- spec/requests/constructor_pages/pages_controller_spec.rb
|
220
205
|
homepage: http://ivanzotov.github.com/constructor
|
221
206
|
licenses: []
|
207
|
+
metadata: {}
|
222
208
|
post_install_message:
|
223
209
|
rdoc_options: []
|
224
210
|
require_paths:
|
225
211
|
- lib
|
226
212
|
required_ruby_version: !ruby/object:Gem::Requirement
|
227
|
-
none: false
|
228
213
|
requirements:
|
229
|
-
- -
|
214
|
+
- - '>='
|
230
215
|
- !ruby/object:Gem::Version
|
231
216
|
version: '0'
|
232
217
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
|
-
none: false
|
234
218
|
requirements:
|
235
|
-
- -
|
219
|
+
- - '>='
|
236
220
|
- !ruby/object:Gem::Version
|
237
221
|
version: '0'
|
238
222
|
requirements: []
|
239
223
|
rubyforge_project:
|
240
|
-
rubygems_version:
|
224
|
+
rubygems_version: 2.0.3
|
241
225
|
signing_key:
|
242
|
-
specification_version:
|
226
|
+
specification_version: 4
|
243
227
|
summary: Pages for Constructor CMS
|
244
228
|
test_files:
|
245
229
|
- spec/features/constructor_pages/pages_controller_spec.rb
|
246
230
|
- spec/models/constructor_pages/field_model_spec.rb
|
247
231
|
- spec/models/constructor_pages/page_model_spec.rb
|
248
232
|
- spec/models/constructor_pages/template_model_spec.rb
|
249
|
-
|
233
|
+
- spec/requests/constructor_pages/pages_controller_spec.rb
|