prismic.io 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +6 -14
  5. data/docs/Prismic.html +1074 -0
  6. data/docs/Prismic/API.html +2987 -0
  7. data/docs/Prismic/API/BadPrismicResponseError.html +147 -0
  8. data/docs/Prismic/API/OAuth.html +560 -0
  9. data/docs/Prismic/API/PrismicWSAuthError.html +375 -0
  10. data/docs/Prismic/API/PrismicWSConnectionError.html +221 -0
  11. data/docs/Prismic/BasicNullCache.html +255 -0
  12. data/docs/Prismic/DefaultHTTPClient.html +350 -0
  13. data/docs/Prismic/Document.html +873 -0
  14. data/docs/Prismic/Error.html +418 -0
  15. data/docs/Prismic/Experiment.html +633 -0
  16. data/docs/Prismic/Experiments.html +633 -0
  17. data/docs/Prismic/Field.html +424 -0
  18. data/docs/Prismic/Form.html +827 -0
  19. data/docs/Prismic/Fragments.html +117 -0
  20. data/docs/Prismic/Fragments/Color.html +632 -0
  21. data/docs/Prismic/Fragments/Date.html +399 -0
  22. data/docs/Prismic/Fragments/DocumentLink.html +1048 -0
  23. data/docs/Prismic/Fragments/Embed.html +679 -0
  24. data/docs/Prismic/Fragments/FileLink.html +604 -0
  25. data/docs/Prismic/Fragments/Fragment.html +339 -0
  26. data/docs/Prismic/Fragments/GeoPoint.html +469 -0
  27. data/docs/Prismic/Fragments/Group.html +710 -0
  28. data/docs/Prismic/Fragments/GroupDocument.html +382 -0
  29. data/docs/Prismic/Fragments/Image.html +780 -0
  30. data/docs/Prismic/Fragments/Image/View.html +759 -0
  31. data/docs/Prismic/Fragments/Image/ViewDoesNotExistException.html +147 -0
  32. data/docs/Prismic/Fragments/ImageLink.html +336 -0
  33. data/docs/Prismic/Fragments/Link.html +412 -0
  34. data/docs/Prismic/Fragments/Multiple.html +513 -0
  35. data/docs/Prismic/Fragments/Number.html +401 -0
  36. data/docs/Prismic/Fragments/Select.html +349 -0
  37. data/docs/Prismic/Fragments/Separator.html +396 -0
  38. data/docs/Prismic/Fragments/Slice.html +632 -0
  39. data/docs/Prismic/Fragments/SliceZone.html +474 -0
  40. data/docs/Prismic/Fragments/StructuredText.html +664 -0
  41. data/docs/Prismic/Fragments/StructuredText/Block.html +232 -0
  42. data/docs/Prismic/Fragments/StructuredText/Block/Embed.html +367 -0
  43. data/docs/Prismic/Fragments/StructuredText/Block/Heading.html +366 -0
  44. data/docs/Prismic/Fragments/StructuredText/Block/Image.html +755 -0
  45. data/docs/Prismic/Fragments/StructuredText/Block/ListItem.html +372 -0
  46. data/docs/Prismic/Fragments/StructuredText/Block/Paragraph.html +223 -0
  47. data/docs/Prismic/Fragments/StructuredText/Block/Preformatted.html +223 -0
  48. data/docs/Prismic/Fragments/StructuredText/Block/Text.html +818 -0
  49. data/docs/Prismic/Fragments/StructuredText/BlockGroup.html +423 -0
  50. data/docs/Prismic/Fragments/StructuredText/Span.html +384 -0
  51. data/docs/Prismic/Fragments/StructuredText/Span/Em.html +213 -0
  52. data/docs/Prismic/Fragments/StructuredText/Span/Hyperlink.html +359 -0
  53. data/docs/Prismic/Fragments/StructuredText/Span/Label.html +362 -0
  54. data/docs/Prismic/Fragments/StructuredText/Span/Strong.html +213 -0
  55. data/docs/Prismic/Fragments/Text.html +396 -0
  56. data/docs/Prismic/Fragments/Timestamp.html +399 -0
  57. data/docs/Prismic/Fragments/WebLink.html +340 -0
  58. data/docs/Prismic/HtmlSerializer.html +270 -0
  59. data/docs/Prismic/JsonParser.html +1764 -0
  60. data/docs/Prismic/LinkResolver.html +399 -0
  61. data/docs/Prismic/LruCache.html +1140 -0
  62. data/docs/Prismic/Predicates.html +1630 -0
  63. data/docs/Prismic/Ref.html +643 -0
  64. data/docs/Prismic/Response.html +1159 -0
  65. data/docs/Prismic/SearchForm.html +2172 -0
  66. data/docs/Prismic/SearchForm/AuthenticationException.html +147 -0
  67. data/docs/Prismic/SearchForm/AuthorizationException.html +147 -0
  68. data/docs/Prismic/SearchForm/FormSearchException.html +147 -0
  69. data/docs/Prismic/SearchForm/NoRefSetException.html +147 -0
  70. data/docs/Prismic/SearchForm/RefNotFoundException.html +147 -0
  71. data/docs/Prismic/SearchForm/UnsupportedFormKind.html +147 -0
  72. data/docs/Prismic/Variation.html +546 -0
  73. data/docs/Prismic/WithFragments.html +1803 -0
  74. data/docs/_index.html +752 -0
  75. data/docs/class_list.html +54 -0
  76. data/docs/css/common.css +1 -0
  77. data/docs/css/full_list.css +57 -0
  78. data/docs/css/style.css +339 -0
  79. data/docs/file.README.html +180 -0
  80. data/docs/file_list.html +56 -0
  81. data/docs/frames.html +26 -0
  82. data/docs/index.html +180 -0
  83. data/docs/js/app.js +219 -0
  84. data/docs/js/full_list.js +178 -0
  85. data/docs/js/jquery.js +4 -0
  86. data/docs/method_list.html +2381 -0
  87. data/docs/top-level-namespace.html +112 -0
  88. data/lib/prismic.rb +17 -1
  89. data/lib/prismic/api.rb +31 -19
  90. data/lib/prismic/fragments/image.rb +6 -0
  91. data/lib/prismic/json_parsers.rb +2 -0
  92. data/lib/prismic/version.rb +1 -1
  93. data/spec/cache_spec.rb +12 -12
  94. data/spec/json_parsers_spec.rb +10 -5
  95. data/spec/oauth_spec.rb +3 -3
  96. data/spec/prismic_spec.rb +7 -7
  97. data/spec/responses_mocks/api.json +12 -12
  98. data/spec/responses_mocks/document.json +4 -2
  99. data/spec/responses_mocks/document_with_unknown_fragment.json +2 -0
  100. data/spec/responses_mocks/fragments.json +5 -3
  101. data/spec/responses_mocks/slices.json +2 -0
  102. data/spec/responses_mocks/structured_text_with_labels.json +2 -2
  103. data/spec/simple_search_spec.rb +55 -0
  104. metadata +103 -24
  105. data/deploy-doc.sh +0 -9
  106. data/spec/doc_spec.rb +0 -298
  107. data/spec/lesbonneschoses_spec.rb +0 -228
