intranet-pictures 1.0.6 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/intranet/pictures/json_db_provider.rb +41 -71
- data/lib/intranet/pictures/responder.rb +127 -89
- data/lib/intranet/pictures/version.rb +1 -1
- data/lib/intranet/resources/haml/pictures_browse.haml +8 -8
- data/lib/intranet/resources/haml/pictures_home.haml +18 -19
- data/lib/intranet/resources/locales/en.yml +0 -1
- data/lib/intranet/resources/locales/fr.yml +0 -1
- data/lib/intranet/resources/www/jpictures.js +32 -14
- data/lib/intranet/resources/www/photoswipe/photoswipe-dynamic-caption-plugin.css +47 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe-dynamic-caption-plugin.esm.js +400 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe-lightbox.esm.js +1382 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe-lightbox.esm.js.map +1 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe-lightbox.esm.min.js +5 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe.css +383 -142
- data/lib/intranet/resources/www/photoswipe/photoswipe.esm.js +5279 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe.esm.js.map +1 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe.esm.min.js +5 -0
- data/lib/intranet/resources/www/style.css +13 -0
- data/spec/intranet/pictures/json_db_provider_spec.rb +52 -147
- data/spec/intranet/pictures/responder_spec.rb +176 -191
- data/spec/intranet/pictures/sample-db.json +28 -38
- data/spec/spec_helper.rb +6 -8
- metadata +26 -28
- data/lib/intranet/resources/haml/pictures_photoswipe.haml +0 -23
- data/lib/intranet/resources/www/photoswipe/LICENSE +0 -21
- data/lib/intranet/resources/www/photoswipe/default-skin/default-skin.css +0 -484
- data/lib/intranet/resources/www/photoswipe/default-skin/default-skin.png +0 -0
- data/lib/intranet/resources/www/photoswipe/default-skin/default-skin.svg +0 -1
- data/lib/intranet/resources/www/photoswipe/default-skin/preloader.gif +0 -0
- data/lib/intranet/resources/www/photoswipe/photoswipe-ui-default.js +0 -861
- data/lib/intranet/resources/www/photoswipe/photoswipe-ui-default.min.js +0 -4
- data/lib/intranet/resources/www/photoswipe/photoswipe.js +0 -3734
- data/lib/intranet/resources/www/photoswipe/photoswipe.min.js +0 -4
@@ -48,54 +48,11 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
describe '#css_dependencies' do
|
52
|
-
it 'should return the list of CSS dependencies' do
|
53
|
-
expect(@responder.css_dependencies).to include(
|
54
|
-
'design/style.css',
|
55
|
-
'design/photoswipe/photoswipe.css',
|
56
|
-
'design/photoswipe/default-skin/default-skin.css'
|
57
|
-
)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe '#js_dependencies' do
|
62
|
-
it 'should return the list of JavaScript dependencies' do
|
63
|
-
expect(@responder.js_dependencies).to include(
|
64
|
-
'design/jpictures.js',
|
65
|
-
'design/photoswipe/photoswipe.min.js',
|
66
|
-
'design/photoswipe/photoswipe-ui-default.min.js'
|
67
|
-
)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
51
|
describe '#generate_page' do
|
72
|
-
def photoswipe_markup # rubocop:disable Metrics/MethodLength
|
73
|
-
"<div aria-hidden class='pswp' role='dialog' tabindex='-1'>\n" \
|
74
|
-
"<div class='pswp__bg'></div>\n" \
|
75
|
-
"<div class='pswp__scroll-wrap'>\n" \
|
76
|
-
"<div class='pswp__container'>\n" \
|
77
|
-
"<div class='pswp__item'></div>\n" \
|
78
|
-
"<div class='pswp__item'></div>\n" \
|
79
|
-
"<div class='pswp__item'></div>\n" \
|
80
|
-
"</div>\n" \
|
81
|
-
"<div class='pswp__ui pswp__ui--hidden'>\n" \
|
82
|
-
"<div class='pswp__top-bar'>\n" \
|
83
|
-
"<div class='pswp__counter'></div>\n" \
|
84
|
-
"<button class='pswp__button pswp__button--close' title='#{I18n.t('pictures.viewer.close')} (Esc)'></button>\n" \
|
85
|
-
"<button class='pswp__button pswp__button--fs' title='#{I18n.t('pictures.viewer.fullscreen')}'></button>\n" \
|
86
|
-
"<button class='pswp__button pswp__button--zoom' title='#{I18n.t('pictures.viewer.zoom')}'></button>\n" \
|
87
|
-
"<div class='pswp__preloader'>\n<div class='pswp__preloader__icn'>\n<div class='pswp__preloader__cut'>\n<div class='pswp__preloader__donut'></div>\n</div>\n</div>\n</div>\n</div>\n" \
|
88
|
-
"<div class='pswp__share-modal pswp__share-modal--hidden pswp__single-tap'>\n<div class='pswp__share-tooltip'></div>\n</div>\n" \
|
89
|
-
"<button class='pswp__button pswp__button--arrow--left' title='#{I18n.t('pictures.viewer.previous')}'></button>\n" \
|
90
|
-
"<button class='pswp__button pswp__button--arrow--right' title='#{I18n.t('pictures.viewer.next')}'></button>\n" \
|
91
|
-
"<div class='pswp__caption'>\n<div class='pswp__caption__center'></div>\n</div>\n" \
|
92
|
-
"</div>\n</div>\n</div>\n\n"
|
93
|
-
end
|
94
|
-
|
95
52
|
context 'when asked for \'/index.html\'' do
|
96
53
|
it 'should return a partial HTML content showing recent groups according to configuration' do
|
97
54
|
# Nominal case with limit
|
98
|
-
recents = [{
|
55
|
+
recents = [{ 'group_by' => 'location', 'sort_by' => 'datetime', 'sort_order' => 'desc', 'limit' => 2 }]
|
99
56
|
@responder.instance_variable_set(:@recents, recents)
|
100
57
|
code, mime, content = @responder.generate_page('/index.html', {})
|
101
58
|
expect(code).to eql(206)
|
@@ -108,19 +65,25 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
108
65
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
109
66
|
"<li>My Gallery</li>\n" \
|
110
67
|
"</ul>\n\n" \
|
111
|
-
"<h3>#{I18n.t('pictures.recents.
|
68
|
+
"<h3>#{I18n.t('pictures.recents.location')}</h3>\n" \
|
112
69
|
"<ul class='groups'>\n" \
|
113
|
-
"<li title='
|
114
|
-
"<li title='
|
70
|
+
"<li title='New York, USA'>\n<a onclick='openImagesGallery("location=New York, USA&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=New York, USA")'></div>\n<figcaption>\nNew York, USA\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
71
|
+
"<li title='Paris, France'>\n<a onclick='openImagesGallery("location=Paris, France&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
115
72
|
"</ul>\n" \
|
116
|
-
"<p class='see_more'>\n<a href='
|
117
|
-
"</section>\n"
|
118
|
-
title: 'My Gallery'
|
73
|
+
"<p class='see_more'>\n<a href='browse.html?group_by=location&sort_by=datetime&sort_order=desc'>#{I18n.t('pictures.see_more')}</a>\n</p>\n" \
|
74
|
+
"</section>\n",
|
75
|
+
title: 'My Gallery',
|
76
|
+
stylesheets: [
|
77
|
+
'design/style.css',
|
78
|
+
'design/photoswipe/photoswipe.css',
|
79
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
80
|
+
],
|
81
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
119
82
|
}
|
120
83
|
)
|
121
84
|
|
122
85
|
# Nominal case with limit
|
123
|
-
recents = [{
|
86
|
+
recents = [{ 'group_by' => 'location', 'sort_by' => 'datetime', 'limit' => 2 }]
|
124
87
|
@responder.instance_variable_set(:@recents, recents)
|
125
88
|
code, mime, content = @responder.generate_page('/index.html', {})
|
126
89
|
expect(code).to eql(206)
|
@@ -133,19 +96,25 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
133
96
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
134
97
|
"<li>My Gallery</li>\n" \
|
135
98
|
"</ul>\n\n" \
|
136
|
-
"<h3>#{I18n.t('pictures.recents.
|
99
|
+
"<h3>#{I18n.t('pictures.recents.location')}</h3>\n" \
|
137
100
|
"<ul class='groups'>\n" \
|
138
|
-
"<li title='
|
139
|
-
"<li title='
|
101
|
+
"<li title='Paris, France'>\n<a onclick='openImagesGallery("location=Paris, France&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
102
|
+
"<li title='Tokyo, Japan'>\n<a onclick='openImagesGallery("location=Tokyo, Japan&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Tokyo, Japan")'></div>\n<figcaption>\nTokyo, Japan\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
140
103
|
"</ul>\n" \
|
141
|
-
"<p class='see_more'>\n<a href='
|
142
|
-
"</section>\n"
|
143
|
-
title: 'My Gallery'
|
104
|
+
"<p class='see_more'>\n<a href='browse.html?group_by=location&sort_by=datetime'>#{I18n.t('pictures.see_more')}</a>\n</p>\n" \
|
105
|
+
"</section>\n",
|
106
|
+
title: 'My Gallery',
|
107
|
+
stylesheets: [
|
108
|
+
'design/style.css',
|
109
|
+
'design/photoswipe/photoswipe.css',
|
110
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
111
|
+
],
|
112
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
144
113
|
}
|
145
114
|
)
|
146
115
|
|
147
116
|
# Nominal case without limit
|
148
|
-
recents = [{
|
117
|
+
recents = [{ 'group_by' => 'location', 'sort_by' => 'location', 'sort_order' => 'desc' }]
|
149
118
|
@responder.instance_variable_set(:@recents, recents)
|
150
119
|
code, mime, content = @responder.generate_page('/index.html', {})
|
151
120
|
expect(code).to eql(206)
|
@@ -158,19 +127,25 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
158
127
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
159
128
|
"<li>My Gallery</li>\n" \
|
160
129
|
"</ul>\n\n" \
|
161
|
-
"<h3>#{I18n.t('pictures.recents.
|
130
|
+
"<h3>#{I18n.t('pictures.recents.location')}</h3>\n" \
|
162
131
|
"<ul class='groups'>\n" \
|
163
|
-
"<li title='
|
164
|
-
"<li title='
|
165
|
-
"<li title='
|
132
|
+
"<li title='Tokyo, Japan'>\n<a onclick='openImagesGallery("location=Tokyo, Japan&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Tokyo, Japan")'></div>\n<figcaption>\nTokyo, Japan\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
133
|
+
"<li title='Paris, France'>\n<a onclick='openImagesGallery("location=Paris, France&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
134
|
+
"<li title='New York, USA'>\n<a onclick='openImagesGallery("location=New York, USA&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=New York, USA")'></div>\n<figcaption>\nNew York, USA\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
166
135
|
"</ul>\n" \
|
167
|
-
"</section>\n"
|
168
|
-
title: 'My Gallery'
|
136
|
+
"</section>\n",
|
137
|
+
title: 'My Gallery',
|
138
|
+
stylesheets: [
|
139
|
+
'design/style.css',
|
140
|
+
'design/photoswipe/photoswipe.css',
|
141
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
142
|
+
],
|
143
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
169
144
|
}
|
170
145
|
)
|
171
146
|
|
172
147
|
# Incorrect recents specification
|
173
|
-
recents = [{
|
148
|
+
recents = [{ 'group_by' => 'invalid', 'sort_by' => 'location' }]
|
174
149
|
@responder.instance_variable_set(:@recents, recents)
|
175
150
|
code, mime, content = @responder.generate_page('/index.html', {})
|
176
151
|
expect(code).to eql(404)
|
@@ -180,7 +155,8 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
180
155
|
|
181
156
|
it 'should return a partial HTML content showing all groups according to configuration' do
|
182
157
|
# Nominal case without recents
|
183
|
-
home_groups = [{
|
158
|
+
home_groups = [{ 'group_by' => 'location', 'sort_by' => 'location',
|
159
|
+
'browse_group_by' => 'author' }]
|
184
160
|
@responder.instance_variable_set(:@home_groups, home_groups)
|
185
161
|
code, mime, content = @responder.generate_page('/index.html', {})
|
186
162
|
expect(code).to eql(206)
|
@@ -193,21 +169,28 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
193
169
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
194
170
|
"<li>My Gallery</li>\n" \
|
195
171
|
"</ul>\n\n" \
|
196
|
-
"<h3>#{I18n.t('pictures.browse_by.
|
172
|
+
"<h3>#{I18n.t('pictures.browse_by.location')}</h3>\n" \
|
197
173
|
"<ul class='groups wide'>\n" \
|
198
|
-
"<li title='
|
199
|
-
"<li title='
|
200
|
-
"<li title='
|
174
|
+
"<li title='New York, USA'>\n<a href='browse.html?group_by=author&location=New York, USA'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=New York, USA")'></div>\n<figcaption>\nNew York, USA\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
175
|
+
"<li title='Paris, France'>\n<a href='browse.html?group_by=author&location=Paris, France'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
176
|
+
"<li title='Tokyo, Japan'>\n<a href='browse.html?group_by=author&location=Tokyo, Japan'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Tokyo, Japan")'></div>\n<figcaption>\nTokyo, Japan\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
201
177
|
"</ul>\n" \
|
202
178
|
"</section>\n",
|
203
|
-
title: 'My Gallery'
|
179
|
+
title: 'My Gallery',
|
180
|
+
stylesheets: [
|
181
|
+
'design/style.css',
|
182
|
+
'design/photoswipe/photoswipe.css',
|
183
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
184
|
+
],
|
185
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
204
186
|
}
|
205
187
|
)
|
206
188
|
|
207
189
|
# Nominal case with recents
|
208
|
-
recents = [{
|
190
|
+
recents = [{ 'group_by' => 'location', 'sort_by' => 'location', 'sort_order' => 'asc' }]
|
209
191
|
@responder.instance_variable_set(:@recents, recents)
|
210
|
-
home_groups = [{
|
192
|
+
home_groups = [{ 'group_by' => 'author', 'sort_by' => 'author', 'sort_order' => 'asc',
|
193
|
+
'browse_group_by' => 'location', 'browse_sort_by' => 'location', 'browse_sort_order' => 'desc' }]
|
211
194
|
@responder.instance_variable_set(:@home_groups, home_groups)
|
212
195
|
code, mime, content = @responder.generate_page('/index.html', {})
|
213
196
|
expect(code).to eql(206)
|
@@ -220,29 +203,35 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
220
203
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
221
204
|
"<li>My Gallery</li>\n" \
|
222
205
|
"</ul>\n\n" \
|
223
|
-
"<h3>#{I18n.t('pictures.recents.
|
206
|
+
"<h3>#{I18n.t('pictures.recents.location')}</h3>\n" \
|
224
207
|
"<ul class='groups'>\n" \
|
225
|
-
"<li title='
|
226
|
-
"<li title='
|
227
|
-
"<li title='
|
208
|
+
"<li title='New York, USA'>\n<a onclick='openImagesGallery("location=New York, USA&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=New York, USA")'></div>\n<figcaption>\nNew York, USA\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
209
|
+
"<li title='Paris, France'>\n<a onclick='openImagesGallery("location=Paris, France&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
210
|
+
"<li title='Tokyo, Japan'>\n<a onclick='openImagesGallery("location=Tokyo, Japan&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Tokyo, Japan")'></div>\n<figcaption>\nTokyo, Japan\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
228
211
|
"</ul>\n" \
|
229
|
-
"<h3>#{I18n.t('pictures.browse_by.
|
212
|
+
"<h3>#{I18n.t('pictures.browse_by.author')}</h3>\n" \
|
230
213
|
"<ul class='groups wide'>\n" \
|
231
|
-
"<li title='
|
232
|
-
"<li title='
|
214
|
+
"<li title='Jane Doe'>\n<a href='browse.html?group_by=location&sort_by=location&sort_order=desc&author=Jane Doe'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?author=Jane Doe")'></div>\n<figcaption>\nJane Doe\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
215
|
+
"<li title='John Doe'>\n<a href='browse.html?group_by=location&sort_by=location&sort_order=desc&author=John Doe'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?author=John Doe")'></div>\n<figcaption>\nJohn Doe\n<br>\n<em>Best photographer ever</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
233
216
|
"</ul>\n" \
|
234
|
-
"</section>\n"
|
235
|
-
title: 'My Gallery'
|
217
|
+
"</section>\n",
|
218
|
+
title: 'My Gallery',
|
219
|
+
stylesheets: [
|
220
|
+
'design/style.css',
|
221
|
+
'design/photoswipe/photoswipe.css',
|
222
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
223
|
+
],
|
224
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
236
225
|
}
|
237
226
|
)
|
238
227
|
end
|
239
228
|
end
|
240
229
|
|
241
|
-
context 'when asked for \'/
|
242
|
-
it 'should return a partial HTML content with selected
|
243
|
-
#
|
244
|
-
query = {}
|
245
|
-
code, mime, content = @responder.generate_page('/
|
230
|
+
context 'when asked for \'/browse.html\'' do
|
231
|
+
it 'should return a partial HTML content with selected pictures grouped as requested' do
|
232
|
+
# No selector nor sort order
|
233
|
+
query = { 'group_by' => 'author' }
|
234
|
+
code, mime, content = @responder.generate_page('/browse.html', query)
|
246
235
|
expect(code).to eql(206)
|
247
236
|
expect(mime).to eql('text/html')
|
248
237
|
expect(content).to eql(
|
@@ -252,20 +241,26 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
252
241
|
"<li>\n<a href='/index.html'>#{I18n.t('nav.home')}</a>\n</li>\n" \
|
253
242
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
254
243
|
"<li>\n<a href='index.html'>My Gallery</a>\n</li>\n" \
|
255
|
-
"<li>#{I18n.t('pictures.nav.
|
244
|
+
"<li>#{I18n.t('pictures.nav.author')}</li>\n" \
|
256
245
|
"</ul>\n\n" \
|
257
246
|
"<ul class='groups'>\n" \
|
258
|
-
"<li title='
|
259
|
-
"<li title='
|
247
|
+
"<li title='John Doe'>\n<a onclick='openImagesGallery("author=John Doe&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?author=John Doe")'></div>\n<figcaption>\nJohn Doe\n<br>\n<em>Best photographer ever</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
248
|
+
"<li title='Jane Doe'>\n<a onclick='openImagesGallery("author=Jane Doe&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?author=Jane Doe")'></div>\n<figcaption>\nJane Doe\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
260
249
|
"</ul>\n" \
|
261
|
-
"</section>\n"
|
262
|
-
title: 'My Gallery'
|
250
|
+
"</section>\n",
|
251
|
+
title: 'My Gallery',
|
252
|
+
stylesheets: [
|
253
|
+
'design/style.css',
|
254
|
+
'design/photoswipe/photoswipe.css',
|
255
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
256
|
+
],
|
257
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
263
258
|
}
|
264
259
|
)
|
265
260
|
|
266
|
-
#
|
267
|
-
query = { '
|
268
|
-
code, mime, content = @responder.generate_page('/
|
261
|
+
# Valid selector, valid sort order
|
262
|
+
query = { 'group_by' => 'location', 'author' => 'John Doe', 'sort_by' => 'location', 'sort_order' => 'desc' }
|
263
|
+
code, mime, content = @responder.generate_page('/browse.html', query)
|
269
264
|
expect(code).to eql(206)
|
270
265
|
expect(mime).to eql('text/html')
|
271
266
|
expect(content).to eql(
|
@@ -275,20 +270,26 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
275
270
|
"<li>\n<a href='/index.html'>#{I18n.t('nav.home')}</a>\n</li>\n" \
|
276
271
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
277
272
|
"<li>\n<a href='index.html'>My Gallery</a>\n</li>\n" \
|
278
|
-
"<li>#{I18n.t('pictures.nav.
|
273
|
+
"<li>#{I18n.t('pictures.nav.location')} (John Doe)</li>\n" \
|
279
274
|
"</ul>\n\n" \
|
280
275
|
"<ul class='groups'>\n" \
|
281
|
-
"<li title='
|
282
|
-
"<li title='
|
276
|
+
"<li title='Tokyo, Japan'>\n<a onclick='openImagesGallery("author=John Doe&location=Tokyo, Japan&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Tokyo, Japan")'></div>\n<figcaption>\nTokyo, Japan\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
277
|
+
"<li title='Paris, France'>\n<a onclick='openImagesGallery("author=John Doe&location=Paris, France&sort_by=datetime");'>\n<figure>\n<div style='background-image: url("api/group_thumbnail?location=Paris, France")'></div>\n<figcaption>\nParis, France\n<br>\n<em>The City of Light</em>\n</figcaption>\n</figure>\n</a>\n</li>\n" \
|
283
278
|
"</ul>\n" \
|
284
|
-
"</section>\n"
|
285
|
-
title: 'My Gallery'
|
279
|
+
"</section>\n",
|
280
|
+
title: 'My Gallery',
|
281
|
+
stylesheets: [
|
282
|
+
'design/style.css',
|
283
|
+
'design/photoswipe/photoswipe.css',
|
284
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
285
|
+
],
|
286
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
286
287
|
}
|
287
288
|
)
|
288
289
|
|
289
290
|
# Invalid selector
|
290
|
-
query = { 'foo' => 'bar' }
|
291
|
-
code, mime, content = @responder.generate_page('/
|
291
|
+
query = { 'group_by' => 'location', 'foo' => 'bar' }
|
292
|
+
code, mime, content = @responder.generate_page('/browse.html', query)
|
292
293
|
expect(code).to eql(206)
|
293
294
|
expect(mime).to eql('text/html')
|
294
295
|
expect(content).to eql(
|
@@ -298,120 +299,104 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
298
299
|
"<li>\n<a href='/index.html'>#{I18n.t('nav.home')}</a>\n</li>\n" \
|
299
300
|
"<li>#{I18n.t('pictures.menu')}</li>\n" \
|
300
301
|
"<li>\n<a href='index.html'>My Gallery</a>\n</li>\n" \
|
301
|
-
"<li>#{I18n.t('pictures.nav.
|
302
|
+
"<li>#{I18n.t('pictures.nav.location')} (bar)</li>\n" \
|
302
303
|
"</ul>\n\n" \
|
303
304
|
"<ul class='groups'>\n</ul>\n" \
|
304
|
-
"</section>\n"
|
305
|
-
title: 'My Gallery'
|
305
|
+
"</section>\n",
|
306
|
+
title: 'My Gallery',
|
307
|
+
stylesheets: [
|
308
|
+
'design/style.css',
|
309
|
+
'design/photoswipe/photoswipe.css',
|
310
|
+
'design/photoswipe/photoswipe-dynamic-caption-plugin.css'
|
311
|
+
],
|
312
|
+
scripts: [{ src: 'design/jpictures.js', type: 'module' }]
|
306
313
|
}
|
307
314
|
)
|
308
315
|
|
309
|
-
# Invalid
|
310
|
-
|
316
|
+
# Invalid grouping criteria
|
317
|
+
query = { 'group_by' => 'foo' }
|
318
|
+
code, mime, content = @responder.generate_page('/browse.html', query)
|
311
319
|
expect(code).to eql(404)
|
312
320
|
expect(mime).to be_empty
|
313
321
|
expect(content).to be_empty
|
314
322
|
|
315
|
-
# Invalid
|
316
|
-
query = { 'sort_order' => 'foo' }
|
317
|
-
code, mime, content = @responder.generate_page('/
|
323
|
+
# Invalid sorting criteria
|
324
|
+
query = { 'group_by' => 'location', 'sort_order' => 'foo' }
|
325
|
+
code, mime, content = @responder.generate_page('/browse.html', query)
|
318
326
|
expect(code).to eql(404)
|
319
327
|
expect(mime).to be_empty
|
320
328
|
expect(content).to be_empty
|
321
329
|
end
|
322
330
|
end
|
323
331
|
|
324
|
-
context 'when asked for \'/
|
325
|
-
it 'should return
|
326
|
-
|
327
|
-
query = {}
|
328
|
-
code, mime, content = @responder.generate_page('/api/groups/group1', query)
|
332
|
+
context 'when asked for \'/i18n.js\'' do
|
333
|
+
it 'should return the internationalized version of required JavaScript variables' do
|
334
|
+
code, mime, content = @responder.generate_page('/i18n.js', {})
|
329
335
|
expect(code).to eql(200)
|
330
|
-
expect(mime).to eql('
|
336
|
+
expect(mime).to eql('text/javascript')
|
331
337
|
expect(content).to eql(
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
338
|
+
"export default {\n" \
|
339
|
+
" viewer_close: '#{I18n.t('pictures.viewer.close')}',\n" \
|
340
|
+
" viewer_zoom: '#{I18n.t('pictures.viewer.zoom')}',\n" \
|
341
|
+
" viewer_previous: '#{I18n.t('pictures.viewer.previous')}',\n" \
|
342
|
+
" viewer_next: '#{I18n.t('pictures.viewer.next')}' };"
|
336
343
|
)
|
344
|
+
end
|
345
|
+
end
|
337
346
|
|
338
|
-
|
339
|
-
|
340
|
-
|
347
|
+
context 'when asked for \'/api/group_thumbnail\'' do
|
348
|
+
it 'should return the selected group thumnail' do
|
349
|
+
# Existing group with thumbnail
|
350
|
+
query = { 'location' => 'New York, USA' }
|
351
|
+
code, mime, content = @responder.generate_page('/api/group_thumbnail', query)
|
341
352
|
expect(code).to eql(200)
|
342
|
-
expect(mime).to eql('
|
343
|
-
expect(content).to eql(
|
344
|
-
[
|
345
|
-
{ 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' },
|
346
|
-
{ 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' }
|
347
|
-
].to_json
|
348
|
-
)
|
353
|
+
expect(mime).to eql('image/png')
|
354
|
+
expect(content).to eql(File.read(File.join(__dir__, 'alpha.png')))
|
349
355
|
|
350
|
-
# Existing group
|
351
|
-
query = { '
|
352
|
-
code, mime, content = @responder.generate_page('/api/
|
353
|
-
expect(code).to eql(200)
|
354
|
-
expect(mime).to eql('application/json')
|
355
|
-
expect(content).to eql(
|
356
|
-
[
|
357
|
-
{ 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' },
|
358
|
-
{ 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' }
|
359
|
-
].to_json
|
360
|
-
)
|
361
|
-
query = { 'group1' => 'group1_title1', 'sort_by' => 'id', 'sort_order' => 'desc' }
|
362
|
-
code, mime, content = @responder.generate_page('/api/groups/group2', query)
|
356
|
+
# Existing group with no specified thumbnail
|
357
|
+
query = { 'location' => 'Paris, France' }
|
358
|
+
code, mime, content = @responder.generate_page('/api/group_thumbnail', query)
|
363
359
|
expect(code).to eql(200)
|
364
|
-
expect(mime).to eql('
|
360
|
+
expect(mime).to eql('image/svg+xml')
|
365
361
|
expect(content).to eql(
|
366
|
-
|
367
|
-
{ 'id' => 'group2_title3', 'title' => 'Group 2, Title 3', 'value' => 'aabb' },
|
368
|
-
{ 'id' => 'group2_title2', 'title' => 'Group 2, Title 2', 'value' => 'bcde', 'brief' => 'brief_text_2' }
|
369
|
-
].to_json
|
362
|
+
File.read(File.join(__dir__, '../../../lib/intranet/resources/www/group_thumbnail.svg'))
|
370
363
|
)
|
371
364
|
|
372
|
-
#
|
373
|
-
query = { '
|
374
|
-
code, mime, content = @responder.generate_page('/api/
|
375
|
-
expect(code).to eql(200)
|
376
|
-
expect(mime).to eql('application/json')
|
377
|
-
expect(content).to eql([].to_json)
|
378
|
-
|
379
|
-
# Invalid group type
|
380
|
-
code, mime, content = @responder.generate_page('/api/groups/foo', {})
|
365
|
+
# Existing group with non-existant thumbnail
|
366
|
+
query = { 'author' => 'Jane Doe' }
|
367
|
+
code, mime, content = @responder.generate_page('/api/group_thumbnail', query)
|
381
368
|
expect(code).to eql(404)
|
382
369
|
expect(mime).to be_empty
|
383
370
|
expect(content).to be_empty
|
384
371
|
|
385
|
-
# Invalid
|
386
|
-
query = { '
|
387
|
-
code, mime, content = @responder.generate_page('/api/
|
372
|
+
# Invalid query
|
373
|
+
query = { 'location' => 'Tokyo, Japan', 'camera' => 'Canon EOS 5D MARK IV' }
|
374
|
+
code, mime, content = @responder.generate_page('/api/group_thumbnail', query)
|
388
375
|
expect(code).to eql(404)
|
389
376
|
expect(mime).to be_empty
|
390
377
|
expect(content).to be_empty
|
391
378
|
end
|
392
379
|
end
|
393
380
|
|
394
|
-
context 'when asked for \'/api/
|
395
|
-
it 'should return the selected group
|
396
|
-
# Existing group with
|
397
|
-
query = { '
|
398
|
-
code, mime, content = @responder.generate_page('/api/
|
381
|
+
context 'when asked for \'/api/group_brief\'' do
|
382
|
+
it 'should return the selected group brief text' do
|
383
|
+
# Existing group with brief text
|
384
|
+
query = { 'location' => 'Paris, France' }
|
385
|
+
code, mime, content = @responder.generate_page('/api/group_brief', query)
|
399
386
|
expect(code).to eql(200)
|
400
|
-
expect(mime).to eql('
|
401
|
-
expect(content).to eql(
|
387
|
+
expect(mime).to eql('application/json')
|
388
|
+
expect(content).to eql('The City of Light'.to_json)
|
402
389
|
|
403
|
-
# Existing group with no
|
404
|
-
query = { '
|
405
|
-
code, mime, content = @responder.generate_page('/api/
|
390
|
+
# Existing group with no brief text
|
391
|
+
query = { 'location' => 'Tokyo, Japan' }
|
392
|
+
code, mime, content = @responder.generate_page('/api/group_brief', query)
|
406
393
|
expect(code).to eql(200)
|
407
|
-
expect(mime).to eql('
|
408
|
-
expect(content).to eql(
|
409
|
-
File.read(File.join(__dir__, '../../../lib/intranet/resources/www/group_thumbnail.svg'))
|
410
|
-
)
|
394
|
+
expect(mime).to eql('application/json')
|
395
|
+
expect(content).to eql(''.to_json)
|
411
396
|
|
412
|
-
#
|
413
|
-
query = { '
|
414
|
-
code, mime, content = @responder.generate_page('/api/
|
397
|
+
# Invalid query
|
398
|
+
query = { 'location' => 'Tokyo, Japan', 'camera' => 'Canon EOS 5D MARK IV' }
|
399
|
+
code, mime, content = @responder.generate_page('/api/group_brief', query)
|
415
400
|
expect(code).to eql(404)
|
416
401
|
expect(mime).to be_empty
|
417
402
|
expect(content).to be_empty
|
@@ -426,46 +411,46 @@ RSpec.describe Intranet::Pictures::Responder do
|
|
426
411
|
expect(mime).to eql('application/json')
|
427
412
|
expect(content).to eql(
|
428
413
|
[
|
429
|
-
{ 'datetime' => '2019:07:22 09:41:31', '
|
430
|
-
{ 'datetime' => '2020:06:19 07:51:05', '
|
431
|
-
{ 'datetime' => '2020:06:20 18:14:09', '
|
432
|
-
{ 'datetime' => '2020:06:20 06:09:54', '
|
433
|
-
{ 'datetime' => '2019:07:22 09:45:17', '
|
414
|
+
{ 'datetime' => '2019:07:22 09:41:31', 'author' => 'John Doe', 'location' => 'Paris, France', 'camera' => 'Apple iPhone 11' },
|
415
|
+
{ 'datetime' => '2020:06:19 07:51:05', 'flash' => false, 'author' => 'Jane Doe', 'location' => 'Tokyo, Japan' },
|
416
|
+
{ 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' },
|
417
|
+
{ 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' },
|
418
|
+
{ 'datetime' => '2019:07:22 09:45:17', 'author' => 'John Doe', 'location' => 'Tokyo, Japan' }
|
434
419
|
].to_json
|
435
420
|
)
|
436
421
|
|
437
422
|
# Valid selector, no sort order
|
438
|
-
query = { '
|
423
|
+
query = { 'author' => 'Jane Doe', 'flash' => true }
|
439
424
|
code, mime, content = @responder.generate_page('/api/pictures', query)
|
440
425
|
expect(code).to eql(200)
|
441
426
|
expect(mime).to eql('application/json')
|
442
427
|
expect(content).to eql(
|
443
428
|
[
|
444
|
-
{ 'datetime' => '2020:06:20 18:14:09', '
|
445
|
-
{ 'datetime' => '2020:06:20 06:09:54', '
|
429
|
+
{ 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' },
|
430
|
+
{ 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' }
|
446
431
|
].to_json
|
447
432
|
)
|
448
433
|
|
449
434
|
# Valid selector, valid sort order
|
450
|
-
query = { '
|
435
|
+
query = { 'author' => 'Jane Doe', 'flash' => true, 'sort_by' => 'datetime' }
|
451
436
|
code, mime, content = @responder.generate_page('/api/pictures', query)
|
452
437
|
expect(code).to eql(200)
|
453
438
|
expect(mime).to eql('application/json')
|
454
439
|
expect(content).to eql(
|
455
440
|
[
|
456
|
-
{ 'datetime' => '2020:06:20 06:09:54', '
|
457
|
-
{ 'datetime' => '2020:06:20 18:14:09', '
|
441
|
+
{ 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' },
|
442
|
+
{ 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }
|
458
443
|
].to_json
|
459
444
|
)
|
460
|
-
query = { '
|
445
|
+
query = { 'author' => 'Jane Doe', 'flash' => true, 'sort_by' => 'location',
|
461
446
|
'sort_order' => 'desc' }
|
462
447
|
code, mime, content = @responder.generate_page('/api/pictures', query)
|
463
448
|
expect(code).to eql(200)
|
464
449
|
expect(mime).to eql('application/json')
|
465
450
|
expect(content).to eql(
|
466
451
|
[
|
467
|
-
{ 'datetime' => '2020:06:20 06:09:54', '
|
468
|
-
{ 'datetime' => '2020:06:20 18:14:09', '
|
452
|
+
{ 'datetime' => '2020:06:20 06:09:54', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'Paris, France', 'camera' => 'Canon EOS 5D MARK IV' },
|
453
|
+
{ 'datetime' => '2020:06:20 18:14:09', 'flash' => true, 'author' => 'Jane Doe', 'location' => 'New York, USA' }
|
469
454
|
].to_json
|
470
455
|
)
|
471
456
|
|