spontaneous 0.2.0.beta9 → 0.2.0.beta10
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -0
- data/LICENSE +18 -17
- data/Rakefile +1 -1
- data/application/css/core.css.scss +1 -1
- data/application/css/dialogue.css.scss +8 -20
- data/application/js/preview.js +28 -7
- data/application/js/publish.js +15 -4
- data/application/js/top_bar.js +0 -16
- data/application/js/views/piece_view.js +1 -1
- data/lib/spontaneous/asset/environment.rb +16 -1
- data/lib/spontaneous/box.rb +68 -0
- data/lib/spontaneous/capistrano/deploy.rb +7 -4
- data/lib/spontaneous/capistrano/sync.rb +2 -2
- data/lib/spontaneous/cli/init.rb +70 -19
- data/lib/spontaneous/cli/init/db.rb +34 -55
- data/lib/spontaneous/cli/init/mysql.rb +5 -5
- data/lib/spontaneous/cli/init/postgresql.rb +8 -9
- data/lib/spontaneous/cli/init/sqlite.rb +1 -2
- data/lib/spontaneous/cli/migrate.rb +0 -1
- data/lib/spontaneous/cli/site.rb +4 -0
- data/lib/spontaneous/collections/entry_set.rb +11 -0
- data/lib/spontaneous/data_mapper/content_model.rb +2 -0
- data/lib/spontaneous/data_mapper/content_model/serialization.rb +2 -2
- data/lib/spontaneous/extensions/array.rb +12 -2
- data/lib/spontaneous/field/base.rb +10 -0
- data/lib/spontaneous/field/file.rb +32 -2
- data/lib/spontaneous/field/image.rb +24 -2
- data/lib/spontaneous/field/select.rb +8 -0
- data/lib/spontaneous/field/webvideo.rb +8 -0
- data/lib/spontaneous/generators/site/config/initializers/fields.rb +55 -0
- data/lib/spontaneous/json.rb +3 -2
- data/lib/spontaneous/logger.rb +2 -2
- data/lib/spontaneous/media/file.rb +3 -3
- data/lib/spontaneous/media/image/attributes.rb +72 -6
- data/lib/spontaneous/media/image/renderable.rb +53 -20
- data/lib/spontaneous/media/store.rb +3 -3
- data/lib/spontaneous/media/store/backend.rb +16 -0
- data/lib/spontaneous/media/store/cloud.rb +52 -12
- data/lib/spontaneous/media/store/local.rb +6 -3
- data/lib/spontaneous/model.rb +3 -0
- data/lib/spontaneous/model/core/entries.rb +34 -13
- data/lib/spontaneous/model/core/entry.rb +3 -1
- data/lib/spontaneous/model/page/controllers.rb +1 -2
- data/lib/spontaneous/model/page/paths.rb +18 -7
- data/lib/spontaneous/output/context.rb +0 -8
- data/lib/spontaneous/output/template/renderer.rb +2 -0
- data/lib/spontaneous/plugins/application/state.rb +0 -4
- data/lib/spontaneous/prototypes/field_prototype.rb +4 -0
- data/lib/spontaneous/publishing/immediate.rb +0 -5
- data/lib/spontaneous/publishing/progress.rb +2 -2
- data/lib/spontaneous/publishing/rerender.rb +1 -4
- data/lib/spontaneous/publishing/simultaneous.rb +19 -17
- data/lib/spontaneous/publishing/steps.rb +12 -3
- data/lib/spontaneous/rack.rb +2 -0
- data/lib/spontaneous/rack/asset_server.rb +5 -2
- data/lib/spontaneous/rack/back.rb +9 -1
- data/lib/spontaneous/rack/back/base.rb +1 -0
- data/lib/spontaneous/rack/back/changes.rb +5 -0
- data/lib/spontaneous/rack/back/preview.rb +4 -4
- data/lib/spontaneous/rack/back/private.rb +11 -0
- data/lib/spontaneous/rack/middleware/scope.rb +16 -4
- data/lib/spontaneous/rack/page_controller.rb +2 -2
- data/lib/spontaneous/rack/public.rb +52 -4
- data/lib/spontaneous/sequel.rb +10 -13
- data/lib/spontaneous/site.rb +28 -8
- data/lib/spontaneous/site/publishing.rb +1 -1
- data/lib/spontaneous/site/storage.rb +7 -4
- data/lib/spontaneous/tasks/environment.rake +3 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +23 -2
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +7 -12
- data/test/fixtures/assets/public1/css/data.css.scss +1 -1
- data/test/functional/test_application.rb +15 -0
- data/test/functional/test_cli.rb +109 -3
- data/test/functional/test_front.rb +108 -10
- data/test/test_helper.rb +3 -3
- data/test/unit/fields/test_boolean_fields.rb +80 -0
- data/test/unit/fields/test_date_fields.rb +47 -0
- data/test/unit/fields/test_file_field.rb +210 -0
- data/test/unit/{test_images.rb → fields/test_image_fields.rb} +133 -15
- data/test/unit/fields/test_location_fields.rb +41 -0
- data/test/unit/fields/test_option_fields.rb +61 -0
- data/test/unit/fields/test_tag_list_fields.rb +45 -0
- data/test/unit/fields/test_text_fields.rb +124 -0
- data/test/unit/fields/test_web_video_fields.rb +198 -0
- data/test/unit/test_assets.rb +22 -22
- data/test/unit/test_boxes.rb +34 -13
- data/test/unit/test_changesets.rb +1 -0
- data/test/unit/test_extensions.rb +17 -0
- data/test/unit/test_fields.rb +20 -643
- data/test/unit/test_media.rb +9 -9
- data/test/unit/test_page.rb +47 -0
- data/test/unit/test_publishing_pipeline.rb +2 -2
- data/test/unit/test_serialisation.rb +37 -0
- data/test/unit/test_storage.rb +42 -3
- metadata +37 -17
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe "Date fields" do
         | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                @site = setup_site
         | 
