refinerycms-images 1.0.11 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/refinery/admin/images_controller.rb +110 -0
- data/app/helpers/refinery/admin/images_helper.rb +24 -0
- data/app/models/refinery/image.rb +96 -0
- data/app/views/refinery/admin/images/_actions.html.erb +15 -0
- data/app/views/{admin → refinery/admin}/images/_existing_image.html.erb +13 -26
- data/app/views/{admin → refinery/admin}/images/_form.html.erb +11 -15
- data/app/views/{admin → refinery/admin}/images/_grid_view.html.erb +7 -5
- data/app/views/refinery/admin/images/_images.html.erb +2 -0
- data/app/views/{admin → refinery/admin}/images/_list_view.html.erb +0 -0
- data/app/views/{admin → refinery/admin}/images/_list_view_image.html.erb +7 -5
- data/app/views/refinery/admin/images/_records.html.erb +18 -0
- data/app/views/refinery/admin/images/edit.html.erb +1 -0
- data/app/views/refinery/admin/images/index.html.erb +6 -0
- data/app/views/{admin → refinery/admin}/images/insert.html.erb +10 -13
- data/app/views/refinery/admin/images/new.html.erb +1 -0
- data/config/locales/bg.yml +37 -36
- data/config/locales/cs.yml +37 -36
- data/config/locales/da.yml +37 -36
- data/config/locales/de.yml +37 -36
- data/config/locales/el.yml +37 -36
- data/config/locales/en.yml +37 -36
- data/config/locales/es.yml +38 -37
- data/config/locales/fi.yml +37 -36
- data/config/locales/fr.yml +37 -36
- data/config/locales/it.yml +47 -45
- data/config/locales/ja.yml +44 -0
- data/config/locales/ko.yml +44 -0
- data/config/locales/lt.yml +37 -36
- data/config/locales/lv.yml +37 -36
- data/config/locales/nb.yml +37 -37
- data/config/locales/nl.yml +36 -35
- data/config/locales/pl.yml +38 -37
- data/config/locales/pt-BR.yml +38 -37
- data/config/locales/rs.yml +37 -37
- data/config/locales/ru.yml +37 -36
- data/config/locales/sk.yml +37 -36
- data/config/locales/sl.yml +36 -35
- data/config/locales/sv.yml +37 -36
- data/config/locales/vi.yml +37 -36
- data/config/locales/zh-CN.yml +37 -36
- data/config/locales/zh-TW.yml +37 -36
- data/config/routes.rb +4 -7
- data/db/migrate/20100913234707_create_refinerycms_images_schema.rb +10 -18
- data/lib/generators/refinery/images/images_generator.rb +10 -0
- data/lib/generators/refinery/images/templates/config/initializers/refinery/images.rb.erb +41 -0
- data/lib/refinery/images.rb +25 -0
- data/lib/refinery/images/configuration.rb +54 -0
- data/lib/refinery/images/dragonfly.rb +54 -0
- data/lib/refinery/images/engine.rb +38 -0
- data/lib/refinery/images/validators.rb +7 -0
- data/lib/refinery/images/validators/image_size_validator.rb +19 -0
- data/lib/refinerycms-images.rb +1 -76
- data/refinerycms-images.gemspec +14 -91
- data/spec/factories/image.rb +5 -0
- data/{features/uploads → spec/fixtures}/beach.jpeg +0 -0
- data/spec/fixtures/fathead.png +0 -0
- data/spec/fixtures/image-with-dashes.jpg +0 -0
- data/spec/lib/generators/refinery/images/images_generator_spec.rb +29 -0
- data/spec/models/refinery/image_spec.rb +158 -0
- data/spec/requests/refinery/admin/images_spec.rb +103 -0
- metadata +116 -106
- data/app/controllers/admin/images_controller.rb +0 -106
- data/app/helpers/admin/images_helper.rb +0 -27
- data/app/models/image.rb +0 -116
- data/app/views/admin/images/_actions.html.erb +0 -16
- data/app/views/admin/images/_images.html.erb +0 -2
- data/app/views/admin/images/_records.html.erb +0 -18
- data/app/views/admin/images/edit.html.erb +0 -1
- data/app/views/admin/images/index.html.erb +0 -6
- data/app/views/admin/images/new.html.erb +0 -1
- data/config/locales/jp.yml +0 -43
- data/config/locales/lolcat.yml +0 -43
- data/features/manage_images.feature +0 -49
- data/features/step_definitions/image_steps.rb +0 -40
- data/features/support/factories.rb +0 -7
- data/features/support/paths.rb +0 -17
- data/features/uploads/id-rather-be-here.jpg +0 -0
- data/features/uploads/refinery_is_awesome.txt +0 -1
- data/lib/gemspec.rb +0 -38
- data/lib/generators/refinerycms_images_generator.rb +0 -8
- data/spec/models/image_spec.rb +0 -115
- data/spec/uploads/beach.jpeg +0 -0
@@ -1,106 +0,0 @@
|
|
1
|
-
module Admin
|
2
|
-
class ImagesController < Admin::BaseController
|
3
|
-
|
4
|
-
include Admin::ImagesHelper
|
5
|
-
|
6
|
-
crudify :image,
|
7
|
-
:order => "created_at DESC",
|
8
|
-
:sortable => false,
|
9
|
-
:xhr_paging => true
|
10
|
-
|
11
|
-
before_filter :change_list_mode_if_specified, :init_dialog
|
12
|
-
|
13
|
-
def new
|
14
|
-
@image = Image.new if @image.nil?
|
15
|
-
|
16
|
-
@url_override = admin_images_path(:dialog => from_dialog?)
|
17
|
-
end
|
18
|
-
|
19
|
-
# This renders the image insert dialog
|
20
|
-
def insert
|
21
|
-
self.new if @image.nil?
|
22
|
-
|
23
|
-
@url_override = admin_images_path(request.query_parameters.merge(:insert => true))
|
24
|
-
|
25
|
-
if params[:conditions].present?
|
26
|
-
extra_condition = params[:conditions].split(',')
|
27
|
-
|
28
|
-
extra_condition[1] = true if extra_condition[1] == "true"
|
29
|
-
extra_condition[1] = false if extra_condition[1] == "false"
|
30
|
-
extra_condition[1] = nil if extra_condition[1] == "nil"
|
31
|
-
end
|
32
|
-
|
33
|
-
find_all_images(({extra_condition[0].to_sym => extra_condition[1]} if extra_condition.present?))
|
34
|
-
search_all_images if searching?
|
35
|
-
|
36
|
-
paginate_images
|
37
|
-
|
38
|
-
render :action => "insert"
|
39
|
-
end
|
40
|
-
|
41
|
-
def create
|
42
|
-
@images = []
|
43
|
-
begin
|
44
|
-
unless params[:image].present? and params[:image][:image].is_a?(Array)
|
45
|
-
@images << (@image = Image.create(params[:image]))
|
46
|
-
else
|
47
|
-
params[:image][:image].each do |image|
|
48
|
-
@images << (@image = Image.create(:image => image))
|
49
|
-
end
|
50
|
-
end
|
51
|
-
rescue Dragonfly::FunctionManager::UnableToHandle
|
52
|
-
logger.warn($!.message)
|
53
|
-
@image = Image.new
|
54
|
-
end
|
55
|
-
|
56
|
-
unless params[:insert]
|
57
|
-
if @images.all?{|i| i.valid?}
|
58
|
-
flash.notice = t('created', :scope => 'refinery.crudify', :what => "'#{@images.collect{|i| i.title}.join("', '")}'")
|
59
|
-
unless from_dialog?
|
60
|
-
redirect_to :action => 'index'
|
61
|
-
else
|
62
|
-
render :text => "<script>parent.window.location = '#{admin_images_url}';</script>"
|
63
|
-
end
|
64
|
-
else
|
65
|
-
self.new # important for dialogs
|
66
|
-
render :action => 'new'
|
67
|
-
end
|
68
|
-
else
|
69
|
-
# if all uploaded images are ok redirect page back to dialog, else show current page with error
|
70
|
-
if @images.all?{|i| i.valid?}
|
71
|
-
@image_id = @image.id if @image.persisted?
|
72
|
-
@image = nil
|
73
|
-
|
74
|
-
redirect_to request.query_parameters.merge(:action => 'insert')
|
75
|
-
else
|
76
|
-
self.insert
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
protected
|
82
|
-
|
83
|
-
def init_dialog
|
84
|
-
@app_dialog = params[:app_dialog].present?
|
85
|
-
@field = params[:field]
|
86
|
-
@update_image = params[:update_image]
|
87
|
-
@thumbnail = params[:thumbnail]
|
88
|
-
@callback = params[:callback]
|
89
|
-
@conditions = params[:conditions]
|
90
|
-
end
|
91
|
-
|
92
|
-
def paginate_images
|
93
|
-
@images = @images.paginate(:page => (@paginate_page_number ||= params[:page]),
|
94
|
-
:per_page => Image.per_page(from_dialog?, !@app_dialog))
|
95
|
-
end
|
96
|
-
|
97
|
-
def restrict_controller
|
98
|
-
super unless action_name == 'insert'
|
99
|
-
end
|
100
|
-
|
101
|
-
def store_current_location!
|
102
|
-
super unless action_name == 'insert' or from_dialog?
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
module Admin
|
2
|
-
module ImagesHelper
|
3
|
-
|
4
|
-
def image_views
|
5
|
-
RefinerySetting.find_or_set(:image_views, [:grid, :list])
|
6
|
-
end
|
7
|
-
|
8
|
-
def current_image_view
|
9
|
-
RefinerySetting.find_or_set(:preferred_image_view, :grid)
|
10
|
-
end
|
11
|
-
|
12
|
-
def other_image_views
|
13
|
-
image_views.reject {|image_view| image_view.to_s == current_image_view.to_s }
|
14
|
-
end
|
15
|
-
|
16
|
-
def change_list_mode_if_specified
|
17
|
-
if action_name == 'index' and params[:view].present? and image_views.include?(params[:view].to_sym)
|
18
|
-
RefinerySetting.set(:preferred_image_view, params[:view])
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def images_paginator(collection, dialog = false)
|
23
|
-
will_paginate collection
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
data/app/models/image.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
class Image < ActiveRecord::Base
|
4
|
-
|
5
|
-
# What is the max image size a user can upload
|
6
|
-
MAX_SIZE_IN_MB = 5
|
7
|
-
|
8
|
-
image_accessor :image
|
9
|
-
|
10
|
-
validates :image, :presence => {},
|
11
|
-
:length => { :maximum => MAX_SIZE_IN_MB.megabytes }
|
12
|
-
validates_property :mime_type, :of => :image, :in => %w(image/jpeg image/png image/gif image/tiff),
|
13
|
-
:message => :incorrect_format
|
14
|
-
|
15
|
-
# Docs for acts_as_indexed http://github.com/dougal/acts_as_indexed
|
16
|
-
acts_as_indexed :fields => [:title]
|
17
|
-
|
18
|
-
# when a dialog pops up with images, how many images per page should there be
|
19
|
-
PAGES_PER_DIALOG = 18
|
20
|
-
|
21
|
-
# when a dialog pops up with images, but that dialog has image resize options
|
22
|
-
# how many images per page should there be
|
23
|
-
PAGES_PER_DIALOG_THAT_HAS_SIZE_OPTIONS = 12
|
24
|
-
|
25
|
-
# when listing images out in the admin area, how many images should show per page
|
26
|
-
PAGES_PER_ADMIN_INDEX = 20
|
27
|
-
|
28
|
-
# allows Mass-Assignment
|
29
|
-
attr_accessible :id, :image, :image_size
|
30
|
-
|
31
|
-
delegate :size, :mime_type, :url, :width, :height, :to => :image
|
32
|
-
|
33
|
-
class << self
|
34
|
-
# How many images per page should be displayed?
|
35
|
-
def per_page(dialog = false, has_size_options = false)
|
36
|
-
if dialog
|
37
|
-
unless has_size_options
|
38
|
-
PAGES_PER_DIALOG
|
39
|
-
else
|
40
|
-
PAGES_PER_DIALOG_THAT_HAS_SIZE_OPTIONS
|
41
|
-
end
|
42
|
-
else
|
43
|
-
PAGES_PER_ADMIN_INDEX
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def user_image_sizes
|
48
|
-
RefinerySetting.find_or_set(:user_image_sizes, {
|
49
|
-
:small => '110x110>',
|
50
|
-
:medium => '225x255>',
|
51
|
-
:large => '450x450>'
|
52
|
-
}, :destroyable => false)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Get a thumbnail job object given a geometry.
|
57
|
-
def thumbnail(geometry = nil)
|
58
|
-
if geometry.is_a?(Symbol) and self.class.user_image_sizes.keys.include?(geometry)
|
59
|
-
geometry = self.class.user_image_sizes[geometry]
|
60
|
-
end
|
61
|
-
|
62
|
-
if geometry.present? && !geometry.is_a?(Symbol)
|
63
|
-
image.thumb(geometry)
|
64
|
-
else
|
65
|
-
image
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Intelligently works out dimensions for a thumbnail of this image based on the Dragonfly geometry string.
|
70
|
-
def thumbnail_dimensions(geometry)
|
71
|
-
geometry = geometry.to_s
|
72
|
-
width = original_width = self.image_width.to_f
|
73
|
-
height = original_height = self.image_height.to_f
|
74
|
-
geometry_width, geometry_height = geometry.to_s.split(%r{\#{1,2}|\+|>|!|x}im)[0..1].map(&:to_f)
|
75
|
-
if (original_width * original_height > 0) && geometry =~ ::Dragonfly::ImageMagick::Processor::THUMB_GEOMETRY
|
76
|
-
if geometry =~ ::Dragonfly::ImageMagick::Processor::RESIZE_GEOMETRY
|
77
|
-
if geometry !~ %r{\d+x\d+>} || (geometry =~ %r{\d+x\d+>} && (width > geometry_width.to_f || height > geometry_height.to_f))
|
78
|
-
# Try scaling with width factor first. (wf = width factor)
|
79
|
-
wf_width = (original_width * (geometry_width / width)).ceil
|
80
|
-
wf_height = (original_height * (geometry_width / width)).ceil
|
81
|
-
|
82
|
-
# Scale with height factor (hf = height factor)
|
83
|
-
hf_width = (original_width * (geometry_height / height)).ceil
|
84
|
-
hf_height = (original_height * (geometry_height / height)).ceil
|
85
|
-
|
86
|
-
# Take the highest value that doesn't exceed either axis limit.
|
87
|
-
use_wf = wf_width <= geometry_width && wf_height <= geometry_height
|
88
|
-
if use_wf && hf_width <= geometry_width && hf_height <= geometry_height
|
89
|
-
use_wf = wf_width * wf_height > hf_width * hf_height
|
90
|
-
end
|
91
|
-
|
92
|
-
if use_wf
|
93
|
-
width = wf_width
|
94
|
-
height = wf_height
|
95
|
-
else
|
96
|
-
width = hf_width
|
97
|
-
height = hf_height
|
98
|
-
end
|
99
|
-
end
|
100
|
-
else
|
101
|
-
# cropping
|
102
|
-
width = geometry_width
|
103
|
-
height = geometry_height
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
{:width => width.to_i, :height => height.to_i}
|
108
|
-
end
|
109
|
-
|
110
|
-
# Returns a titleized version of the filename
|
111
|
-
# my_file.jpg returns My File
|
112
|
-
def title
|
113
|
-
CGI::unescape(image_name.to_s).gsub(/\.\w+$/, '').titleize
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
<ul>
|
2
|
-
<li>
|
3
|
-
<%= render :partial => "/shared/admin/search", :locals => {:url => admin_images_url} %>
|
4
|
-
</li>
|
5
|
-
<li>
|
6
|
-
<%= link_to t('.create_new_image'), new_admin_image_path(:dialog => true, :width => 600, :height => 300),
|
7
|
-
:class => "add_icon" %>
|
8
|
-
</li>
|
9
|
-
<% other_image_views.each do |image_view| %>
|
10
|
-
<li>
|
11
|
-
<%= link_to t('switch_to', :scope => 'admin.images.index.view', :view_name => t("#{image_view}", :scope => 'admin.images.index.view')),
|
12
|
-
admin_images_path(:view => image_view, :page => params[:page]),
|
13
|
-
:class => "reorder_icon" %>
|
14
|
-
</li>
|
15
|
-
<% end %>
|
16
|
-
</ul>
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<% if searching? %>
|
2
|
-
<h2><%= t('results_for', :scope => 'shared.admin.search', :query => params[:search]) %></h2>
|
3
|
-
<% end %>
|
4
|
-
<% if @images.any? %>
|
5
|
-
<div class='pagination_container'>
|
6
|
-
<%= render :partial => 'images' %>
|
7
|
-
</div>
|
8
|
-
<% else %>
|
9
|
-
<p>
|
10
|
-
<% unless searching? %>
|
11
|
-
<strong>
|
12
|
-
<%= t('.no_images_yet') %>
|
13
|
-
</strong>
|
14
|
-
<% else %>
|
15
|
-
<%= t('no_results', :scope => 'shared.admin.search') %>
|
16
|
-
<% end %>
|
17
|
-
</p>
|
18
|
-
<% end %>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= render :partial => "form" %>
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= render :partial => "/admin/images/form" %>
|
data/config/locales/jp.yml
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
jp:
|
2
|
-
plugins:
|
3
|
-
refinery_images:
|
4
|
-
title: 画像
|
5
|
-
description: 画像の編集
|
6
|
-
admin:
|
7
|
-
images:
|
8
|
-
delete: この画像を削除
|
9
|
-
edit: 画像を編集
|
10
|
-
form:
|
11
|
-
image: 画像
|
12
|
-
use_current_image: この画像を使用する
|
13
|
-
or: または
|
14
|
-
replace_image: " この画像と差し替える"
|
15
|
-
current_image: 選択されている画像
|
16
|
-
maximum_image_size: '画像は最大で %{megabytes}MB までです。'
|
17
|
-
actions:
|
18
|
-
create_new_image: 画像を追加する
|
19
|
-
records:
|
20
|
-
no_images_yet: まだ画像はありません。「画像を追加する」をクリックして下さい。
|
21
|
-
index:
|
22
|
-
view:
|
23
|
-
switch_to: '%{view_name}表示に切り替え'
|
24
|
-
list: リスト
|
25
|
-
grid: グリッド
|
26
|
-
grid_view:
|
27
|
-
view_live_html: 'この画像を<br/><em>新しいウィンドウで開く</em>'
|
28
|
-
existing_image:
|
29
|
-
button_text: 挿入
|
30
|
-
resize_image: サイズ変更
|
31
|
-
size: サイズ
|
32
|
-
insert:
|
33
|
-
existing_image: ライブラリ
|
34
|
-
new_image: アップロード
|
35
|
-
activerecord:
|
36
|
-
models:
|
37
|
-
image: 画像
|
38
|
-
errors:
|
39
|
-
models:
|
40
|
-
image:
|
41
|
-
blank: アップロードする画像を選択して下さい。
|
42
|
-
too_long: '画像は最大で%{count}までです。'
|
43
|
-
incorrect_format: '使用出来る画像のフォーマットはJPG、GIFまたはPNGです。'
|
data/config/locales/lolcat.yml
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
lolcat:
|
2
|
-
plugins:
|
3
|
-
refinery_images:
|
4
|
-
title: IMAGEZ
|
5
|
-
description: MANAGE IMAGEZ
|
6
|
-
admin:
|
7
|
-
images:
|
8
|
-
delete: REMOOV DIS IMAGE FOREVR
|
9
|
-
edit: EDIT DIS IMAGE
|
10
|
-
form:
|
11
|
-
image: IMAGE
|
12
|
-
use_current_image: USE CURRENT IMAGE
|
13
|
-
or: OR
|
14
|
-
replace_image: " REPLACE IT WIF DIS WAN..."
|
15
|
-
current_image: CURRENT IMAGE
|
16
|
-
maximum_image_size: TEH MAXIMUM IMAGE SIZE IZ %{megabytes} MEGABYTEZ.
|
17
|
-
actions:
|
18
|
-
create_new_image: ADD NEW IMAGE
|
19
|
-
records:
|
20
|
-
no_images_yet: THAR R NO IMAGEZ YET. CLICK "ADD NEW IMAGE" 2 ADD UR FURST IMAGE.
|
21
|
-
index:
|
22
|
-
view:
|
23
|
-
switch_to: SWITCH 2 %{view_name} VIEW
|
24
|
-
list: LIST
|
25
|
-
grid: GRID
|
26
|
-
grid_view:
|
27
|
-
view_live_html: VIEW DIS IMAGE <BR/><EM>OPENS IN NEW WINDOW</EM>
|
28
|
-
existing_image:
|
29
|
-
button_text: INSERT
|
30
|
-
resize_image: RESIZE TEH IMAGE?
|
31
|
-
size: SIZE
|
32
|
-
insert:
|
33
|
-
existing_image: EXISTIN IMAGE
|
34
|
-
new_image: NEW IMAGE
|
35
|
-
activerecord:
|
36
|
-
models:
|
37
|
-
image: IMAGE
|
38
|
-
errors:
|
39
|
-
models:
|
40
|
-
image:
|
41
|
-
blank: U MUST SPECIFY AN IMAGE 4 UPLOAD
|
42
|
-
too_long: IMAGE SHUD BE SMALLR THAN %{count} IN SIZE
|
43
|
-
incorrect_format: UR IMAGE MUST BE EITHR JPG, PNG OR GIF
|
@@ -1,49 +0,0 @@
|
|
1
|
-
@refinerycms @images @images-manage
|
2
|
-
Feature: Manage Images
|
3
|
-
In order to control the content on my website
|
4
|
-
As an administrator
|
5
|
-
I want to create and manage images
|
6
|
-
|
7
|
-
Background:
|
8
|
-
Given I am a logged in refinery user
|
9
|
-
And I have no images
|
10
|
-
|
11
|
-
@images-valid @valid
|
12
|
-
Scenario: Create Valid Image
|
13
|
-
When I go to the list of images
|
14
|
-
And I follow "Add new image"
|
15
|
-
And I attach the image at "beach.jpeg"
|
16
|
-
And I press "Save"
|
17
|
-
Then the image "beach.jpeg" should have uploaded successfully
|
18
|
-
And I should have 1 image
|
19
|
-
And the image should have size "254718"
|
20
|
-
And the image should have width "500"
|
21
|
-
And the image should have height "375"
|
22
|
-
And the image should have mime_type "image/jpeg"
|
23
|
-
|
24
|
-
@images-invalid @invalid
|
25
|
-
Scenario: Create Invalid Image (format)
|
26
|
-
When I go to the list of images
|
27
|
-
And I follow "Add new image"
|
28
|
-
And I upload the image at "refinery_is_awesome.txt"
|
29
|
-
And I press "Save"
|
30
|
-
Then I should not see "successfully added"
|
31
|
-
And I should have 0 images
|
32
|
-
|
33
|
-
@images-edit @edit
|
34
|
-
Scenario: Edit Existing Image
|
35
|
-
When I upload the image at "beach.jpeg"
|
36
|
-
And I go to the list of images
|
37
|
-
And I follow "Edit this image"
|
38
|
-
And I attach the image at "id-rather-be-here.jpg"
|
39
|
-
And I press "Save"
|
40
|
-
Then I should see "'Id Rather Be Here' was successfully updated."
|
41
|
-
And I should have 1 image
|
42
|
-
|
43
|
-
@images-delete @delete
|
44
|
-
Scenario: Delete Image
|
45
|
-
When I upload the image at "beach.jpeg"
|
46
|
-
When I go to the list of images
|
47
|
-
And I follow "Remove this image forever"
|
48
|
-
Then I should see "'Beach' was successfully removed."
|
49
|
-
And I should have 0 images
|