@@ -1,9 +0,0 @@
1
- yard && \
2
- cd doc && \
3
- rm -rf doc/phpdoc-cache-* && \
4
- git init . && \
5
- git add . && \
6
- git commit -m "Update documentation."; \
7
- git push "git@github.com:prismicio/ruby-kit.git" master:gh-pages --force && \
8
- rm -rf .git
9
-
@@ -1,298 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe 'Documentation' do
5
-
6
- describe 'api' do
7
-
8
- it 'api.get' do
9
- # startgist:983989438334c8bf7967:prismic-api.rb
10
- api = Prismic.api('https://lesbonneschoses.cdn.wroom.io/api')
11
- # endgist
12
- api.should_not be_nil
13
- end
14
-
15
- it 'apiPrivate' do
16
- expect {
17
- # startgist:efecc8f60b1f69bada81:prismic-apiPrivate.rb
18
- # This will fail because the token is invalid, but this is how to access a private API
19
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api', 'MC5-XXXXXXX-vRfvv70')
20
- # endgist
21
- # err.message, "Unexpected status code [401] on URL https://lesbonneschoses.cdn.prismic.io/api?access_token=MC5-XXXXXXX-vRfvv70"); // gisthide
22
- }.to raise_error(Prismic::API::PrismicWSAuthError, "Can't connect to Prismic's API: Invalid access token")
23
- end
24
-
25
- it 'references' do
26
- # startgist:55a7ef6bc691bf3c4929:prismic-references.rb
27
- preview_token = 'MC5VbDdXQmtuTTB6Z0hNWHF3.c--_vVbvv73vv73vv73vv71EA--_vS_vv73vv70T77-9Ke-_ve-_vWfvv70ebO-_ve-_ve-_vQN377-9ce-_vRfvv70';
28
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api', preview_token)
29
- st_patrick_ref = api.ref('St-Patrick specials')
30
- # Now we'll use this reference for all our calls
31
- response = api.query(Prismic::Predicates::at('document.type', 'product'), 'ref' => st_patrick_ref)
32
- # The Response object contains all documents of type "product"
33
- # including the new "Saint-Patrick's Cupcake"
34
- # endgist
35
- response.results.length.should == 17
36
- end
37
-
38
- end
39
-
40
- describe 'queries' do
41
-
42
- it 'simple query' do
43
- # startgist:f1007f1c4c4bc94f9fc6:prismic-simplequery.rb
44
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api')
45
- response = api
46
- .form('everything')
47
- .query(Prismic::Predicates::at('document.type', 'product'))
48
- .submit(api.master_ref)
49
- # response contains all documents of type 'product', paginated
50
- # endgist
51
- response.results.size.should == 16
52
- end
53
-
54
- it 'orderings' do
55
- # startgist:f987025745dbbf26e817:prismic-orderings.rb
56
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api')
57
- response = api.form('everything')
58
- .ref(api.master_ref)
59
- .query(Prismic::Predicates::at('document.type', 'product'))
60
- .page_size(100)
61
- .orderings('[my.product.price desc]')
62
- .submit
63
- # The products are now ordered by price, highest first
64
- results = response.results
65
- # endgist
66
- response.results_per_page.should == 100
67
- end
68
-
69
- it 'predicates' do
70
- # startgist:7b93db67fa25ac386603:prismic-predicates.rb
71
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api')
72
- response = api
73
- .form('everything')
74
- .query(
75
- Prismic::Predicates::at('document.type', 'product'),
76
- Prismic::Predicates::date_after('my.blog-post.date', 1401580800000))
77
- .submit(api.master_ref)
78
- # endgist
79
- response.results.size.should == 0
80
- end
81
-
82
- it 'all predicates' do
83
- # startgist:1efb7363a5f573627308:prismic-allPredicates.rb
84
- # 'at' predicate: equality of a fragment to a value.
85
- at = Predicates::at('document.type', 'article')
86
- # 'any' predicate: equality of a fragment to a value.
87
- any = Predicates::any('document.type', ['article', 'blog-post'])
88
-
89
- # 'fulltext' predicate: fulltext search in a fragment.
90
- fulltext = Predicates::fulltext('my.article.body', 'sausage')
91
-
92
- # 'similar' predicate, with a document id as reference
93
- similar = Predicates::similar('UXasdFwe42D', 10)
94
- # endgist
95
- at.should == ['at', 'document.type', 'article']
96
- any.should == ['any', 'document.type', ['article', 'blog-post']]
97
- end
98
-
99
- end
100
-
101
- describe 'fragments' do
102
-
103
- it 'text' do
104
- api = Prismic::api('https://lesbonneschoses.cdn.prismic.io/api')
105
- doc = api.getByID('UlfoxUnM0wkXYXbl')
106
- # startgist:4cbc1abffe7cc1209f95:prismic-getText.rb
107
- author = doc.get_text('blog-post.author')
108
- if author == nil
109
- name = 'Anonymous'
110
- else
111
- name = author.value
112
- end
113
- # endgist
114
- name.should == 'John M. Martelle, Fine Pastry Magazine'
115
- end
116
-
117
- it 'number' do
118
- api = Prismic::api('https://lesbonneschoses.cdn.prismic.io/api')
119
- response = api.form('everything')
120
- .query(Predicates::at('document.id', 'UlfoxUnM0wkXYXbO'))
121
- .ref(api.master_ref)
122
- .submit
123
- doc = response[0]
124
- # startgist:4e263ac039e0b0cea0be:prismic-getNumber.rb
125
- # Number predicates
126
- gt = Predicates::gt('my.product.price', 10)
127
- lt = Predicates::lt('my.product.price', 20)
128
- in_range = Predicates::in_range('my.product.price', 10, 20)
129
-
130
- # Accessing number fields
131
- price = doc.get_number('product.price').value
132
- # endgist
133
- price.should == 2.5
134
- end
135
-
136
- it 'images' do
137
- api = Prismic::api('https://lesbonneschoses.cdn.prismic.io/api')
138
- response = api.form('everything')
139
- .query(Predicates::at('document.id', 'UlfoxUnM0wkXYXbO'))
140
- .ref(api.master_ref)
141
- .submit
142
- doc = response[0]
143
- # startgist:154ba379a5000f14b3ea:prismic-images.rb
144
- # Accessing image fields
145
- image = doc.get_image('product.image')
146
- # Most of the time you will be using the "main" view
147
- url = image.main.url
148
- # endgist
149
- url.should == 'https://d2aw36oac6sa9o.cloudfront.net/lesbonneschoses/f606ad513fcc2a73b909817119b84d6fd0d61a6d.png'
150
- end
151
-
152
- it 'date and timestamp' do
153
- api = Prismic::api('https://lesbonneschoses.cdn.prismic.io/api')
154
- response = api.form('everything')
155
- .query(Predicates::at('document.id', 'UlfoxUnM0wkXYXbl'))
156
- .ref(api.master_ref)
157
- .submit
158
- doc = response[0]
159
- # startgist:4ac2db89bde0ca0c2b33:prismic-dateTimestamp.rb
160
- # Date and Timestamp predicates
161
- dateBefore = Predicates::date_before('my.product.releaseDate', Time.new(2014, 6, 1))
162
- dateAfter = Predicates::date_after('my.product.releaseDate', Time.new(2014, 1, 1))
163
- dateBetween = Predicates::date_between('my.product.releaseDate', Time.new(2014, 1, 1), Time.new(2014, 6, 1))
164
- dayOfMonth = Predicates::day_of_month('my.product.releaseDate', 14)
165
- dayOfMonthAfter = Predicates::day_of_month_after('my.product.releaseDate', 14)
166
- dayOfMonthBefore = Predicates::day_of_month_before('my.product.releaseDate', 14)
167
- dayOfWeek = Predicates::day_of_week('my.product.releaseDate', 'Tuesday')
168
- dayOfWeekAfter = Predicates::day_of_week_after('my.product.releaseDate', 'Wednesday')
169
- dayOfWeekBefore = Predicates::day_of_week_before('my.product.releaseDate', 'Wednesday')
170
- month = Predicates::month('my.product.releaseDate', 'June')
171
- monthBefore = Predicates::month_before('my.product.releaseDate', 'June')
172
- monthAfter = Predicates::month_after('my.product.releaseDate', 'June')
173
- year = Predicates::year('my.product.releaseDate', 2014)
174
- hour = Predicates::hour('my.product.releaseDate', 12)
175
- hourBefore = Predicates::hour_before('my.product.releaseDate', 12)
176
- hourAfter = Predicates::hour_after('my.product.releaseDate', 12)
177
-
178
- # Accessing Date and Timestamp fields
179
- date = doc.get_date('blog-post.date').value
180
- date_year = date ? date.year : nil
181
- update_time = doc.get_timestamp('blog-post.update')
182
- update_hour = update_time ? update_time.value.hour : nil
183
- # endgist
184
- date_year.should == 2013
185
- end
186
-
187
- it 'group' do
188
- json = '{"id":"abcd","type":"article","href":"","slugs":[],"tags":[],"data":{"article":{"documents":{"type":"Group","value":[{"linktodoc":{"type":"Link.document","value":{"document":{"id":"UrDejAEAAFwMyrW9","type":"doc","tags":[],"slug":"installing-meta-micro"},"isBroken":false}},"desc":{"type":"StructuredText","value":[{"type":"paragraph","text":"A detailed step by step point of view on how installing happens.","spans":[]}]}},{"linktodoc":{"type":"Link.document","value":{"document":{"id":"UrDmKgEAALwMyrXA","type":"doc","tags":[],"slug":"using-meta-micro"},"isBroken":false}}}]}}}}'
189
- document = Prismic::JsonParser.document_parser(JSON.load(json))
190
- resolver = Prismic.link_resolver('master') { |doc_link| "http://localhost/#{doc_link.id}" }
191
- # startgist:4c87bd640086b9094151:prismic-group.rb
192
- group = document.get_group('article.documents')
193
- docs = group ? group : []
194
- docs.each do |doc|
195
- # Desc and Link are Fragments, their type depending on what's declared in the Document Mask
196
- desc = doc['desc']
197
- link = doc['linktodoc']
198
- end
199
- # endgist
200
- docs[0]['desc'].as_html(resolver).should == '<p>A detailed step by step point of view on how installing happens.</p>'
201
- end
202
-
203
- it 'link' do
204
- json = '{"id":"abcd","type":"article","href":"","slugs":[],"tags":[],"data":{"article":{"source":{"type":"Link.document","value":{"document":{"id":"UlfoxUnM0wkXYXbE","type":"product","tags":["Macaron"],"slug":"dark-chocolate-macaron"},"isBroken":false}}}}}'
205
- document = Prismic::JsonParser.document_parser(JSON.load(json))
206
- # startgist:762dfce77d215e6c70b0:prismic-link.rb
207
- resolver = Prismic.link_resolver('master') { |doc_link| "http://localhost/#{doc_link.id}/#{doc_link.slug}" }
208
- source = document.get_link('article.source')
209
- url = source ? source.url(resolver) : nil
210
- # endgist
211
- url.should == 'http://localhost/UlfoxUnM0wkXYXbE/dark-chocolate-macaron'
212
- end
213
-
214
- it 'embed' do
215
- json = '{"id":"abcd","type":"article","href":"","slugs":[],"tags":[],"data":{"article":{"video":{"type":"Embed","value":{"oembed":{"provider_url":"http://www.youtube.com/","type":"video","thumbnail_height":360,"height":270,"thumbnail_url":"http://i1.ytimg.com/vi/baGfM6dBzs8/hqdefault.jpg","width":480,"provider_name":"YouTube","html":"<iframe width=\\"480\\" height=\\"270\\" src=\\"http://www.youtube.com/embed/baGfM6dBzs8?feature=oembed\\" frameborder=\\"0\\" allowfullscreen></iframe>","author_name":"Siobhan Wilson","version":"1.0","author_url":"http://www.youtube.com/user/siobhanwilsonsongs","thumbnail_width":480,"title":"Siobhan Wilson - All Dressed Up","embed_url":"https://www.youtube.com/watch?v=baGfM6dBzs8"}}}}}}'
216
- document = Prismic::JsonParser.document_parser(JSON.load(json))
217
- # startgist:86d937da7ba242ea981f:prismic-embed.rb
218
- video = document.get_embed('article.video')
219
- # Html is the code to include to embed the object, and depends on the embedded service
220
- html = video ? video.as_html : ''
221
- # endgist
222
- html.should == '<div data-oembed="http://www.youtube.com/" data-oembed-type="video" data-oembed-provider="youtube"><iframe width="480" height="270" src="http://www.youtube.com/embed/baGfM6dBzs8?feature=oembed" frameborder="0" allowfullscreen></iframe></div>'
223
- end
224
-
225
- it 'color' do
226
- json = '{"id":"abcd","type":"article","href":"","slugs":[],"tags":[],"data":{"article":{"background":{"type":"Color","value":"#000000"}}}}'
227
- document = Prismic::JsonParser.document_parser(JSON.load(json))
228
- # startgist:2b41f3a75f129a0d6903:prismic-color.rb
229
- bgcolor = document.get_color('article.background')
230
- hex = '#' + (bgcolor ? bgcolor.value : 'FFFFFF')
231
- # endgist
232
- hex.should == '#000000'
233
- end
234
-
235
- it 'GeoPoint' do
236
- json = '{"id":"abcd","type":"article","href":"","slugs":[],"tags":[],"data":{"article":{"location":{"type":"GeoPoint","value":{"latitude":48.877108,"longitude":2.333879}}}}}'
237
- document = Prismic::JsonParser.document_parser(JSON.load(json))
238
- # startgist:f221a2396c079a7d291f:prismic-geopoint.rb
239
- # "near" predicate for GeoPoint fragments
240
- near = Predicates::near('my.store.location', 48.8768767, 2.3338802, 10)
241
-
242
- # Accessing GeoPoint fragments
243
- place = document.get_geopoint('article.location')
244
- coordinates = place ? (place.latitude.to_s + ',' + place.longitude.to_s) : ''
245
- # endgist
246
- coordinates.should == '48.877108,2.333879'
247
- end
248
-
249
- it 'asHtml' do
250
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api')
251
- response = api
252
- .form('everything')
253
- .query(Prismic::Predicates::at('document.id', 'UlfoxUnM0wkXYXbX'))
254
- .submit(api.master_ref)
255
- # startgist:7b93db67fa25ac386603:prismic-asHtml.rb
256
- resolver = Prismic.link_resolver('master'){ |doc_link| "http:#localhost/#{doc_link.id}" }
257
- doc = response.results[0]
258
- html = doc['blog-post.body'].as_html(resolver)
259
- # endgist
260
- html.should_not be_nil
261
- end
262
-
263
- it 'HtmlSerializer' do
264
- api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api')
265
- response = api
266
- .form('everything')
267
- .query(Prismic::Predicates::at('document.id', 'UlfoxUnM0wkXYXbX'))
268
- .submit(api.master_ref)
269
- # startgist:e7944fe6ecdd8956b72:prismic-htmlSerializer.rb
270
- resolver = Prismic.link_resolver('master'){ |doc_link| "http:#localhost/#{doc_link.id}" }
271
- serializer = Prismic.html_serializer do |element, html|
272
- if element.is_a?(Prismic::Fragments::StructuredText::Block::Image)
273
- # Don't wrap images in a <p> tag
274
- %(<img src="#{element.url}" alt="#{element.alt}" width="#{element.width}" height="#{element.height}" />)
275
- else
276
- nil
277
- end
278
- end
279
- doc = response.results[0]
280
- html = doc.get_structured_text('blog-post.body').as_html(resolver, serializer)
281
- # endgist
282
- html.should_not be_nil
283
- end
284
-
285
- it 'cache' do
286
- # startgist:388900d4e9e7a444e0a2:prismic-cache.rb
287
- # You can pass any object implementing the same methods as the BasicCache
288
- # https://github.com/prismicio/ruby-kit/blob/master/lib/prismic/cache/basic.rb
289
- cache = Prismic::LruCache.new
290
- api = Prismic::api('https://lesbonneschoses.cdn.prismic.io/api', { :cache => cache })
291
- # The Api will use the custom cache object
292
- # endgist
293
- api.should_not be_nil
294
- end
295
-
296
- end
297
-
298
- end
@@ -1,228 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe 'LesBonnesChoses' do
5
- before do
6
- @api = Prismic.api('https://lesbonneschoses.cdn.prismic.io/api', nil)
7
- @master_ref = @api.master_ref
8
- end
9
-
10
- describe '/api' do
11
- it 'API works' do
12
- @api.should_not be_nil
13
- end
14
- end
15
-
16
- describe 'query' do
17
- it 'queries everything and returns 20 documents' do
18
- @api.form('everything').submit(@master_ref).size.should == 20
19
- @api.form('everything').submit(@master_ref).results.size.should == 20
20
- end
21
-
22
- it 'queries macarons (using a predicate) and returns 7 documents' do
23
- @api.query('[[:d = any(document.tags, ["Macaron"])]]')
24
- .results.size.should == 7
25
- @api.query('[[:d = any(document.tags, ["Macaron"])]]').size.should == 7
26
- end
27
-
28
- it 'queries macarons (using a form) and returns 7 documents' do
29
- @api.form('macarons').submit(@master_ref).results.size.should == 7
30
- @api.form('macarons').submit(@master_ref).size.should == 7
31
- end
32
-
33
- it 'queries macarons or cupcakes (using a form + a predicate) and returns 11 documents' do
34
- @api.form('products')
35
- .query('[[:d = any(document.tags, ["Cupcake", "Macaron"])]]')
36
- .submit(@master_ref).results.size.should == 11
37
- @api.form('products')
38
- .query('[[:d = any(document.tags, ["Cupcake", "Macaron"])]]')
39
- .submit(@master_ref).size.should == 11
40
- end
41
- end
42
-
43
- describe 'pagination' do
44
- it 'works in basic cases' do
45
- documents = @api.form('everything').submit(@master_ref)
46
- documents.page.should == 1
47
- documents.results_per_page.should == 20
48
- documents.results_size.should == 20
49
- documents.total_results_size.should == 40
50
- documents.total_pages.should == 2
51
- documents.next_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=2&pageSize=20'
52
- documents.prev_page.should == nil
53
- end
54
- it 'works when passing nil' do
55
- documents = @api.form('everything').page(nil).submit(@master_ref)
56
- documents.page.should == 1
57
- documents.results_per_page.should == 20
58
- documents.results_size.should == 20
59
- documents.total_results_size.should == 40
60
- documents.total_pages.should == 2
61
- documents.next_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=2&pageSize=20'
62
- documents.prev_page.should == nil
63
- end
64
- it 'works on page 2' do
65
- documents = @api.form('everything').page("2").submit(@master_ref)
66
- documents.page.should == 2
67
- documents.results_per_page.should == 20
68
- documents.results_size.should == 20
69
- documents.total_results_size.should == 40
70
- documents.total_pages.should == 2
71
- documents.next_page.should == nil
72
- documents.prev_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=1&pageSize=20'
73
- end
74
- it 'works on page 2 with a pagination step of 10' do
75
- documents = @api.form('everything').page('2').page_size('10').submit(@master_ref)
76
- documents.page.should == 2
77
- documents.results_per_page.should == 10
78
- documents.results_size.should == 10
79
- documents.total_results_size.should == 40
80
- documents.total_pages.should == 4
81
- documents.next_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=3&pageSize=10'
82
- documents.prev_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=1&pageSize=10'
83
- end
84
- it 'works when passing nil' do
85
- documents = @api.form('everything').page(nil).submit(@master_ref)
86
- documents.page.should == 1
87
- documents.results_per_page.should == 20
88
- documents.results_size.should == 20
89
- documents.total_results_size.should == 40
90
- documents.total_pages.should == 2
91
- documents.next_page.should == 'https://d2aw36oac6sa9o.cloudfront.net/api/documents/search?ref=UlfoxUnM08QWYXdl&page=2&pageSize=20'
92
- documents.prev_page.should == nil
93
- end
94
- end
95
-
96
- describe 'API::Document' do
97
- before do
98
- @document = @api.form('everything').query('[[:d = at(document.id, "UlfoxUnM0wkXYXbh")]]').submit(@master_ref)[0]
99
- end
100
-
101
- it 'Operator [] works on document' do
102
- @document['job-offer.name'].as_html(nil).should == '<h1>Pastry Dresser</h1>'
103
- end
104
-
105
- it 'Operator [] returns nil if wrong type' do
106
- @document['product.name'].should == nil
107
- end
108
-
109
- it 'Operator [] raises error if field is nonsense' do
110
- expect {
111
- @document['blablabla']
112
- }.to raise_error(ArgumentError, 'Argument should contain one dot. Example: product.price')
113
- end
114
- end
115
-
116
- describe 'API::Documents' do
117
- before do
118
- @documents = @api.form('everything').submit(@master_ref)
119
- end
120
-
121
- it 'has a working [] operator' do
122
- @documents[0].slug.should == @documents.results[0].slug
123
- end
124
- it 'has a proper size' do
125
- @documents.length.should == 20
126
- @documents.size.should == 20
127
- end
128
- it 'has a proper each method' do
129
- array = []
130
- @documents.each {|document| array << document.slug }
131
- array.join(' ').should == 'art-director store-intern content-director ganache-specialist community-manager oven-instrumentist paris-saint-lazare tokyo-roppongi-hills london-covent-garden paris-champ-elysees new-york-fifth-avenue pastry-dresser exotic-kiwi-pie apricot-pie sweet-strawberry-pie woodland-cherry-pie cool-coconut-macaron salted-caramel-macaron the-end-of-a-chapter-the-beginning-of-a-new-one get-the-right-approach-to-ganache'
132
- end
133
- it 'is a proper Enumerable' do
134
- @documents.map {|document| document.slug }.join(' ').should == 'art-director store-intern content-director ganache-specialist community-manager oven-instrumentist paris-saint-lazare tokyo-roppongi-hills london-covent-garden paris-champ-elysees new-york-fifth-avenue pastry-dresser exotic-kiwi-pie apricot-pie sweet-strawberry-pie woodland-cherry-pie cool-coconut-macaron salted-caramel-macaron the-end-of-a-chapter-the-beginning-of-a-new-one get-the-right-approach-to-ganache'
135
- end
136
- end
137
-
138
- describe 'FetchLinks' do
139
- it 'Fetches additional data with DocumentLink' do
140
- documents = @api.form('everything')
141
- .query(Prismic::Predicates::at('document.id', 'UlfoxUnM0wkXYXbt'))
142
- .fetch_links('blog-post.author')
143
- .submit(@master_ref).results
144
- link = documents[0].get('blog-post.relatedpost')[0]
145
- link.get_text('blog-post.author').value.should == 'John M. Martelle, Fine Pastry Magazine'
146
- end
147
- end
148
-
149
- describe 'Fragments' do
150
- before do
151
- @link_resolver = Prismic.link_resolver("master"){|doc_link| "http://localhost/#{doc_link.id}" }
152
- @html_serializer = Prismic.html_serializer do |element, html|
153
- if element.is_a?(Prismic::Fragments::StructuredText::Block::Image)
154
- %(<img src="#{element.url}" alt="#{element.alt}" width="#{element.width}" height="#{element.height}" />)
155
- else
156
- nil
157
- end
158
- end
159
- end
160
- describe 'API::Fragments::StructuredText' do
161
- it "returns a correct as_html on a StructuredText with list, span, embed and image" do
162
- @api.form("everything")
163
- .query(%([[:d = at(document.id, "UlfoxUnM0wkXYXbX")]]))
164
- .submit(@master_ref)[0]['blog-post.body'].as_html(@link_resolver).gsub("&#39;", "'").should ==
165
- "<h1>Get the right approach to ganache</h1>\n\n"\
166
- "<p>A lot of people touch base with us to know about one of our key ingredients, and the essential role it plays in our creations: ganache.</p>\n\n"\
167
- "<p>Indeed, ganache is the macaron's softener, or else, macarons would be but tough biscuits; it is the cupcake's wrapper, or else, cupcakes would be but plain old cake. We even sometimes use ganache within our cupcakes, to soften the cake itself, or as a support to our pies' content.</p>\n\n"\
168
- "<h2>How to approach ganache</h2>\n\n"\
169
- "<p class=\"block-img\"><img src=\"https://d2aw36oac6sa9o.cloudfront.net/lesbonneschoses/ee7b984b98db4516aba2eabd54ab498293913c6c.jpg\" alt=\"\" width=\"640\" height=\"425\" /></p>\n\n"\
170
- "<p>Apart from the taste balance, which is always a challenge when it comes to pastry, the tough part about ganache is about thickness. It is even harder to predict through all the phases the ganache gets to meet (how long will it get melted? how long will it remain in the fridge?). "\
171
- "Things get a hell of a lot easier to get once you consider that there are two main ways to get the perfect ganache:</p>\n\n"\
172
- "<ul><li><strong>working from the top down</strong>: start with a thick, almost hard material, and soften it by manipulating it, or by mixing it with a more liquid ingredient (like milk)</li>"\
173
- "<li><strong>working from the bottom up</strong>: start from a liquid-ish state, and harden it by miwing it with thicker ingredients, or by leaving it in the fridge longer.</li></ul>\n\n"\
174
- "<p>We do hope this advice will empower you in your ganache-making skills. Let us know how you did with it!</p>\n\n"\
175
- "<h2>Ganache at <em>Les Bonnes Choses</em></h2>\n\n"\
176
- "<p>We have a saying at Les Bonnes Choses: &quot;Once you can make ganache, you can make anything.&quot;</p>\n\n"\
177
- "<p>As you may know, we like to give our workshop artists the ability to master their art to the top; that is why our Preparation Experts always start off as being Ganache Specialists for Les Bonnes Choses. That way, they're given an opportunity to focus on one exercise before moving on. "\
178
- "Once they master their ganache, and are able to provide the most optimal delight to our customers, we consider they'll thrive as they work on other kinds of preparations.</p>\n\n"\
179
- "<h2>About the chocolate in our ganache</h2>\n\n"\
180
- "<p>Now, we've also had a lot of questions about how our chocolate gets made. It's true, as you might know, that we make it ourselves, from Columbian cocoa and French cow milk, with a process that much resembles the one in the following Discovery Channel documentary.</p>\n\n"\
181
- "<div data-oembed=\"http://www.youtube.com/\" data-oembed-type=\"video\" data-oembed-provider=\"youtube\"><iframe width=\"459\" height=\"344\" src=\"http://www.youtube.com/embed/Ye78F3-CuXY?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe></div>"
182
- end
183
- it "returns a correct as_html on a StructuredText with custom HTML serializer" do
184
- @api.form("everything")
185
- .query(%([[:d = at(document.id, "#{@api.bookmark('about')}")]]))
186
- .submit(@master_ref)[0]['article.content'].as_html(@link_resolver, @html_serializer).gsub("&#39;", "'").should ==
187
- "<h2>A tale of pastry and passion</h2>\n\n"\
188
- "<p>As a child, Jean-Michel Pastranova learned the art of fine cuisine from his grand-father, Jacques Pastranova, who was the creator of the &quot;taste-design&quot; art current, and still today an unmissable reference of forward-thinking in cuisine. At first an assistant in his grand-father's kitchen, Jean-Michel soon found himself fascinated by sweet flavors and the tougher art of pastry, drawing his own path in the ever-changing cuisine world.</p>\n\n"\
189
- "<p>In 1992, the first Les Bonnes Choses store opened on rue Saint-Lazare, in Paris (<a href=\"http://localhost/UlfoxUnM0wkXYXbb\">we're still there!</a>), much to everyone's surprise; indeed, back then, it was very surprising for a highly promising young man with a preordained career as a restaurant chef, to open a pastry shop instead. But soon enough, contemporary chefs understood that Jean-Michel had the drive to redefine a new nobility to pastry, the same way many other kinds of cuisine were being qualified as &quot;fine&quot;.</p>\n\n"\
190
- "<p>In 1996, meeting an overwhelming demand, Jean-Michel Pastranova opened <a href=\"http://localhost/UlfoxUnM0wkXYXbP\">a second shop on Paris's Champs-Élysées</a>, and <a href=\"http://localhost/UlfoxUnM0wkXYXbr\">a third one in London</a>, the same week! Eventually, Les Bonnes Choses gained an international reputation as &quot;a perfection so familiar and new at the same time, that it will feel like a taste travel&quot; (New York Gazette), &quot;the finest balance between surprise and comfort, enveloped in sweetness&quot; (The Tokyo Tribune), &quot;a renewal of the pastry genre (...), the kind that changed the way pastry is approached globally&quot; (The San Francisco Gourmet News). Therefore, it was only a matter of time before Les Bonnes Choses opened shops in <a href=\"http://localhost/UlfoxUnM0wkXYXbc\">New York</a> (2000) and <a href=\"http://localhost/UlfoxUnM0wkXYXbU\">Tokyo</a> (2004).</p>\n\n"\
191
- "<p>In 2013, Jean-Michel Pastranova stepped down as the CEO and Director of Workshops, remaining a senior advisor to the board and to the workshop artists; he passed the light on to Selena, his daugther, who initially learned the art of pastry from him. Passion for great food runs in the Pastranova family...</p>\n\n<img src=\"https://d2aw36oac6sa9o.cloudfront.net/lesbonneschoses/df6c1d87258a5bfadf3479b163fd85c829a5c0b8.jpg\" alt=\"\" width=\"800\" height=\"533\" />\n\n"\
192
- "<h2>Our main value: our customers' delight</h2>\n\n"\
193
- "<p>Our every action is driven by the firm belief that there is art in pastry, and that this art is one of the dearest pleasures one can experience.</p>\n\n"\
194
- "<p>At Les Bonnes Choses, people preparing your macarons are not simply &quot;pastry chefs&quot;: they are &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXba\">ganache specialists</a>&quot;, &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbQ\">fruit experts</a>&quot;, or &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbn\">oven instrumentalists</a>&quot;. They are the best people out there to perform the tasks they perform to create your pastry, giving it the greatest value. And they just love to make their specialized pastry skill better and better until perfection.</p>\n\n"\
195
- "<p>Of course, there is a workshop in each <em>Les Bonnes Choses</em> store, and every pastry you buy was made today, by the best pastry specialists in your country.</p>\n\n"\
196
- "<p>However, the very difficult art of creating new concepts, juggling with tastes and creating brand new, powerful experiences, is performed every few months, during our &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbl\">Pastry Art Brainstorms</a>&quot;. During the event, the best pastry artists in the world (some working for <em>Les Bonnes Choses</em>, some not) gather in Paris, and showcase the experiments they've been working on; then, the other present artists comment on the piece, and iterate on it together, in order to make it the best possible masterchief!</p>\n\n"\
197
- "<p>The session is presided by Jean-Michel Pastranova, who then selects the most delightful experiences, to add it to <em>Les Bonnes Choses</em>'s catalogue.</p>"
198
- end
199
- it "returns a correct as_html on a StructuredText with links" do
200
- @api.form("everything")
201
- .query(%([[:d = at(document.id, "#{@api.bookmark('about')}")]]))
202
- .submit(@master_ref)[0]['article.content'].as_html(@link_resolver).gsub("&#39;", "'").should ==
203
- "<h2>A tale of pastry and passion</h2>\n\n"\
204
- "<p>As a child, Jean-Michel Pastranova learned the art of fine cuisine from his grand-father, Jacques Pastranova, who was the creator of the &quot;taste-design&quot; art current, and still today an unmissable reference of forward-thinking in cuisine. At first an assistant in his grand-father's kitchen, Jean-Michel soon found himself fascinated by sweet flavors and the tougher art of pastry, drawing his own path in the ever-changing cuisine world.</p>\n\n"\
205
- "<p>In 1992, the first Les Bonnes Choses store opened on rue Saint-Lazare, in Paris (<a href=\"http://localhost/UlfoxUnM0wkXYXbb\">we're still there!</a>), much to everyone's surprise; indeed, back then, it was very surprising for a highly promising young man with a preordained career as a restaurant chef, to open a pastry shop instead. But soon enough, contemporary chefs understood that Jean-Michel had the drive to redefine a new nobility to pastry, the same way many other kinds of cuisine were being qualified as &quot;fine&quot;.</p>\n\n"\
206
- "<p>In 1996, meeting an overwhelming demand, Jean-Michel Pastranova opened <a href=\"http://localhost/UlfoxUnM0wkXYXbP\">a second shop on Paris's Champs-Élysées</a>, and <a href=\"http://localhost/UlfoxUnM0wkXYXbr\">a third one in London</a>, the same week! Eventually, Les Bonnes Choses gained an international reputation as &quot;a perfection so familiar and new at the same time, that it will feel like a taste travel&quot; (New York Gazette), &quot;the finest balance between surprise and comfort, enveloped in sweetness&quot; (The Tokyo Tribune), &quot;a renewal of the pastry genre (...), the kind that changed the way pastry is approached globally&quot; (The San Francisco Gourmet News). Therefore, it was only a matter of time before Les Bonnes Choses opened shops in <a href=\"http://localhost/UlfoxUnM0wkXYXbc\">New York</a> (2000) and <a href=\"http://localhost/UlfoxUnM0wkXYXbU\">Tokyo</a> (2004).</p>\n\n"\
207
- "<p>In 2013, Jean-Michel Pastranova stepped down as the CEO and Director of Workshops, remaining a senior advisor to the board and to the workshop artists; he passed the light on to Selena, his daugther, who initially learned the art of pastry from him. Passion for great food runs in the Pastranova family...</p>\n\n<p class=\"block-img\"><img src=\"https://d2aw36oac6sa9o.cloudfront.net/lesbonneschoses/df6c1d87258a5bfadf3479b163fd85c829a5c0b8.jpg\" alt=\"\" width=\"800\" height=\"533\" /></p>\n\n"\
208
- "<h2>Our main value: our customers' delight</h2>\n\n"\
209
- "<p>Our every action is driven by the firm belief that there is art in pastry, and that this art is one of the dearest pleasures one can experience.</p>\n\n"\
210
- "<p>At Les Bonnes Choses, people preparing your macarons are not simply &quot;pastry chefs&quot;: they are &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXba\">ganache specialists</a>&quot;, &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbQ\">fruit experts</a>&quot;, or &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbn\">oven instrumentalists</a>&quot;. They are the best people out there to perform the tasks they perform to create your pastry, giving it the greatest value. And they just love to make their specialized pastry skill better and better until perfection.</p>\n\n"\
211
- "<p>Of course, there is a workshop in each <em>Les Bonnes Choses</em> store, and every pastry you buy was made today, by the best pastry specialists in your country.</p>\n\n"\
212
- "<p>However, the very difficult art of creating new concepts, juggling with tastes and creating brand new, powerful experiences, is performed every few months, during our &quot;<a href=\"http://localhost/UlfoxUnM0wkXYXbl\">Pastry Art Brainstorms</a>&quot;. During the event, the best pastry artists in the world (some working for <em>Les Bonnes Choses</em>, some not) gather in Paris, and showcase the experiments they've been working on; then, the other present artists comment on the piece, and iterate on it together, in order to make it the best possible masterchief!</p>\n\n"\
213
- "<p>The session is presided by Jean-Michel Pastranova, who then selects the most delightful experiences, to add it to <em>Les Bonnes Choses</em>'s catalogue.</p>"
214
- end
215
- it "returns a correct as_text on a StructuredText" do
216
- @api.form("everything")
217
- .query(%([[:d = at(document.id, "UlfoxUnM0wkXYXbt")]]))
218
- .submit(@master_ref)[0]['blog-post.body'].as_text.should == "The end of a chapter the beginning of a new one Jean-Michel Pastranova, the founder of Les Bonnes Choses, and creator of the whole concept of modern fine pastry, has decided to step down as the CEO and the Director of Workshops of Les Bonnes Choses, to focus on other projects, among which his now best-selling pastry cook books, but also to take on a primary role in a culinary television show to be announced later this year. \"I believe I've taken the Les Bonnes Choses concept as far as it can go. Les Bonnes Choses is already an entity that is driven by its people, thanks to a strong internal culture, so I don't feel like they need me as much as they used to. I'm sure they are greater ways to come, to innovate in pastry, and I'm sure Les Bonnes Choses's coming innovation will be even more mind-blowing than if I had stayed longer.\" He will remain as a senior advisor to the board, and to the workshop artists, as his daughter Selena, who has been working with him for several years, will fulfill the CEO role from now on. \"My father was able not only to create a revolutionary concept, but also a company culture that puts everyone in charge of driving the company's innovation and quality. That gives us years, maybe decades of revolutionary ideas to come, and there's still a long, wonderful path to walk in the fine pastry world.\""
219
- end
220
-
221
- it "returns a correct as_text on a StructuredText with a separator" do
222
- @api.form("everything")
223
- .query(%([[:d = at(document.id, "UlfoxUnM0wkXYXbt")]]))
224
- .submit(@master_ref)[0]['blog-post.body'].as_text(' #### ').should == "The end of a chapter the beginning of a new one #### Jean-Michel Pastranova, the founder of Les Bonnes Choses, and creator of the whole concept of modern fine pastry, has decided to step down as the CEO and the Director of Workshops of Les Bonnes Choses, to focus on other projects, among which his now best-selling pastry cook books, but also to take on a primary role in a culinary television show to be announced later this year. #### \"I believe I've taken the Les Bonnes Choses concept as far as it can go. Les Bonnes Choses is already an entity that is driven by its people, thanks to a strong internal culture, so I don't feel like they need me as much as they used to. I'm sure they are greater ways to come, to innovate in pastry, and I'm sure Les Bonnes Choses's coming innovation will be even more mind-blowing than if I had stayed longer.\" #### He will remain as a senior advisor to the board, and to the workshop artists, as his daughter Selena, who has been working with him for several years, will fulfill the CEO role from now on. #### \"My father was able not only to create a revolutionary concept, but also a company culture that puts everyone in charge of driving the company's innovation and quality. That gives us years, maybe decades of revolutionary ideas to come, and there's still a long, wonderful path to walk in the fine pastry world.\""
225
- end
226
- end
227
- end
228
- end