| 8 | 
            +
                @now = Time.now
         | 
| 9 | 
            +
                stub_time(@now)
         | 
| 10 | 
            +
                Spontaneous::State.delete
         | 
| 11 | 
            +
                @site.background_mode = :immediate
         | 
| 12 | 
            +
                @content_class = Class.new(::Piece)
         | 
| 13 | 
            +
                @prototype = @content_class.field :date
         | 
| 14 | 
            +
                @content_class.stubs(:name).returns("ContentClass")
         | 
| 15 | 
            +
                @instance = @content_class.create
         | 
| 16 | 
            +
                @field = @instance.date
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              it "have a distinct editor class" do
         | 
| 20 | 
            +
                @prototype.instance_class.editor_class.must_equal "Spontaneous.Field.Date"
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it "adopt any field called 'date'" do
         | 
| 24 | 
            +
                assert @field.is_a?(Spontaneous::Field::Date), "Field should be an instance of DateField but instead has the following ancestors #{ @prototype.instance_class.ancestors }"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it "default to an empty string" do
         | 
| 28 | 
            +
                @field.value(:html).must_equal ""
         | 
| 29 | 
            +
                @field.value(:plain).must_equal ""
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              it "correctly parse strings" do
         | 
| 33 | 
            +
                @field.value = "Friday, 8 June, 2012"
         | 
| 34 | 
            +
                @field.value(:html).must_equal %(<time datetime="2012-06-08">Friday, 8 June, 2012</time>)
         | 
| 35 | 
            +
                @field.value(:plain).must_equal %(Friday, 8 June, 2012)
         | 
| 36 | 
            +
                @field.date.must_equal Date.parse("Friday, 8 June, 2012")
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              it "allow for setting a custom default format" do
         | 
| 40 | 
            +
                prototype = @content_class.field :datef, :date, :format => "%d %b %Y, %a"
         | 
| 41 | 
            +
                instance = @content_class.new
         | 
| 42 | 
            +
                field = instance.datef
         | 
| 43 | 
            +
                field.value = "Friday, 8 June, 2012"
         | 
| 44 | 
            +
                field.value(:html).must_equal %(<time datetime="2012-06-08">08 Jun 2012, Fri</time>)
         | 
| 45 | 
            +
                field.value(:plain).must_equal %(08 Jun 2012, Fri)
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,210 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 4 | 
            +
            require 'fog'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            describe "File Fields" do
         | 
| 7 | 
            +
              let(:path) { File.expand_path("../../../fixtures/images/vimlogo.pdf", __FILE__) }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def site
         | 
| 10 | 
            +
                @site = setup_site
         | 
| 11 | 
            +
                @now = Time.now
         | 
| 12 | 
            +
                stub_time(@now)
         | 
| 13 | 
            +
                Spontaneous::State.delete
         | 
| 14 | 
            +
                @site.background_mode = :immediate
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              before do
         | 
| 17 | 
            +
                site
         | 
| 18 | 
            +
                assert File.exists?(path), "Test file #{path} does not exist"
         | 
| 19 | 
            +
                @content_class = Class.new(::Piece)
         | 
| 20 | 
            +
                @prototype = @content_class.field :file
         | 
