dead_simple_cms 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|