dead_simple_cms 0.9.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.
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +266 -0
- data/Rakefile +17 -0
- data/dead_simple_cms.gemspec +47 -0
- data/lib/dead_simple_cms.rb +132 -0
- data/lib/dead_simple_cms/attribute/collection.rb +45 -0
- data/lib/dead_simple_cms/attribute/type/all.rb +104 -0
- data/lib/dead_simple_cms/attribute/type/base.rb +79 -0
- data/lib/dead_simple_cms/attribute/type/collection_support.rb +26 -0
- data/lib/dead_simple_cms/configuration.rb +50 -0
- data/lib/dead_simple_cms/file_uploader/base.rb +29 -0
- data/lib/dead_simple_cms/group.rb +58 -0
- data/lib/dead_simple_cms/group/configuration.rb +32 -0
- data/lib/dead_simple_cms/group/presenter.rb +23 -0
- data/lib/dead_simple_cms/rails/action_controller/extensions.rb +24 -0
- data/lib/dead_simple_cms/rails/action_controller/fragment_sweeper.rb +19 -0
- data/lib/dead_simple_cms/rails/action_view/extensions.rb +14 -0
- data/lib/dead_simple_cms/rails/action_view/form_builders/default.rb +16 -0
- data/lib/dead_simple_cms/rails/action_view/form_builders/interface.rb +72 -0
- data/lib/dead_simple_cms/rails/action_view/form_builders/simple_form.rb +43 -0
- data/lib/dead_simple_cms/rails/action_view/form_builders/simple_form_with_bootstrap.rb +19 -0
- data/lib/dead_simple_cms/rails/action_view/presenter.rb +63 -0
- data/lib/dead_simple_cms/section.rb +103 -0
- data/lib/dead_simple_cms/section/builder.rb +73 -0
- data/lib/dead_simple_cms/storage/base.rb +49 -0
- data/lib/dead_simple_cms/storage/database.rb +33 -0
- data/lib/dead_simple_cms/storage/memory.rb +20 -0
- data/lib/dead_simple_cms/storage/rails_cache.rb +19 -0
- data/lib/dead_simple_cms/storage/redis.rb +23 -0
- data/lib/dead_simple_cms/util/identifier.rb +40 -0
- data/lib/dead_simple_cms/util/identifier/dictionary.rb +65 -0
- data/lib/dead_simple_cms/version.rb +3 -0
- data/spec/dead_simple_cms/attribute/collection_spec.rb +46 -0
- data/spec/dead_simple_cms/attribute/type/all_spec.rb +252 -0
- data/spec/dead_simple_cms/attribute/type/base_spec.rb +117 -0
- data/spec/dead_simple_cms/configuration_spec.rb +117 -0
- data/spec/dead_simple_cms/file_uploader/base_spec.rb +35 -0
- data/spec/dead_simple_cms/group/configuration_spec.rb +24 -0
- data/spec/dead_simple_cms/group/presenter_spec.rb +28 -0
- data/spec/dead_simple_cms/group_spec.rb +65 -0
- data/spec/dead_simple_cms/rails/action_view/form_builders/default_spec.rb +8 -0
- data/spec/dead_simple_cms/rails/action_view/form_builders/simple_form_spec.rb +8 -0
- data/spec/dead_simple_cms/rails/action_view/form_builders/simple_form_with_bootstrap_spec.rb +8 -0
- data/spec/dead_simple_cms/rails/action_view/fragment_sweeper_spec.rb +22 -0
- data/spec/dead_simple_cms/rails/action_view/presenter_spec.rb +54 -0
- data/spec/dead_simple_cms/section/builder_spec.rb +28 -0
- data/spec/dead_simple_cms/section_spec.rb +78 -0
- data/spec/dead_simple_cms/storage/base_spec.rb +59 -0
- data/spec/dead_simple_cms/storage/database_spec.rb +51 -0
- data/spec/dead_simple_cms/storage/memory_spec.rb +25 -0
- data/spec/dead_simple_cms/storage/rails_cache_spec.rb +33 -0
- data/spec/dead_simple_cms/storage/redis_spec.rb +33 -0
- data/spec/dead_simple_cms/util/identifier/dictionary/duplciate_item_spec.rb +10 -0
- data/spec/dead_simple_cms/util/identifier/dictionary/invalid_entry_class_spec.rb +10 -0
- data/spec/dead_simple_cms/util/identifier/dictionary_spec.rb +42 -0
- data/spec/dead_simple_cms/util/identifier_spec.rb +27 -0
- data/spec/setup.rb +26 -0
- data/spec/setup/banner_presenter.rb +19 -0
- data/spec/setup/rspec_template_builder.rb +104 -0
- data/spec/setup/shared.rb +57 -0
- data/spec/setup/test_file_uploader.rb +12 -0
- data/spec/spec_helper.rb +48 -0
- metadata +221 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Storage
|
3
|
+
class Base
|
4
|
+
|
5
|
+
# Public: The serializer class used to convert the attributes hash into a String.
|
6
|
+
class_attribute :serializer_class
|
7
|
+
|
8
|
+
attr_reader :section
|
9
|
+
|
10
|
+
def initialize(section)
|
11
|
+
@section = section
|
12
|
+
end
|
13
|
+
|
14
|
+
# Public: Return a hash of the typed attributes from the data source.
|
15
|
+
def read
|
16
|
+
@_cache ||= (value = read_value) ? serializer_class.load(read_value) : {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Write all the attributes of the section to it's data source. Returns the attributes_hash.
|
20
|
+
def write
|
21
|
+
hash = attributes_hash
|
22
|
+
write_value(serializer_class.dump(hash))
|
23
|
+
@_cache = hash # set @_cache after the write
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Unique key for use in the storage mechanism.
|
27
|
+
def unique_key
|
28
|
+
@unique_key ||= section.identifier
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Public: Values to store.
|
34
|
+
def attributes_hash
|
35
|
+
attributes_hash = section.attributes.to_hash
|
36
|
+
attributes_hash.each { |k, attr| attributes_hash[k] = attr.value }
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_value
|
40
|
+
raise(NotImplementedError, "Please provide a read_value method for #{self.class}")
|
41
|
+
end
|
42
|
+
|
43
|
+
def write_value(value)
|
44
|
+
raise(NotImplementedError, "Please provide a write_value method for #{self.class}")
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Storage
|
3
|
+
class Database < Base
|
4
|
+
|
5
|
+
# Public: Table used to store the key/value pairs for the CMS
|
6
|
+
#
|
7
|
+
# Structure
|
8
|
+
# * key: varchar
|
9
|
+
# * value: text
|
10
|
+
#
|
11
|
+
class Table < ActiveRecord::Base
|
12
|
+
self.table_name = "dead_simple_cms"
|
13
|
+
validates :key, :presence => true, :uniqueness => true
|
14
|
+
end
|
15
|
+
|
16
|
+
class_attribute :active_record
|
17
|
+
self.active_record = Table
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def read_value
|
22
|
+
record = active_record.find_by_key(unique_key)
|
23
|
+
record && record.value
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_value(value)
|
27
|
+
record = active_record.find_or_create_by_key(unique_key)
|
28
|
+
record.update_attribute(:value, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Storage
|
3
|
+
# Public: Only used for testing and test-driving purposes. Once your application shutdown, you will lose the CMS information
|
4
|
+
class Memory < Base
|
5
|
+
|
6
|
+
@@cache = {}
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def read_value
|
11
|
+
@@cache[unique_key]
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_value(value)
|
15
|
+
@@cache[unique_key] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Storage
|
3
|
+
# Public: Store all the values in whatever is defined for the rails cache.
|
4
|
+
# Does not support storage of data with the value (ie no file storage support).
|
5
|
+
class RailsCache < Base
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def read_value
|
10
|
+
::Rails.cache.read(unique_key)
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_value(value)
|
14
|
+
::Rails.cache.write(unique_key, value, :expires_in => 5.years.from_now) # some really long time
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Storage
|
3
|
+
class Redis < Base
|
4
|
+
class << self
|
5
|
+
attr_writer :connection
|
6
|
+
def connection
|
7
|
+
@connection ||= (defined?(REDIS) && REDIS) || raise(NotImplementedError, "Redis connection not set.")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def read_value
|
14
|
+
self.class.connection.get(unique_key)
|
15
|
+
end
|
16
|
+
|
17
|
+
def write_value(value)
|
18
|
+
self.class.connection.set(unique_key, value)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'dead_simple_cms/util/identifier/dictionary'
|
2
|
+
module DeadSimpleCMS
|
3
|
+
module Util
|
4
|
+
|
5
|
+
# Public: A module for the convention of having an identifier:
|
6
|
+
#
|
7
|
+
# * an identifier (Symbol)
|
8
|
+
# * a label (default: titleize) to present to the world
|
9
|
+
# * a collection for looking up items based on their `identifier`
|
10
|
+
#
|
11
|
+
# We specifically got away from having a "name" as that usually leads to confusion. Is the name the "foo_bar" name or the
|
12
|
+
# pretty "Foo Bar" name?
|
13
|
+
module Identifier
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
|
16
|
+
included do
|
17
|
+
attr_accessor :label, :identifier
|
18
|
+
end
|
19
|
+
|
20
|
+
module InstanceMethods
|
21
|
+
|
22
|
+
def initialize(identifier, options={})
|
23
|
+
@identifier = identifier.to_sym
|
24
|
+
@label = options[:label] || identifier.to_s.titleize
|
25
|
+
super()
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
# Public: creates a new dictionary class.
|
33
|
+
def new_dictionary(*args, &block)
|
34
|
+
Dictionary.new(self, *args, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module DeadSimpleCMS
|
2
|
+
module Util
|
3
|
+
module Identifier
|
4
|
+
# Public: a dictionary of objects along with their identifiers. Since we are indexing by the identifier, we extend
|
5
|
+
# from Hash since that is our primary data store for the objects. We also enforce the condition that the values must
|
6
|
+
# be of a +target_class+.
|
7
|
+
class Dictionary < Hash
|
8
|
+
class DuplciateItem < StandardError ; end
|
9
|
+
class InvalidEntryClass < StandardError ; end
|
10
|
+
|
11
|
+
attr_reader :target_class, :identifier_method
|
12
|
+
|
13
|
+
def initialize(target_class, *args, &block)
|
14
|
+
options = args.extract_options!
|
15
|
+
@identifier_method = options[:identifier_method] || :identifier
|
16
|
+
@target_class = target_class
|
17
|
+
super(*args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def identifiers
|
21
|
+
keys
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: Convenience method for adding item by it's identifier.
|
25
|
+
def add(item)
|
26
|
+
self[to_identifier(item)] = item
|
27
|
+
end
|
28
|
+
|
29
|
+
def include?(key)
|
30
|
+
key?(to_identifier(key))
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hash
|
34
|
+
Hash[self]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: set a record for the dictionary.
|
38
|
+
#
|
39
|
+
# * If the value is not of type target_class, raise an error.
|
40
|
+
# * If the record already exists, raise an error.
|
41
|
+
def []=(key, value)
|
42
|
+
raise InvalidEntryClass, "Only entries with class #{target_class} can be added" unless value.is_a?(target_class)
|
43
|
+
identifier = to_identifier(key)
|
44
|
+
raise DuplciateItem, "#{identifier} already present in dictionary." if key?(identifier)
|
45
|
+
super(identifier, value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def [](key)
|
49
|
+
super(to_identifier(key))
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Private: Cast an identifier or other object into an identifier.
|
55
|
+
def to_identifier(identifier)
|
56
|
+
case identifier
|
57
|
+
when String, Symbol then identifier.to_sym
|
58
|
+
when Util::Identifier then identifier.send(identifier_method) # if module is included
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DeadSimpleCMS::Attribute::Collection do
|
4
|
+
|
5
|
+
subject { described_class.new(:collection_identifier) }
|
6
|
+
|
7
|
+
describe ".dictionary_identifier_method" do
|
8
|
+
it "should default to :identifier" do
|
9
|
+
described_class.dictionary_identifier_method.should == :identifier
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
its(:identifier) { should == :collection_identifier }
|
14
|
+
|
15
|
+
its(:attributes) { should be_an_instance_of(DeadSimpleCMS::Util::Identifier::Dictionary) }
|
16
|
+
|
17
|
+
its (:persisted?) { should be false }
|
18
|
+
|
19
|
+
describe "#update_attributes" do
|
20
|
+
|
21
|
+
it "should delegate to the setter on #attributes" do
|
22
|
+
subject.should_receive(:foo=).with(:bar)
|
23
|
+
subject.update_attributes(:foo => :bar)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#add_attribute" do
|
29
|
+
|
30
|
+
let(:string_attribute) { DeadSimpleCMS::Attribute::Type::String.new(:string_attr) }
|
31
|
+
|
32
|
+
before(:each) { subject.add_attribute(string_attribute) }
|
33
|
+
|
34
|
+
it "should create a getter method" do
|
35
|
+
string_attribute.stub(:value).and_return("value")
|
36
|
+
subject.string_attr.should == "value"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should create a setter method" do
|
40
|
+
subject.string_attr = "value1"
|
41
|
+
subject.attributes[:string_attr].value.should == "value1"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,252 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
shared_examples_for DeadSimpleCMS::Attribute::Type::CollectionSupport do
|
4
|
+
describe "#initialize" do
|
5
|
+
context "when collection is provided" do
|
6
|
+
|
7
|
+
let(:options) { {} }
|
8
|
+
|
9
|
+
subject { described_class.new(:some_identifier, options.update(:collection => %w{a b c})) }
|
10
|
+
|
11
|
+
context "and valid :input_type is specified" do
|
12
|
+
let(:options) { {:input_type => :radio} }
|
13
|
+
its(:input_type) { should == :radio }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "and valid :input_type is not specified" do
|
17
|
+
let(:options) { {:input_type => :string} }
|
18
|
+
|
19
|
+
def self.default_input_type(type)
|
20
|
+
around(:each) do |example|
|
21
|
+
tmp = described_class.default_input_type
|
22
|
+
described_class.default_input_type = type
|
23
|
+
example.run
|
24
|
+
described_class.default_input_type = tmp
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "and default_input_type is not valid" do
|
29
|
+
default_input_type(:string)
|
30
|
+
its(:input_type) { should == described_class::DEFAULT_COLLECTION_INPUT_TYPE }
|
31
|
+
end
|
32
|
+
|
33
|
+
context "and default_input_type is valid" do
|
34
|
+
default_input_type(:radio)
|
35
|
+
its(:input_type) { should == :radio }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
shared_context "Attribute Setup" do
|
44
|
+
|
45
|
+
let(:options) { {} }
|
46
|
+
|
47
|
+
subject { described_class.new(:sample_identifier, options) }
|
48
|
+
|
49
|
+
end
|
50
|
+
describe DeadSimpleCMS::Attribute::Type::String do
|
51
|
+
|
52
|
+
include_context "Attribute Setup"
|
53
|
+
|
54
|
+
it_behaves_like DeadSimpleCMS::Attribute::Type::CollectionSupport
|
55
|
+
|
56
|
+
its(:default_input_type) { should == :string }
|
57
|
+
|
58
|
+
end
|
59
|
+
describe DeadSimpleCMS::Attribute::Type::Text do
|
60
|
+
|
61
|
+
include_context "Attribute Setup"
|
62
|
+
|
63
|
+
its(:default_input_type) { should == :text }
|
64
|
+
|
65
|
+
end
|
66
|
+
describe DeadSimpleCMS::Attribute::Type::Symbol do
|
67
|
+
|
68
|
+
include_context "Attribute Setup"
|
69
|
+
|
70
|
+
its(:default_input_type) { should == :string }
|
71
|
+
|
72
|
+
end
|
73
|
+
describe DeadSimpleCMS::Attribute::Type::Boolean do
|
74
|
+
|
75
|
+
include_context "Attribute Setup"
|
76
|
+
|
77
|
+
it_behaves_like DeadSimpleCMS::Attribute::Type::CollectionSupport
|
78
|
+
|
79
|
+
its(:default_input_type) { should == :radio }
|
80
|
+
its(:collection) { should == [true, false] }
|
81
|
+
|
82
|
+
describe "#convert_value" do
|
83
|
+
it %{should convert "true" or "1" into TrueClass} do
|
84
|
+
["True", "true", "1", "TruE"].each do |str|
|
85
|
+
subject.send(:convert_value, str).should be true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it %{should interpret everything else as false} do
|
90
|
+
%w{abcs false 0 dude sweet}.each do |str|
|
91
|
+
subject.send(:convert_value, str).should be false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when a non-String is passed in" do
|
96
|
+
it "should interpret true or false as themselves" do
|
97
|
+
[true, false].each do |bool|
|
98
|
+
subject.send(:convert_value, bool).should be bool
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should interpret nil as false" do
|
103
|
+
subject.send(:convert_value, nil).should be false
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should interpret other objects" do
|
107
|
+
[Object.new, :dfdf].each { |x| subject.send(:convert_value, x).should be true }
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
describe DeadSimpleCMS::Attribute::Type::Numeric do
|
114
|
+
|
115
|
+
include_context "Attribute Setup"
|
116
|
+
|
117
|
+
it_behaves_like DeadSimpleCMS::Attribute::Type::CollectionSupport
|
118
|
+
|
119
|
+
its(:default_input_type) { should == :string }
|
120
|
+
|
121
|
+
end
|
122
|
+
describe DeadSimpleCMS::Attribute::Type::Integer do
|
123
|
+
|
124
|
+
include_context "Attribute Setup"
|
125
|
+
|
126
|
+
it_behaves_like DeadSimpleCMS::Attribute::Type::CollectionSupport
|
127
|
+
|
128
|
+
its(:default_input_type) { should == :string }
|
129
|
+
|
130
|
+
describe "#convert_value" do
|
131
|
+
it "should convert the value into an integer" do
|
132
|
+
subject.send(:convert_value, "545").should be 545
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should return nil if nil passed in" do
|
136
|
+
subject.send(:convert_value, nil).should be nil
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
describe DeadSimpleCMS::Attribute::Type::File do
|
143
|
+
|
144
|
+
include_context "Attribute Setup"
|
145
|
+
|
146
|
+
its(:default_input_type) { should == :file }
|
147
|
+
|
148
|
+
let(:file_ext) { "jpg" }
|
149
|
+
let(:data) { double("data") }
|
150
|
+
let(:options) { {:data => data, :file_ext => file_ext}}
|
151
|
+
let(:uploaded_file) do
|
152
|
+
require 'stringio'
|
153
|
+
ActionDispatch::Http::UploadedFile.new(:filename => "filename.png", :tempfile => StringIO.new("file information") )
|
154
|
+
end
|
155
|
+
|
156
|
+
its(:data) { should == data }
|
157
|
+
|
158
|
+
describe "#file_ext" do
|
159
|
+
its(:file_ext) { should == file_ext }
|
160
|
+
|
161
|
+
it "should default to 'dat' if none provided" do
|
162
|
+
described_class.new(:identifier).file_ext.should == "dat"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#convert_value" do
|
167
|
+
it "should return the value if it is a String" do
|
168
|
+
subject.send(:convert_value, "string").should == "string"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should return the value if it is nil" do
|
172
|
+
subject.send(:convert_value, nil).should be nil
|
173
|
+
end
|
174
|
+
|
175
|
+
context "when ActionDispatch::Http::UploadedFile is passed in" do
|
176
|
+
it "should set the file_ext from the uploaded filename" do
|
177
|
+
subject.send(:convert_value, uploaded_file)
|
178
|
+
subject.file_ext.should == "png"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should set the data" do
|
182
|
+
subject.send(:convert_value, uploaded_file)
|
183
|
+
subject.data.should == "file information"
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should return the stored @value" do
|
187
|
+
subject.instance_variable_set(:@value, :value)
|
188
|
+
subject.send(:convert_value, uploaded_file).should == :value
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#upload!" do
|
194
|
+
|
195
|
+
context "when uploader_class is not set" do
|
196
|
+
around(:each) do |example|
|
197
|
+
tmp = described_class.uploader_class
|
198
|
+
described_class.uploader_class = nil
|
199
|
+
example.run
|
200
|
+
described_class.uploader_class = tmp
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should raise an error if the uploader_class is not set" do
|
204
|
+
lambda { subject.upload! }.should raise_error(NotImplementedError)
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
|
209
|
+
context "when uploader_class is set" do
|
210
|
+
let(:file_uploader_class) do
|
211
|
+
Class.new(DeadSimpleCMS::FileUploader::Base) do
|
212
|
+
def upload! ; end
|
213
|
+
def url; "new url" end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
before(:each) do
|
218
|
+
subject.uploader_class = file_uploader_class
|
219
|
+
end
|
220
|
+
it "should call upload!" do
|
221
|
+
subject.should_receive(:upload!).once
|
222
|
+
subject.upload!
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should set the url with the value" do
|
226
|
+
subject.upload!
|
227
|
+
subject.value.should == "new url"
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
describe DeadSimpleCMS::Attribute::Type::Image do
|
236
|
+
|
237
|
+
include_context "Attribute Setup"
|
238
|
+
|
239
|
+
let(:options) { {:width => 406, :height => 600} }
|
240
|
+
|
241
|
+
its(:width) { should == 406 }
|
242
|
+
its(:height) { should == 600 }
|
243
|
+
|
244
|
+
describe "#hint" do
|
245
|
+
context "when not set" do
|
246
|
+
its(:hint) { should == "Image should be 406 x 600." }
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
end
|
251
|
+
|
252
|
+
|