| 21 | 
            +
                @content_class.stubs(:name).returns("ContentClass")
         | 
| 22 | 
            +
                @instance = @content_class.create
         | 
| 23 | 
            +
                @field = @instance.file
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              after do
         | 
| 27 | 
            +
                teardown_site
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
              it "have a distinct editor class" do
         | 
| 30 | 
            +
                @prototype.instance_class.editor_class.must_equal "Spontaneous.Field.File"
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              it "adopt any field called 'file'" do
         | 
| 34 | 
            +
                assert @field.is_a?(Spontaneous::Field::File), "Field should be an instance of FileField but instead has the following ancestors #{ @prototype.instance_class.ancestors }"
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              it "gives the right value for #blank?" do
         | 
| 38 | 
            +
                @field.blank?.must_equal true
         | 
| 39 | 
            +
                @field.value = 'http://example.com/image.jpg'
         | 
| 40 | 
            +
                @field.blank?.must_equal false
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              it "copy files to the media folder" do
         | 
| 44 | 
            +
                File.open(path, 'rb') do |file|
         | 
| 45 | 
            +
                  @field.value = {
         | 
| 46 | 
            +
                    :tempfile => file,
         | 
| 47 | 
            +
                    :type => "application/pdf",
         | 
| 48 | 
            +
                    :filename => "vimlogo.pdf"
         | 
| 49 | 
            +
                  }
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                url = @field.value
         | 
| 52 | 
            +
                path = File.join File.dirname(Spontaneous.media_dir), url
         | 
| 53 | 
            +
                assert File.exist?(path), "Media file should have been copied into place"
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "generate the requisite file metadata" do
         | 
| 57 | 
            +
                File.open(path, 'rb') do |file|
         | 
| 58 | 
            +
                  @field.value = {
         | 
| 59 | 
            +
                    :tempfile => file,
         | 
| 60 | 
            +
                    :type => "application/pdf",
         | 
| 61 | 
            +
                    :filename => "vimlogo.pdf"
         | 
| 62 | 
            +
                  }
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                @field.value(:html).must_match %r{/media/.+/vimlogo.pdf$}
         | 
| 65 | 
            +
                @field.value.must_match %r{/media/.+/vimlogo.pdf$}
         | 
| 66 | 
            +
                @field.path.must_equal @field.value
         | 
| 67 | 
            +
                @field.value(:filesize).must_equal 2254
         | 
| 68 | 
            +
                @field.filesize.must_equal 2254
         | 
| 69 | 
            +
                @field.value(:filename).must_equal "vimlogo.pdf"
         | 
| 70 | 
            +
                @field.filename.must_equal "vimlogo.pdf"
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              it "just accept the given value if passed a path to a non-existant file" do
         | 
| 74 | 
            +
                @field.value = "/images/nosuchfile.rtf"
         | 
| 75 | 
            +
                @field.value.must_equal  "/images/nosuchfile.rtf"
         | 
| 76 | 
            +
                @field.filename.must_equal "nosuchfile.rtf"
         | 
| 77 | 
            +
                @field.filesize.must_equal 0
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              it "copy the given file if passed a path to an existing file" do
         | 
| 81 | 
            +
                @field.value = path
         | 
| 82 | 
            +
                @field.value.must_match %r{/media/.+/vimlogo.pdf$}
         | 
| 83 | 
            +
                @field.filename.must_equal "vimlogo.pdf"
         | 
| 84 | 
            +
                @field.filesize.must_equal 2254
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
              it "sets the unprocessed value to a JSON encoded array of MD5 hash & filename" do
         | 
| 88 | 
            +
                @field.value = path
         | 
| 89 | 
            +
                @instance.save
         | 
| 90 | 
            +
                @field.unprocessed_value.must_equal ["vimlogo.pdf", "1de7e866d69c2f56b4a3f59ed1c98b74"].to_json
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              it "sets the field hash to the MD5 hash of the file" do
         | 
| 94 | 
            +
                @field.value = path
         | 
| 95 | 
            +
                @field.file_hash.must_equal "1de7e866d69c2f56b4a3f59ed1c98b74"
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              it "sets the original filename of the file" do
         | 
| 99 | 
            +
                @field.value = path
         | 
| 100 | 
            +
                @field.original_filename.must_equal "vimlogo.pdf"
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              it "doesn't set the hash of a file that can't be found" do
         | 
| 104 | 
            +
                @field.value = "/images/nosuchfile.rtf"
         | 
| 105 | 
            +
                @field.file_hash.must_equal ""
         | 
| 106 | 
            +
              end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              it "sets the original filename of a file that can't be found" do
         | 
