locomotive_cms 0.0.1.4 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/app/controllers/admin/api_contents_controller.rb +30 -0
- data/app/controllers/admin/base_controller.rb +2 -2
- data/app/controllers/admin/content_types_controller.rb +1 -1
- data/app/controllers/admin/custom_fields_controller.rb +33 -0
- data/app/controllers/admin/my_accounts_controller.rb +2 -2
- data/app/controllers/admin/sites_controller.rb +2 -2
- data/app/helpers/admin/accounts_helper.rb +1 -1
- data/app/helpers/admin/custom_fields_helper.rb +1 -1
- data/app/models/asset.rb +2 -1
- data/app/models/asset_collection.rb +2 -2
- data/app/models/content_instance.rb +7 -0
- data/app/models/content_type.rb +1 -0
- data/app/models/page_part.rb +4 -4
- data/app/models/site.rb +1 -1
- data/app/models/theme_asset.rb +2 -0
- data/app/uploaders/asset_uploader.rb +2 -2
- data/app/views/admin/asset_collections/edit.html.haml +6 -3
- data/app/views/admin/content_types/_form.html.haml +10 -5
- data/app/views/admin/content_types/edit.html.haml +3 -1
- data/app/views/admin/content_types/new.html.haml +2 -0
- data/app/views/admin/contents/_form.html.haml +12 -2
- data/app/views/admin/current_sites/_form.html.haml +1 -1
- data/app/views/admin/custom_fields/_edit_field.html.haml +9 -0
- data/app/views/admin/{shared/_custom_fields.html.haml → custom_fields/_index.html.haml} +14 -4
- data/app/views/admin/custom_fields/edit_category.html.haml +43 -0
- data/app/views/admin/pages/_form.html.haml +1 -1
- data/app/views/admin/passwords/edit.html.haml +2 -2
- data/app/views/admin/passwords/new.html.haml +2 -2
- data/app/views/admin/sessions/new.html.haml +1 -1
- data/app/views/admin/shared/_head.html.haml +1 -1
- data/app/views/admin/shared/_header.html.haml +2 -2
- data/app/views/admin/sites/_form.html.haml +1 -1
- data/app/views/admin/theme_assets/images.html.haml +7 -7
- data/app/views/devise/mailer/reset_password_instructions.html.haml +1 -1
- data/config/application.rb +4 -3
- data/config/boot.rb +3 -14
- data/config/initializers/locomotive.rb +1 -0
- data/config/initializers/mongoid.rb +11 -12
- data/config/initializers/secret_token.rb +7 -0
- data/config/locales/admin_ui_en.yml +113 -4
- data/config/routes.rb +6 -8
- data/lib/locomotive/configuration.rb +2 -1
- data/lib/locomotive/liquid/drops/contents.rb +11 -13
- data/lib/locomotive/liquid/drops/javascripts.rb +1 -1
- data/lib/locomotive/liquid/tags/paginate.rb +1 -1
- data/lib/locomotive/render.rb +1 -1
- data/lib/locomotive/routing/site_dispatcher.rb +2 -1
- data/lib/locomotive.rb +3 -1
- data/lib/misc_form_builder.rb +10 -0
- data/public/images/admin/form/big_item-popup.png +0 -0
- data/public/images/admin/form/footer-popup.png +0 -0
- data/public/images/admin/form/header-popup.png +0 -0
- data/public/images/admin/form/icons/edit.png +0 -0
- data/public/images/admin/form/item-popup.png +0 -0
- data/public/images/admin/list/none-small.png +0 -0
- data/public/javascripts/admin/application.js +3 -2
- data/public/javascripts/admin/content_types.js +1 -1
- data/public/javascripts/admin/contents.js +11 -1
- data/public/javascripts/admin/custom_fields/category.js +91 -0
- data/public/javascripts/admin/custom_fields.js +27 -0
- data/public/javascripts/admin/page_parts.js +10 -5
- data/public/javascripts/admin/pages.js +1 -1
- data/public/javascripts/admin/snippets.js +1 -1
- data/public/javascripts/admin/theme_assets.js +2 -0
- data/public/javascripts/admin/utils.js +9 -0
- data/public/javascripts/all.js +14 -2
- data/public/stylesheets/admin/application.css +2 -2
- data/public/stylesheets/admin/box.css +80 -4
- data/public/stylesheets/admin/formtastic_changes.css +7 -2
- data/public/stylesheets/all.css +6 -1
- data/spec/lib/locomotive/render_spec.rb +2 -2
- data/spec/models/asset_collections_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -1
- data/spec/support/locomotive.rb +1 -1
- data/vendor/plugins/custom_fields/Gemfile +11 -0
- data/vendor/plugins/custom_fields/README +2 -2
- data/vendor/plugins/custom_fields/Rakefile +23 -17
- data/vendor/plugins/custom_fields/lib/custom_fields/custom_fields_for.rb +2 -1
- data/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/embeds_many.rb +20 -13
- data/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/has_many_related.rb +33 -0
- data/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/associations/proxy.rb +20 -0
- data/vendor/plugins/custom_fields/lib/custom_fields/extensions/mongoid/document.rb +14 -21
- data/vendor/plugins/custom_fields/lib/custom_fields/{custom_field.rb → field.rb} +25 -23
- data/vendor/plugins/custom_fields/lib/custom_fields/proxy_class_enabler.rb +37 -0
- data/vendor/plugins/custom_fields/lib/custom_fields/types/category.rb +73 -0
- data/vendor/plugins/custom_fields/lib/custom_fields/types/default.rb +18 -0
- data/vendor/plugins/custom_fields/lib/custom_fields.rb +9 -1
- data/vendor/plugins/custom_fields/spec/integration/custom_fields_for_spec.rb +28 -0
- data/vendor/plugins/custom_fields/spec/integration/types/category_spec.rb +26 -0
- data/vendor/plugins/custom_fields/spec/models/person.rb +10 -0
- data/vendor/plugins/custom_fields/spec/models/project.rb +16 -0
- data/vendor/plugins/custom_fields/spec/models/task.rb +10 -0
- data/vendor/plugins/custom_fields/spec/spec_helper.rb +31 -0
- data/vendor/plugins/custom_fields/spec/unit/custom_field_spec.rb +42 -0
- data/vendor/plugins/custom_fields/spec/unit/custom_fields_for_spec.rb +106 -0
- data/vendor/plugins/custom_fields/spec/unit/proxy_class_enabler_spec.rb +25 -0
- data/vendor/plugins/custom_fields/spec/unit/types/category_spec.rb +97 -0
- metadata +83 -35
- data/app/views/devise/confirmations/new.html.haml +0 -12
- data/app/views/devise/registrations/edit.html.haml +0 -35
- data/app/views/devise/registrations/new.html.haml +0 -20
- data/app/views/devise/sessions/new.html.haml +0 -22
- data/app/views/devise/shared/_links.haml +0 -20
- data/app/views/devise/unlocks/new.html.haml +0 -12
- data/vendor/plugins/custom_fields/install.rb +0 -1
@@ -0,0 +1,37 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module ProxyClassEnabler
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
cattr_accessor :klass_with_custom_fields
|
9
|
+
|
10
|
+
def self.to_klass_with_custom_fields(fields)
|
11
|
+
return klass_with_custom_fields unless klass_with_custom_fields.nil?
|
12
|
+
|
13
|
+
klass = Class.new(self)
|
14
|
+
klass.class_eval <<-EOF
|
15
|
+
cattr_accessor :custom_fields, :_parent, :association_name
|
16
|
+
|
17
|
+
def self.model_name
|
18
|
+
@_model_name ||= ActiveModel::Name.new(self.superclass)
|
19
|
+
end
|
20
|
+
|
21
|
+
def custom_fields
|
22
|
+
self.class.custom_fields
|
23
|
+
end
|
24
|
+
EOF
|
25
|
+
|
26
|
+
klass.hereditary = false
|
27
|
+
klass.custom_fields = fields
|
28
|
+
|
29
|
+
[*fields].each { |field| field.apply(klass) }
|
30
|
+
|
31
|
+
klass_with_custom_fields = klass
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Category
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
embeds_many :category_items, :class_name => 'CustomFields::Types::Category::Item'
|
9
|
+
|
10
|
+
validates_associated :category_items
|
11
|
+
|
12
|
+
accepts_nested_attributes_for :category_items, :allow_destroy => true
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
|
17
|
+
def ordered_category_items
|
18
|
+
self.category_items.sort { |a, b| (a.position || 0) <=> (b.position || 0) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def apply_category_type(klass)
|
22
|
+
klass.cattr_accessor :"#{self.safe_alias}_items"
|
23
|
+
|
24
|
+
klass.send("#{self.safe_alias}_items=", self.ordered_category_items)
|
25
|
+
|
26
|
+
klass.class_eval <<-EOF
|
27
|
+
def self.#{self.safe_alias}_names
|
28
|
+
self.#{self.safe_alias}_items.collect(&:name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.group_by_#{self.safe_alias}
|
32
|
+
groups = (if self.embedded?
|
33
|
+
self._parent.send(self.association_name).all
|
34
|
+
else
|
35
|
+
self.all
|
36
|
+
end).to_a.group_by(&:#{self._name})
|
37
|
+
|
38
|
+
self.#{self.safe_alias}_items.collect do |category|
|
39
|
+
{
|
40
|
+
:name => category.name,
|
41
|
+
:items => groups[category._id] || []
|
42
|
+
}.with_indifferent_access
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def #{self.safe_alias}=(name)
|
47
|
+
category_id = self.class.#{self.safe_alias}_items.find { |item| item.name == name }._id rescue name
|
48
|
+
write_attribute(:#{self._name}, category_id)
|
49
|
+
end
|
50
|
+
|
51
|
+
def #{self.safe_alias}
|
52
|
+
category_id = read_attribute(:#{self._name})
|
53
|
+
self.class.#{self.safe_alias}_items.find { |item| item._id == category_id }.name rescue category_id
|
54
|
+
end
|
55
|
+
EOF
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
class Item
|
61
|
+
|
62
|
+
include Mongoid::Document
|
63
|
+
|
64
|
+
field :name
|
65
|
+
field :position, :type => Integer, :default => 0
|
66
|
+
|
67
|
+
embedded_in :custom_field, :inverse_of => :category_items
|
68
|
+
|
69
|
+
validates_presence_of :name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Default
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module InstanceMethods
|
7
|
+
|
8
|
+
def apply_default_type(klass)
|
9
|
+
klass.class_eval <<-EOF
|
10
|
+
alias :#{self.safe_alias} :#{self._name}
|
11
|
+
alias :#{self.safe_alias}= :#{self._name}=
|
12
|
+
EOF
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
$:.unshift File.expand_path(File.dirname(__FILE__))
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'active_support'
|
4
|
+
|
4
5
|
require 'custom_fields/extensions/mongoid/document'
|
6
|
+
require 'custom_fields/extensions/mongoid/associations/proxy'
|
7
|
+
require 'custom_fields/extensions/mongoid/associations/has_many_related'
|
8
|
+
require 'custom_fields/extensions/mongoid/associations/embeds_many'
|
9
|
+
require 'custom_fields/types/default'
|
10
|
+
require 'custom_fields/types/category'
|
11
|
+
require 'custom_fields/proxy_class_enabler'
|
12
|
+
require 'custom_fields/field'
|
5
13
|
require 'custom_fields/custom_fields_for'
|
6
14
|
|
7
15
|
module Mongoid
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::CustomFieldsFor do
|
4
|
+
|
5
|
+
describe 'Saving' do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@project = Project.new(:name => 'Locomotive')
|
9
|
+
@project.person_custom_fields.build(:label => 'E-mail', :_alias => 'email', :kind => 'String')
|
10
|
+
@project.person_custom_fields.build(:label => 'Age', :_alias => 'age', :kind => 'String')
|
11
|
+
end
|
12
|
+
|
13
|
+
context '@create' do
|
14
|
+
|
15
|
+
it 'persists parent object' do
|
16
|
+
lambda { @project.save }.should change(Project, :count).by(1)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'persists custom fields' do
|
20
|
+
@project.save && @project.reload
|
21
|
+
@project.person_custom_fields.count.should == 2
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::Types::Category do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@project = Project.new(:name => 'Locomotive')
|
7
|
+
@field = @project.task_custom_fields.build(:label => 'Main category', :_alias => 'main_category', :kind => 'Category')
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'saving category items' do
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@field.category_items.build :name => 'Development'
|
14
|
+
@field.category_items.build :name => 'Design'
|
15
|
+
@field.updated_at = Time.now
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'persists items' do
|
19
|
+
@field.save.should be_true
|
20
|
+
@project.reload
|
21
|
+
@project.task_custom_fields.first.category_items.size.should == 2
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Project
|
2
|
+
|
3
|
+
include Mongoid::Document
|
4
|
+
include CustomFields::ProxyClassEnabler
|
5
|
+
include CustomFields::CustomFieldsFor
|
6
|
+
|
7
|
+
field :name
|
8
|
+
field :description
|
9
|
+
|
10
|
+
has_many_related :people
|
11
|
+
embeds_many :tasks
|
12
|
+
|
13
|
+
custom_fields_for :people
|
14
|
+
custom_fields_for :tasks
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
3
|
+
|
4
|
+
MODELS = File.join(File.dirname(__FILE__), "models")
|
5
|
+
$LOAD_PATH.unshift(MODELS)
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'bundler'
|
9
|
+
Bundler.setup
|
10
|
+
Bundler.require
|
11
|
+
|
12
|
+
require 'mongoid'
|
13
|
+
require 'mocha'
|
14
|
+
require 'rspec'
|
15
|
+
require 'custom_fields'
|
16
|
+
|
17
|
+
Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require File.basename(file) }
|
18
|
+
|
19
|
+
Mongoid.configure do |config|
|
20
|
+
name = "custom_fields_test"
|
21
|
+
host = "localhost"
|
22
|
+
config.master = Mongo::Connection.new.db(name)
|
23
|
+
# config.master = Mongo::Connection.new('localhost', '27017', :logger => Logger.new($stdout)).db(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
Rspec.configure do |config|
|
27
|
+
config.mock_with :mocha
|
28
|
+
config.after :suite do
|
29
|
+
Mongoid.master.collections.each(&:drop)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::Field do
|
4
|
+
|
5
|
+
it 'is initialized' do
|
6
|
+
lambda { CustomFields::Field.new }.should_not raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#mongoid' do
|
10
|
+
|
11
|
+
before(:each) do
|
12
|
+
@field = CustomFields::Field.new(:label => 'manager', :_name => 'field_1', :kind => 'String', :_alias => 'manager')
|
13
|
+
@field.stubs(:valid?).returns(true)
|
14
|
+
@project = Project.to_klass_with_custom_fields(@field).new
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is added to the list of mongoid fields' do
|
18
|
+
@project.fields['field_1'].should_not be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'on target class' do
|
24
|
+
|
25
|
+
before(:each) do
|
26
|
+
@field = CustomFields::Field.new(:label => 'manager', :_name => 'field_1', :kind => 'String', :_alias => 'manager')
|
27
|
+
@field.stubs(:valid?).returns(true)
|
28
|
+
@project = Project.to_klass_with_custom_fields(@field).new
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has a new field' do
|
32
|
+
@project.respond_to?(:manager).should be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'sets / retrieves a value' do
|
36
|
+
@project.manager = 'Mickael Scott'
|
37
|
+
@project.manager.should == 'Mickael Scott'
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::CustomFieldsFor do
|
4
|
+
|
5
|
+
context '#proxy class' do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@project = Project.new
|
9
|
+
@klass = @project.tasks.klass
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns the proxy class in the association' do
|
13
|
+
@klass.should == @project.tasks.build.class
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has a link to the parent' do
|
17
|
+
@klass._parent.should == @project
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has the association name which references to' do
|
21
|
+
@klass.association_name.should == 'tasks'
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with embedded collection' do
|
27
|
+
|
28
|
+
context '#association' do
|
29
|
+
|
30
|
+
before(:each) do
|
31
|
+
@project = Project.new
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'has custom fields for embedded collection' do
|
35
|
+
@project.respond_to?(:task_custom_fields).should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
context '#building' do
|
41
|
+
|
42
|
+
before(:each) do
|
43
|
+
@project = Project.new
|
44
|
+
@project.task_custom_fields.build :label => 'Short summary', :_alias => 'summary', :kind => 'String'
|
45
|
+
@task = @project.tasks.build
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns a new document whose Class is different from the original one' do
|
49
|
+
@task.class.should_not == Task
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns a new document with custom field' do
|
53
|
+
@project.tasks.build
|
54
|
+
@project.tasks.build
|
55
|
+
@task.respond_to?(:summary).should be_true
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'sets/gets custom attributes' do
|
59
|
+
@task.summary = 'Lorem ipsum...'
|
60
|
+
@task.summary.should == 'Lorem ipsum...'
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with related collection' do
|
68
|
+
|
69
|
+
context '#association' do
|
70
|
+
|
71
|
+
before(:each) do
|
72
|
+
@project = Project.new
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'has custom fields for related collections' do
|
76
|
+
@project.respond_to?(:person_custom_fields).should be_true
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
context '#building' do
|
82
|
+
|
83
|
+
before(:each) do
|
84
|
+
@project = Project.new
|
85
|
+
@project.person_custom_fields.build :label => 'Position in the project', :_alias => 'position', :kind => 'String'
|
86
|
+
@person = @project.people.build
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'returns a new document whose Class is different from the original one' do
|
90
|
+
@person.class.should_not == Task
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'returns a new document with custom field' do
|
94
|
+
@person.respond_to?(:position).should be_true
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'sets/gets custom attributes' do
|
98
|
+
@person.position = 'Designer'
|
99
|
+
@person.position.should == 'Designer'
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::ProxyClassEnabler do
|
4
|
+
|
5
|
+
context '#proxy klass' do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@klass = Task.to_klass_with_custom_fields([])
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'does not be flagged as a inherited document' do
|
12
|
+
@klass.new.hereditary?.should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'has a list of custom fields' do
|
16
|
+
@klass.custom_fields.should == []
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has the exact same model name than its parent' do
|
20
|
+
@klass.model_name.should == 'Task'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomFields::Types::Category do
|
4
|
+
|
5
|
+
context 'on field class' do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@field = CustomFields::Field.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'has the category items field' do
|
12
|
+
@field.respond_to?(:category_items).should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'has the apply method used for the target object' do
|
16
|
+
@field.respond_to?(:apply_category_type).should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'on target class' do
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
@project = build_project_with_category
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has getter/setter' do
|
28
|
+
@project.respond_to?(:global_category).should be_true
|
29
|
+
@project.respond_to?(:global_category=).should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'has the values of this category' do
|
33
|
+
@project.class.global_category_names.should == %w{Maintenance Design Development}
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets the category from a name' do
|
37
|
+
@project.global_category = 'Design'
|
38
|
+
@project.global_category.should == 'Design'
|
39
|
+
@project.field_1.should == '42'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets the category even it does not exit' do
|
43
|
+
@project.global_category = 'Accounting'
|
44
|
+
@project.global_category.should == 'Accounting'
|
45
|
+
@project.field_1.should == 'Accounting'
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'group by category' do
|
49
|
+
|
50
|
+
before(:each) do
|
51
|
+
seed_projects
|
52
|
+
@groups = @project.class.group_by_global_category
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is an non empty array' do
|
56
|
+
@groups.class.should == Array
|
57
|
+
@groups.size.should == 3
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'is an array of hash composed of a name' do
|
61
|
+
@groups.collect { |g| g[:name] }.should == %w{Maintenance Design Development}
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is an array of hash composed of a list of objects' do
|
65
|
+
@groups[0][:items].size.should == 0
|
66
|
+
@groups[1][:items].size.should == 1
|
67
|
+
@groups[2][:items].size.should == 2
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_project_with_category
|
75
|
+
field = build_category
|
76
|
+
Project.to_klass_with_custom_fields(field).new
|
77
|
+
end
|
78
|
+
|
79
|
+
def build_category
|
80
|
+
field = CustomFields::Field.new(:label => 'global_category', :_name => 'field_1', :kind => 'Category')
|
81
|
+
field.stubs(:valid?).returns(true)
|
82
|
+
field.category_items.build :name => 'Development', :_id => '41', :position => 2
|
83
|
+
field.category_items.build :name => 'Design', :_id => '42', :position => 1
|
84
|
+
field.category_items.build :name => 'Maintenance', :_id => '43', :position => 0
|
85
|
+
field
|
86
|
+
end
|
87
|
+
|
88
|
+
def seed_projects
|
89
|
+
list = [
|
90
|
+
@project.class.new(:name => 'Locomotive CMS', :global_category => '41'),
|
91
|
+
@project.class.new(:name => 'Ruby on Rails', :global_category => '41'),
|
92
|
+
@project.class.new(:name => 'Dribble', :global_category => '42')
|
93
|
+
]
|
94
|
+
@project.class.stubs(:all).returns(list)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|