| 109 | 
            +
                @field.value = "/images/nosuchfile.rtf"
         | 
| 110 | 
            +
                @field.original_filename.must_equal "/images/nosuchfile.rtf"
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              it "sets the storage name if given an uploaded file" do
         | 
| 114 | 
            +
                @field.value = path
         | 
| 115 | 
            +
                @field.storage_name.must_equal "default"
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              it "sets the storage name if given an uploaded file" do
         | 
| 119 | 
            +
                @field.value = path
         | 
| 120 | 
            +
                @field.storage.must_equal @site.storage
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
              it "sets the storage name to nil for file paths" do
         | 
| 124 | 
            +
                @field.value = "/images/nosuchfile.rtf"
         | 
| 125 | 
            +
                @field.storage_name.must_equal nil
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
              it "allows for re-configuring the generated media URLs" do
         | 
| 129 | 
            +
                @field.value = path
         | 
| 130 | 
            +
                @field.path.must_match %r{^/media/.+/vimlogo.pdf$}
         | 
| 131 | 
            +
                storage = @site.storage("default")
         | 
| 132 | 
            +
                storage.url_mapper = ->(path) { "http://media.example.com#{path}"}
         | 
| 133 | 
            +
                @field.value(:html).must_match %r{^http://media.example.com/media/.+/vimlogo.pdf$}
         | 
| 134 | 
            +
                @field.path.must_match %r{^http://media.example.com/media/.+/vimlogo.pdf$}
         | 
| 135 | 
            +
                @field.url.must_match %r{^http://media.example.com/media/.+/vimlogo.pdf$}
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
              describe "clearing" do
         | 
| 139 | 
            +
                def assert_file_field_empty
         | 
| 140 | 
            +
                  @field.value.must_equal ''
         | 
| 141 | 
            +
                  @field.filename.must_equal ''
         | 
| 142 | 
            +
                  @field.filesize.must_equal 0
         | 
| 143 | 
            +
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                before do
         | 
| 146 | 
            +
                  path = File.expand_path("../../fixtures/images/vimlogo.pdf", __FILE__)
         | 
| 147 | 
            +
                  @field.value = path
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                it "clears the value if set to the empty string" do
         | 
| 151 | 
            +
                  @field.value = ''
         | 
| 152 | 
            +
                  assert_file_field_empty
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
              end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
              describe "with cloud storage" do
         | 
| 157 | 
            +
                before do
         | 
| 158 | 
            +
                  ::Fog.mock!
         | 
| 159 | 
            +
                  @storage_config = {
         | 
| 160 | 
            +
                    provider: "AWS",
         | 
| 161 | 
            +
                    aws_secret_access_key: "SECRET_ACCESS_KEY",
         | 
| 162 | 
            +
                    aws_access_key_id: "ACCESS_KEY_ID",
         | 
| 163 | 
            +
                    public_host: 'https://media.example.com'
         | 
| 164 | 
            +
                  }
         | 
| 165 | 
            +
                  @storage = S::Media::Store::Cloud.new("S3", @storage_config, "media.example.com")
         | 
| 166 | 
            +
                  @storage.name.must_equal "S3"
         | 
| 167 | 
            +
                  @site.storage_backends.unshift(@storage)
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                it "sets the content-disposition header if defined as an 'attachment'" do
         | 
| 171 | 
            +
                  prototype = @content_class.field :attachment, :file, attachment: true
         | 
| 172 | 
            +
                  field = @instance.attachment
         | 
| 173 | 
            +
                  path = File.expand_path("../../../fixtures/images/vimlogo.pdf", __FILE__)
         | 
| 174 | 
            +
                  @storage.expects(:copy).with(path, is_a(Array), { content_type: "application/pdf", content_disposition: 'attachment; filename=vimlogo.pdf'})
         | 
| 175 | 
            +
                  field.value = path
         | 
| 176 | 
            +
                end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                describe 'storage' do
         | 
| 179 | 
            +
                  before do
         | 
| 180 | 
            +
                    @prototype = @content_class.field :attachment, :file
         | 
| 181 | 
            +
                    @field = @instance.attachment
         | 
| 182 | 
            +
                    @storage.stubs(:copy).with(path, is_a(Array), { content_type: "application/pdf"})
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                  it "sets the storage name if given an uploaded file" do
         | 
| 186 | 
            +
                    @field.value = path
         | 
| 187 | 
            +
                    @field.storage_name.must_equal "S3"
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                  it "allows for the file url to be configured by the storage" do
         | 
| 191 | 
            +
                    @field.value = path
         | 
| 192 | 
            +
                    @field.url.must_match %r[^https://media.example.com/0000#{@instance.id}/0001/vimlogo.pdf$]
         | 
| 193 | 
            +
                    @storage.url_mapper = ->(path) { "https://cdn.example.com#{path}" }
         | 
| 194 | 
            +
                    @field.url.must_match %r[^https://cdn.example.com/0000#{@instance.id}/0001/vimlogo.pdf$]
         | 
| 195 | 
            +
                  end
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                  it 'falls back to the site’s default if initialized before storage_name output was defined' do
         | 
| 198 | 
            +
                    @field.value = path
         | 
| 199 | 
            +
                    @field.stubs(:storage_name).returns('[]')
         | 
| 200 | 
            +
                    @field.url.must_match %r[^/0000#{@instance.id}/0001/vimlogo.pdf$]
         | 
| 201 | 
            +
                  end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                  it "gives the right value for #blank?" do
         | 
| 204 | 
            +
                    @field.blank?.must_equal true
         | 
| 205 | 
            +
                    @field.value = path
         | 
| 206 | 
            +
                    @field.blank?.must_equal false
         | 
| 207 | 
            +
                  end
         | 
| 208 | 
            +
                end
         | 
| 209 | 
            +
              end
         | 
| 210 | 
            +
            end
         | 
| @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            # encoding: UTF-8
         | 
| 2 2 |  | 
| 3 3 |  | 
| 4 | 
            -
            require File.expand_path(' | 
| 4 | 
            +
            require File.expand_path('../../../test_helper', __FILE__)
         | 
| 5 5 | 
             
            require 'fog'
         | 
| 6 6 |  | 
| 7 | 
            -
            describe " | 
| 7 | 
            +
            describe "Image Fields" do
         | 
| 8 8 |  | 
| 9 9 | 
             
              before do
         | 
| 10 10 | 
             
                @site = setup_site
         | 
| @@ -16,9 +16,14 @@ describe "Images" do | |
| 16 16 |  | 
| 17 17 | 
             
              describe "Image fields set using absolute values" do
         | 
| 18 18 | 
             
                before do
         | 
| 19 | 
            +
                  class ::Piece < ::Content::Piece
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                  @owner = Piece.create
         | 
| 19 22 | 
             
                  @image = S::Field::Image.new(:name => "image")
         | 
| 23 | 
            +
                  @image.owner = @owner
         | 
| 20 24 | 
             
                  @image.prototype = Spontaneous::Prototypes::FieldPrototype.new(@site.model, :image, :image)
         | 
| 21 25 | 
             
                end
         | 
| 26 | 
            +
             | 
| 22 27 | 
             
                it "accept and not alter URL values" do
         | 
| 23 28 | 
             
                  url =  "http://example.com/image.png"
         | 
| 24 29 | 
             
                  @image.value = url
         | 
| @@ -52,7 +57,7 @@ describe "Images" do | |
| 52 57 | 
             
                  @revision = 10
         | 
| 53 58 | 
             
                  @site.stubs(:working_revision).returns(@revision)
         | 
| 54 59 |  | 
| 55 | 
            -
                  @src_image =  Pathname.new(File.join(File.dirname(__FILE__), " | 
| 60 | 
            +
                  @src_image =  Pathname.new(File.join(File.dirname(__FILE__), "../../fixtures/images/rose.jpg")).realpath
         | 
| 56 61 | 
             
                  @origin_image = @upload_dir + "rose.jpg"
         | 
| 57 62 | 
             
                  FileUtils.cp(@src_image.to_s, @origin_image.to_s)
         | 
| 58 63 | 
             
                  @origin_image = @origin_image.realpath.to_s
         | 
| @@ -125,8 +130,33 @@ describe "Images" do | |
| 125 130 |  | 
| 126 131 | 
             
                  describe "in templates" do
         | 
| 127 132 |  | 
| 133 | 
            +
                    after do
         | 
| 134 | 
            +
                      Spontaneous::Field::Image.default_attributes = {}
         | 
| 135 | 
            +
                    end
         | 
| 136 | 
            +
             | 
| 128 137 | 
             
                    it "render an <img/> tag in HTML format" do
         | 
| 129 | 
            -
                      assert_has_elements @image.to_html.split(' '), %(<img src="#{@image.src}"  | 
| 138 | 
            +
                      assert_has_elements @image.to_html.split(' '), %(<img src="#{@image.src}" alt="" />).split(" ")
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                    it 'will fill in the image’s size if told to do so' do
         | 
| 142 | 
            +
                      expected = %(<img src="#{@image.src}" width="400" height="533" alt="" />).split(" ")
         | 
| 143 | 
            +
                      assert_has_elements @image.to_html(size: true).split(' '), expected
         | 
| 144 | 
            +
                      assert_has_elements @image.to_html(size: :auto).split(' '), expected
         | 
| 145 | 
            +
                      assert_has_elements @image.to_html(size: 'auto').split(' '), expected
         | 
| 146 | 
            +
                    end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                    it 'will fill in the image’s width with natural value if given a size of auto' do
         | 
| 149 | 
            +
                      expected = %(<img src="#{@image.src}" width="400" alt="" />).split(" ")
         | 
| 150 | 
            +
                      assert_has_elements @image.to_html(width: :auto).split(' '), expected
         | 
| 151 | 
            +
                      assert_has_elements @image.to_html(width: true).split(' '), expected
         | 
| 152 | 
            +
                      assert_has_elements @image.to_html(width: 'auto').split(' '), expected
         | 
| 153 | 
            +
                    end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                    it 'will fill in the image’s height with natural value if given a size of auto' do
         | 
| 156 | 
            +
                      expected = %(<img src="#{@image.src}" height="533" alt="" />).split(" ")
         | 
| 157 | 
            +
                      assert_has_elements @image.to_html(height: true).split(' '), expected
         | 
| 158 | 
            +
                      assert_has_elements @image.to_html(height: :auto).split(' '), expected
         | 
| 159 | 
            +
                      assert_has_elements @image.to_html(height: 'auto').split(' '), expected
         | 
| 130 160 | 
             
                    end
         | 
| 131 161 |  | 
| 132 162 | 
             
                    it "use passed hash to overwrite tag attributes" do
         | 
| @@ -136,21 +166,21 @@ describe "Images" do | |
| 136 166 | 
             
                        :rel => "lightbox",
         | 
| 137 167 | 
             
                        :random => "present"
         | 
| 138 168 | 
             
                      }
         | 
| 139 | 
            -
                      assert_has_elements @image.to_html(attr).split(" "), %(<img src="#{@image.src}"  | 
| 169 | 
            +
                      assert_has_elements @image.to_html(attr).split(" "), %(<img src="#{@image.src}" alt="Magic" class="magic" rel="lightbox" random="present" />).split(" ")
         | 
| 140 170 | 
             
                    end
         | 
| 141 171 |  | 
| 142 172 | 
             
                    it "be intelligent about setting width & height" do
         | 
| 143 | 
            -
                      @image.to_html({ : | 
| 144 | 
            -
                      assert_has_elements @image.to_html({ : | 
| 145 | 
            -
                      assert_has_elements @image.to_html({ : | 
| 173 | 
            +
                      @image.to_html({ width: 100 }).split(" ").must_have_elements %(<img src="#{@image.src}" width="100" alt="" />).split(" ")
         | 
| 174 | 
            +
                      assert_has_elements @image.to_html({ height: 100 }).split(" "), %(<img src="#{@image.src}" height="100" alt="" />).split(" ")
         | 
| 175 | 
            +
                      assert_has_elements @image.to_html({ width: 100, height: 100 }).split(" "), %(<img src="#{@image.src}" width="100" height="100" alt="" />).split(" ")
         | 
| 146 176 | 
             
                    end
         | 
| 147 177 |  | 
| 148 | 
            -
                    it "turn off setting  | 
| 178 | 
            +
                    it "turn off setting width & height if either is passed as false" do
         | 
| 149 179 | 
             
                      assert_has_elements @image.to_html({ :width => false }).split(" "), %(<img src="#{@image.src}" alt="" />).split(" ")
         | 
| 150 180 | 
             
                    end
         | 
| 151 181 |  | 
| 152 182 | 
             
                    it "escape values in params" do
         | 
| 153 | 
            -
                      assert_has_elements @image.to_html({ :alt => "<danger\">" }).split(" "), %(<img src="#{@image.src}"  | 
| 183 | 
            +
                      assert_has_elements @image.to_html({ :alt => "<danger\">" }).split(" "), %(<img src="#{@image.src}" alt="<danger">" />).split(" ")
         | 
| 154 184 | 
             
                    end
         | 
| 155 185 |  | 
| 156 186 | 
             
                    it "not include size parameters unless known" do
         | 
| @@ -160,7 +190,22 @@ describe "Images" do | |
| 160 190 | 
             
                    end
         | 
| 161 191 |  | 
| 162 192 | 
             
                    it "output image tags for its sizes too" do
         | 
| 163 | 
            -
                      assert_has_elements @image.thumbnail.to_html(: | 
| 193 | 
            +
                      assert_has_elements @image.thumbnail.to_html(alt: "Thumb", size: true).split(' '), %(<img src="#{@image.thumbnail.src}" width="38" height="50" alt="Thumb" />).split(" ")
         | 
| 194 | 
            +
                    end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                    it 'allows for setting site-wide options' do
         | 
| 197 | 
            +
                      Spontaneous::Field::Image.default_attributes = { width: :auto, alt: 'Banana'}
         | 
| 198 | 
            +
                      assert_has_elements @image.to_html().split(' '), %(<img src="#{@image.src}" width="400" alt="Banana" />).split(" ")
         | 
| 199 | 
            +
                      assert_has_elements @image.to_html(width: false, alt: 'Other').split(' '), %(<img src="#{@image.src}" alt="Other" />).split(" ")
         | 
| 200 | 
            +
                    end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                    it 'allows for setting values with a proc' do
         | 
| 203 | 
            +
                      Spontaneous::Field::Image.default_attributes = { something: proc { |field| field.name }}
         | 
| 204 | 
            +
                      assert_has_elements @image.to_html().split(' '), %(<img src="#{@image.src}" alt="" something="photo" />).split(" ")
         | 
| 205 | 
            +
                    end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
                    it 'allows for setting data-* values with a hash' do
         | 
| 208 | 
            +
                      assert_has_elements @image.to_html(data: {name: proc { |field| field.name }, id: proc { |field| field.owner.id }}).split(' '), %(<img src="#{@image.src}" alt="" data-name="photo" data-id="#{@content_id}" />).split(" ")
         | 
| 164 209 | 
             
                    end
         | 
| 165 210 | 
             
                  end
         | 
| 166 211 | 
             
                  describe "defined by classes" do
         | 
| @@ -257,7 +302,7 @@ describe "Images" do | |
| 257 302 |  | 
| 258 303 | 
             
                end
         | 
| 259 304 |  | 
| 260 | 
            -
                describe "cloud storage | 
| 305 | 
            +
                describe "cloud storage" do
         | 
| 261 306 | 
             
                  before do
         | 
| 262 307 | 
             
                    @bucket_name = "media.example.com"
         | 
| 263 308 | 
             
                    @aws_credentials = {
         | 
| @@ -267,9 +312,9 @@ describe "Images" do | |
| 267 312 | 
             
                      :public_host => "http://media.example.com"
         | 
| 268 313 | 
             
                    }
         | 
| 269 314 | 
             
                    ::Fog.mock!
         | 
| 270 | 
            -
                    @storage = Spontaneous::Media::Store::Cloud.new(@aws_credentials, 'media.example.com')
         | 
| 315 | 
            +
                    @storage = Spontaneous::Media::Store::Cloud.new("S3", @aws_credentials, 'media.example.com')
         | 
| 271 316 | 
             
                    @storage.backend.directories.create(:key => @bucket_name)
         | 
| 272 | 
            -
                    @site. | 
| 317 | 
            +
                    @site.storage_backends.unshift(@storage)
         | 
| 273 318 | 
             
                    @image.value = @origin_image.to_s
         | 
| 274 319 | 
             
                  end
         | 
| 275 320 |  | 
| @@ -281,6 +326,79 @@ describe "Images" do | |
| 281 326 | 
             
                    @image.original.src.must_equal "http://media.example.com/00234/0010/rose.jpg"
         | 
| 282 327 | 
             
                    @image.thumbnail.src.must_equal "http://media.example.com/00234/0010/rose.thumbnail.jpg"
         | 
| 283 328 | 
             
                  end
         | 
| 329 | 
            +
             | 
| 330 | 
            +
                  it "allows for reconfiguring the media urls" do
         | 
| 331 | 
            +
                    @storage.url_mapper = proc { |path| "http://cdn.example.com#{path}" }
         | 
| 332 | 
            +
                    @image.original.src.must_equal "http://cdn.example.com/00234/0010/rose.jpg"
         | 
| 333 | 
            +
                    @image.thumbnail.src.must_equal "http://cdn.example.com/00234/0010/rose.thumbnail.jpg"
         | 
| 334 | 
            +
                  end
         | 
| 335 | 
            +
                end
         | 
| 336 | 
            +
              end
         | 
| 337 | 
            +
             | 
| 338 | 
            +
              describe '#blank?' do
         | 
| 339 | 
            +
                before do
         | 
| 340 | 
            +
                  class ::ContentWithImage < ::Content::Piece
         | 
| 341 | 
            +
                    field :photo, :image do
         | 
| 342 | 
            +
                      size :smaller do
         | 
| 343 | 
            +
                        fit width: 100, height: 100
         | 
| 344 | 
            +
                      end
         | 
| 345 | 
            +
                    end
         | 
| 346 | 
            +
                  end
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                  @instance = ContentWithImage.new
         | 
| 349 | 
            +
             | 
| 350 | 
            +
                  # @content_id = 234
         | 
| 351 | 
            +
                  # @instance.stubs(:id).returns(@content_id)
         | 
| 352 | 
            +
                  @field = @instance.photo
         | 
| 353 | 
            +
                end
         | 
| 354 | 
            +
             | 
| 355 | 
            +
                after do
         | 
| 356 | 
            +
                  Object.send(:remove_const, :ContentWithImage) rescue nil
         | 
| 357 | 
            +
                end
         | 
| 358 | 
            +
             | 
| 359 | 
            +
                it 'returns true for empty images' do
         | 
| 360 | 
            +
                  @field.blank?.must_equal true
         | 
| 361 | 
            +
                  @field.original.blank?.must_equal true
         | 
| 362 | 
            +
                  @field.smaller.blank?.must_equal true
         | 
| 363 | 
            +
                end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                it 'returns false for images with values' do
         | 
| 366 | 
            +
                  path = File.expand_path("../../../../fixtures/images/rose.jpg", __FILE__)
         | 
| 367 | 
            +
                  @field.value = path
         | 
| 368 | 
            +
                  @instance.save
         | 
| 369 | 
            +
                  @field.blank?.must_equal false
         | 
| 370 | 
            +
                  @field.original.blank?.must_equal false
         | 
| 371 | 
            +
                  @field.smaller.blank?.must_equal false
         | 
| 372 | 
            +
                end
         | 
| 373 | 
            +
             | 
| 374 | 
            +
                describe 'with cloud storage' do
         | 
| 375 | 
            +
                  before do
         | 
| 376 | 
            +
                    @bucket_name = "media.example.com"
         | 
| 377 | 
            +
                    @aws_credentials = {
         | 
| 378 | 
            +
                      :provider=>"AWS",
         | 
| 379 | 
            +
                      :aws_secret_access_key=>"SECRET_ACCESS_KEY",
         | 
| 380 | 
            +
                      :aws_access_key_id=>"ACCESS_KEY_ID",
         | 
| 381 | 
            +
                      :public_host => "http://media.example.com"
         | 
| 382 | 
            +
                    }
         | 
| 383 | 
            +
                    ::Fog.mock!
         | 
| 384 | 
            +
                    @storage = Spontaneous::Media::Store::Cloud.new("S3", @aws_credentials, 'media.example.com')
         | 
| 385 | 
            +
                    @storage.backend.directories.create(:key => @bucket_name)
         | 
| 386 | 
            +
                    @site.storage_backends.unshift(@storage)
         | 
| 387 | 
            +
                  end
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                  it 'returns true for empty images' do
         | 
| 390 | 
            +
                    @field.blank?.must_equal true
         | 
| 391 | 
            +
                    @field.original.blank?.must_equal true
         | 
| 392 | 
            +
                    @field.smaller.blank?.must_equal true
         | 
| 393 | 
            +
                  end
         | 
| 394 | 
            +
                  it 'returns false for images with values' do
         | 
| 395 | 
            +
                    path = File.expand_path("../../../../fixtures/images/rose.jpg", __FILE__)
         | 
| 396 | 
            +
                    @field.value = path
         | 
| 397 | 
            +
                    @instance.save
         | 
| 398 | 
            +
                    @field.blank?.must_equal false
         | 
| 399 | 
            +
                    @field.original.blank?.must_equal false
         | 
| 400 | 
            +
                    @field.smaller.blank?.must_equal false
         | 
| 401 | 
            +
                  end
         | 
| 284 402 | 
             
                end
         | 
| 285 403 | 
             
              end
         | 
| 286 404 |  | 
| @@ -306,7 +424,7 @@ describe "Images" do | |
| 306 424 | 
             
                  @content_id = 234
         | 
| 307 425 | 
             
                  @instance.stubs(:id).returns(@content_id)
         | 
| 308 426 | 
             
                  @field = @instance.photo
         | 
| 309 | 
            -
                  path = File.expand_path(" | 
| 427 | 
            +
                  path = File.expand_path("../../../../fixtures/images/rose.jpg", __FILE__)
         | 
| 310 428 | 
             
                  @field.value = path
         | 
| 311 429 | 
             
                end
         | 
| 312 430 |  |