jekyll-twitter-plugin 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +7 -5
- data/Gemfile +1 -0
- data/README.md +37 -17
- data/Rakefile +1 -0
- data/jekyll-twitter-plugin.gemspec +6 -5
- data/lib/jekyll-twitter-plugin.rb +56 -20
- data/spec/api_request_spec.rb +2 -1
- data/spec/integration_tests.rb +5 -8
- data/spec/spec_helper.rb +2 -2
- data/spec/support/jekyll_template.rb +1 -0
- data/spec/twitter_tag_spec.rb +317 -82
- metadata +23 -12
- data/spec/support/shared_contexts.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d5a28bcf4677a1a5ca462788776ead3431ed26444a2f6e2f632e1d2bc9ca5fcd
|
4
|
+
data.tar.gz: ba7ba303e24ca67c1ff1313813722c94f88353ef7d2014af2bbca7c75c53012f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fe96d45ec4959d1b98489408676f504e70398fc5aaaa4cb550201193457a7286f3a18e394298aafc68e1c2dc463b79b358d5c5c0dbef6c3b59672e6957a1e74
|
7
|
+
data.tar.gz: 2bd3d486f229a82c43ee757499fc23e975e490383b4b6d8ac725acde09818c4703b1537d47c7aaedcecb498d2963534cde5a261b37840c010b47a5c09230303e
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# jekyll-twitter-plugin
|
4
4
|
|
5
|
-
A Liquid tag plugin for Jekyll blogging engine that embeds Tweets, Timelines and more from Twitter API.
|
5
|
+
A Liquid tag plugin for the Jekyll blogging engine that embeds Tweets, Timelines and more from Twitter API.
|
6
6
|
|
7
7
|
[![Build Status](https://travis-ci.org/rob-murray/jekyll-twitter-plugin.svg?branch=master)](https://travis-ci.org/rob-murray/jekyll-twitter-plugin)
|
8
8
|
[![Gem Version](https://badge.fury.io/rb/jekyll-twitter-plugin.svg)](http://badge.fury.io/rb/jekyll-twitter-plugin)
|
@@ -12,9 +12,9 @@ A Liquid tag plugin for Jekyll blogging engine that embeds Tweets, Timelines and
|
|
12
12
|
|
13
13
|
## Description
|
14
14
|
|
15
|
-
**jekyll-twitter-plugin** is a Liquid tag plugin for [Jekyll](http://jekyllrb.com/) that enables Twitter content to be used in any pages generated by Jekyll
|
15
|
+
**jekyll-twitter-plugin** is a Liquid tag plugin for [Jekyll](http://jekyllrb.com/) that enables Twitter content to be used in any pages generated by Jekyll. Content is fetched from the [Twitter Publish platform](https://publish.twitter.com).
|
16
16
|
|
17
|
-
The [Publish platform](https://publish.twitter.com) allows Twitter users to curate content for display outside of Twitter
|
17
|
+
The [Publish platform](https://publish.twitter.com) allows Twitter users to curate content for display outside of Twitter. You can display many different types of content with the familiar Twitter styling. We use this API and allow any customisation of the content that is accepted by the Twitter publish platform.
|
18
18
|
|
19
19
|
> You can now embed any Twitter content in your Jekyll powered blog!
|
20
20
|
|
@@ -57,7 +57,7 @@ The plugin supports the following features:
|
|
57
57
|
|
58
58
|
## Getting Started
|
59
59
|
|
60
|
-
As mentioned by [Jekyll's documentation](http://jekyllrb.com/docs/plugins/#installing-a-plugin) you have two options; manually import the source file or require the plugin as a `gem`.
|
60
|
+
As mentioned by [Jekyll's documentation](http://jekyllrb.com/docs/plugins/#installing-a-plugin) you have two options; manually import the source file, or require the plugin as a `gem`.
|
61
61
|
|
62
62
|
|
63
63
|
#### Require gem
|
@@ -71,7 +71,7 @@ gem 'jekyll-twitter-plugin'
|
|
71
71
|
Add the `jekyll-twitter-plugin` to your site `_config.yml` file for Jekyll to import the plugin as a gem.
|
72
72
|
|
73
73
|
```ruby
|
74
|
-
|
74
|
+
plugins: ['jekyll-twitter-plugin']
|
75
75
|
```
|
76
76
|
|
77
77
|
#### Manual import
|
@@ -89,7 +89,7 @@ $ wget https://raw.githubusercontent.com/rob-murray/jekyll-twitter-plugin/master
|
|
89
89
|
|
90
90
|
#### Plugin tag usage
|
91
91
|
|
92
|
-
To use the plugin, in your source content use the tag `twitter` and then pass additional options to the plugin
|
92
|
+
To use the plugin, in your source content use the tag `twitter` and then pass additional options to the plugin. These are passed to the API.
|
93
93
|
|
94
94
|
```liquid
|
95
95
|
{% plugin_type twitter_url *options %}
|
@@ -98,20 +98,40 @@ To use the plugin, in your source content use the tag `twitter` and then pass ad
|
|
98
98
|
{% twitter https://twitter.com/jekyllrb maxwidth=500 limit=5 %}
|
99
99
|
```
|
100
100
|
|
101
|
-
| Argument
|
102
|
-
|
103
|
-
| `plugin_type` | Yes
|
104
|
-
| `twitter_url` | Yes
|
105
|
-
| `*options`
|
101
|
+
| Argument | Required? | Description |
|
102
|
+
| --- | --- | --- |
|
103
|
+
| `plugin_type` | Yes | Either `twitter` or `twitternocache` (same as `twitter` but does not cache api responses) |
|
104
|
+
| `twitter_url` | Yes | The Twitter URL to use, check below for supported URLs. |
|
105
|
+
| `*options` | No | Parameters for the API separated by spaces. Refer below and to respective Twitter API documentation for available parameters. |
|
106
106
|
|
107
|
+
#### Custom variables
|
108
|
+
|
109
|
+
In addition to passing the Twitter URL directly to the plugin, you can also use [Front Matter](https://jekyllrb.com/docs/front-matter/) to store URLs as page variables. This allows you to re-use view configuration or partials by keeping the Twitter URL(s) separate to page content.
|
110
|
+
|
111
|
+
```liquid
|
112
|
+
---
|
113
|
+
title: My page
|
114
|
+
tweets:
|
115
|
+
- https://twitter.com/dhh/status/1162426045405921282
|
116
|
+
- https://twitter.com/rails/status/1205565185739673600
|
117
|
+
a_tweet: https://twitter.com/rubygems/status/518821243320287232
|
118
|
+
---
|
119
|
+
|
120
|
+
{% for tweet in page.tweets %}
|
121
|
+
{% twitter tweet align=right width=350 %}
|
122
|
+
{% endfor %}
|
123
|
+
|
124
|
+
{% twitter page.a_tweet %}
|
125
|
+
```
|
107
126
|
|
108
127
|
### Supported Twitter URLs
|
109
128
|
|
110
|
-
The Twitter URLs that are supported
|
129
|
+
The Twitter URLs that are supported depend on Twitter. We pass the url and all parameters to the API - check [Twitter Publish platform](https://publish.twitter.com) for availability. Here is documentation for some common types:
|
111
130
|
|
112
131
|
##### Tweet:
|
113
132
|
|
114
133
|
* [https://dev.twitter.com/web/overview](https://dev.twitter.com/web/overview)
|
134
|
+
* [https://dev.twitter.com/rest/reference/get/statuses/oembed](https://dev.twitter.com/rest/reference/get/statuses/oembed)
|
115
135
|
* [https://dev.twitter.com/web/embedded-tweets/parameters](https://dev.twitter.com/web/embedded-tweets/parameters)
|
116
136
|
|
117
137
|
##### Timeline:
|
@@ -124,9 +144,9 @@ The Twitter URLs that are supported depends on Twitter, we pass the url and all
|
|
124
144
|
|
125
145
|
### Customisation
|
126
146
|
|
127
|
-
All pairs of options and values after the URL are passed to the API
|
147
|
+
All pairs of options and values after the URL are passed to the API. The parameters must be in pairs with the option as the key: `option=value`.
|
128
148
|
|
129
|
-
For
|
149
|
+
For example, if you want to limit the width of the embedded content then the API supports a `maxwidth` option so you could construct the tag as below to limit it to a value of 500 (pixels).
|
130
150
|
|
131
151
|
```liquid
|
132
152
|
{% twitter https://twitter.com/jekyllrb maxwidth=500 %}
|
@@ -149,11 +169,11 @@ All content will be rendered inside a div with the class `jekyll-twitter-plugin`
|
|
149
169
|
</div>
|
150
170
|
```
|
151
171
|
|
152
|
-
If something goes wrong then a basic error message will be displayed
|
172
|
+
If something goes wrong, then a basic error message will be displayed:
|
153
173
|
|
154
174
|
> Tweet could not be processed
|
155
175
|
|
156
|
-
If we receive an error from the API then a message will be cached and rendered something like this below. If
|
176
|
+
If we receive an error from the API then a message will be cached and rendered something like this below. If it's a 404, then this suggests the Tweet is protected or deleted. I will not be fetched again and again. If the Tweet is restored, then simply delete the cached response from `.tweet-cache` directory and build again.
|
157
177
|
|
158
178
|
```html
|
159
179
|
<div class='jekyll-twitter-plugin'>
|
@@ -163,7 +183,7 @@ If we receive an error from the API then a message will be cached and rendered s
|
|
163
183
|
|
164
184
|
### Caching
|
165
185
|
|
166
|
-
Twitter API responses can be cached to speed up Jekyll site builds. The reponses will be cached in a directory within your Jekyll project called `.tweet-cache
|
186
|
+
Twitter API responses can be cached to speed up Jekyll site builds. The reponses will be cached in a directory within your Jekyll project called `.tweet-cache`. This should not be committed to source control.
|
167
187
|
|
168
188
|
Caching is enabled by using the `twitter` tag.
|
169
189
|
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
# frozen_string_literal: true
|
3
|
-
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "jekyll-twitter-plugin"
|
8
|
-
spec.version = "2.
|
8
|
+
spec.version = "2.1.0"
|
9
9
|
spec.authors = ["Rob Murray"]
|
10
10
|
spec.email = ["robmurray17@gmail.com"]
|
11
11
|
spec.summary = "A Liquid tag plugin for Jekyll blogging engine that embeds Tweets, Timelines and more from Twitter API."
|
@@ -17,9 +17,10 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_development_dependency "bundler"
|
20
|
+
spec.add_development_dependency "bundler"
|
21
|
+
spec.add_development_dependency "byebug" if RUBY_VERSION >= "2.0"
|
21
22
|
spec.add_development_dependency "rake"
|
22
23
|
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "rubocop"
|
23
25
|
spec.add_development_dependency "webmock"
|
24
|
-
spec.add_development_dependency "byebug" if RUBY_VERSION >= "2.0"
|
25
26
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "fileutils"
|
3
4
|
require "net/http"
|
4
5
|
require "uri"
|
@@ -11,12 +12,14 @@ require "digest"
|
|
11
12
|
# https://github.com/rob-murray/jekyll-twitter-plugin
|
12
13
|
#
|
13
14
|
module TwitterJekyll
|
15
|
+
VERSION = "2.0.0".freeze
|
16
|
+
REFER_TO_README = "Please see 'https://github.com/rob-murray/jekyll-twitter-plugin' for usage.".freeze
|
17
|
+
LIBRARY_VERSION = "jekyll-twitter-plugin-v#{VERSION}".freeze
|
18
|
+
REQUEST_HEADERS = { "User-Agent" => LIBRARY_VERSION }.freeze
|
19
|
+
|
14
20
|
# TODO: remove after deprecation cycle
|
15
21
|
CONTEXT_API_KEYS = %w(consumer_key consumer_secret access_token access_token_secret).freeze
|
16
22
|
ENV_API_KEYS = %w(TWITTER_CONSUMER_KEY TWITTER_CONSUMER_SECRET TWITTER_ACCESS_TOKEN TWITTER_ACCESS_TOKEN_SECRET).freeze
|
17
|
-
REFER_TO_README = "Please see 'https://github.com/rob-murray/jekyll-twitter-plugin' for usage.".freeze
|
18
|
-
LIBRARY_VERSION = "jekyll-twitter-plugin-v2.0.0".freeze
|
19
|
-
REQUEST_HEADERS = { "User-Agent" => LIBRARY_VERSION }.freeze
|
20
23
|
|
21
24
|
# Cache class that writes to filesystem
|
22
25
|
# TODO: Do i really need to cache?
|
@@ -28,23 +31,22 @@ module TwitterJekyll
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def read(key)
|
31
|
-
file_to_read = cache_file(
|
34
|
+
file_to_read = cache_file(key)
|
32
35
|
JSON.parse(File.read(file_to_read)) if File.exist?(file_to_read)
|
33
36
|
end
|
34
37
|
|
35
38
|
def write(key, data)
|
36
|
-
file_to_write = cache_file(
|
37
|
-
data_to_write = JSON.generate data.to_h
|
39
|
+
file_to_write = cache_file(key)
|
38
40
|
|
39
41
|
File.open(file_to_write, "w") do |f|
|
40
|
-
f.write(
|
42
|
+
f.write(JSON.generate(data.to_h))
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
46
|
private
|
45
47
|
|
46
|
-
def cache_file(
|
47
|
-
File.join(@cache_folder,
|
48
|
+
def cache_file(key)
|
49
|
+
File.join(@cache_folder, cache_filename(key))
|
48
50
|
end
|
49
51
|
|
50
52
|
def cache_filename(cache_key)
|
@@ -75,7 +77,6 @@ module TwitterJekyll
|
|
75
77
|
end
|
76
78
|
|
77
79
|
handle_response(api_request, response)
|
78
|
-
|
79
80
|
rescue Timeout::Error => e
|
80
81
|
ErrorResponse.new(api_request, e.class.name).to_h
|
81
82
|
end
|
@@ -142,11 +143,22 @@ module TwitterJekyll
|
|
142
143
|
ERROR_BODY_TEXT = "<p>Tweet could not be processed</p>".freeze
|
143
144
|
OEMBED_ARG = "oembed".freeze
|
144
145
|
|
146
|
+
URL_OR_STRING_PARAM = /^("|')?(http|https):\/\//i
|
147
|
+
|
145
148
|
attr_writer :cache # for testing
|
146
149
|
|
147
150
|
def initialize(_name, params, _tokens)
|
148
151
|
super
|
149
|
-
|
152
|
+
|
153
|
+
# Test if first arg is a URL or starts with oembed,
|
154
|
+
# otherwise its a Jekyll variable. TODO: remove oembed after deprecation cycle
|
155
|
+
if params =~ URL_OR_STRING_PARAM || params.to_s.start_with?(OEMBED_ARG)
|
156
|
+
@fetch_from_context = false
|
157
|
+
@api_request = parse_params_from_string(params)
|
158
|
+
else
|
159
|
+
@fetch_from_context = true
|
160
|
+
@variable_params = normalize_string_params(params)
|
161
|
+
end
|
150
162
|
end
|
151
163
|
|
152
164
|
# Class that implements caching strategy
|
@@ -158,6 +170,12 @@ module TwitterJekyll
|
|
158
170
|
# Return html string for Jekyll engine
|
159
171
|
# @api public
|
160
172
|
def render(context)
|
173
|
+
if fetch_from_context?
|
174
|
+
variable_name, *params = @variable_params
|
175
|
+
tweet_url = context[variable_name]
|
176
|
+
@api_request = parse_params_from_array [tweet_url, *params]
|
177
|
+
end
|
178
|
+
|
161
179
|
api_secrets_deprecation_warning(context) # TODO: remove after deprecation cycle
|
162
180
|
response = cached_response || live_response
|
163
181
|
html_output_for(response)
|
@@ -165,6 +183,10 @@ module TwitterJekyll
|
|
165
183
|
|
166
184
|
private
|
167
185
|
|
186
|
+
def fetch_from_context?
|
187
|
+
@fetch_from_context
|
188
|
+
end
|
189
|
+
|
168
190
|
def cache
|
169
191
|
@cache ||= self.class.cache_klass.new("./.tweet-cache")
|
170
192
|
end
|
@@ -197,11 +219,19 @@ module TwitterJekyll
|
|
197
219
|
build_response(response) unless response.nil?
|
198
220
|
end
|
199
221
|
|
222
|
+
def parse_params_from_string(str)
|
223
|
+
args = normalize_string_params(str)
|
224
|
+
parse_params(args)
|
225
|
+
end
|
226
|
+
|
227
|
+
def parse_params_from_array(arr)
|
228
|
+
parse_params(arr)
|
229
|
+
end
|
230
|
+
|
200
231
|
# Return an `ApiRequest` with the url and arguments
|
201
232
|
# @api private
|
202
|
-
def parse_params(
|
203
|
-
args
|
204
|
-
invalid_args!(args) unless args.any?
|
233
|
+
def parse_params(args)
|
234
|
+
invalid_args!(args) unless args.compact.any?
|
205
235
|
|
206
236
|
if args[0].to_s == OEMBED_ARG # TODO: remove after deprecation cycle
|
207
237
|
arguments_deprecation_warning(args)
|
@@ -209,25 +239,31 @@ module TwitterJekyll
|
|
209
239
|
end
|
210
240
|
|
211
241
|
url, *api_args = args
|
212
|
-
ApiRequest.new(url,
|
242
|
+
ApiRequest.new(url, hash_from_args(api_args))
|
243
|
+
end
|
244
|
+
|
245
|
+
# Take input arguments, remove quotes & return array of argument values
|
246
|
+
# @api private
|
247
|
+
def normalize_string_params(str)
|
248
|
+
str.to_s.gsub(/"|'/, "").split(/\s+/).map(&:strip)
|
213
249
|
end
|
214
250
|
|
215
251
|
# Transform 'a=b x=y' tag arguments into { "a" => "b", "x" => "y" }
|
216
252
|
# @api private
|
217
|
-
def
|
218
|
-
args.each_with_object({}) do |arg,
|
253
|
+
def hash_from_args(args)
|
254
|
+
args.each_with_object({}) do |arg, results|
|
219
255
|
k, v = arg.split("=").map(&:strip)
|
220
256
|
if k && v
|
221
257
|
v = Regexp.last_match[1] if v =~ /^'(.*)'$/
|
222
|
-
|
258
|
+
results[k] = v
|
223
259
|
end
|
224
260
|
end
|
225
261
|
end
|
226
262
|
|
227
263
|
# Format a response hash
|
228
264
|
# @api private
|
229
|
-
def build_response(
|
230
|
-
OpenStruct.new(
|
265
|
+
def build_response(response_hash)
|
266
|
+
OpenStruct.new(response_hash)
|
231
267
|
end
|
232
268
|
|
233
269
|
# TODO: remove after deprecation cycle
|
data/spec/api_request_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
RSpec.describe TwitterJekyll::ApiRequest do
|
3
4
|
subject(:api_request) { described_class.new(url, params) }
|
4
5
|
let(:url) { "https://twitter.com/twitter_user/status/12345" }
|
@@ -23,7 +24,7 @@ RSpec.describe TwitterJekyll::ApiRequest do
|
|
23
24
|
let(:params) { { align: "right" } }
|
24
25
|
|
25
26
|
it "has encoded query params" do
|
26
|
-
expect(URI.decode_www_form(uri.query)).to match_array [["url", url], %w
|
27
|
+
expect(URI.decode_www_form(uri.query)).to match_array [["url", url], %w[align right]]
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
data/spec/integration_tests.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
# Basic integration example - run code to produce html output
|
3
3
|
#
|
4
|
-
# * Requires .env populated with valid Twitter API creds.
|
5
|
-
#
|
6
4
|
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
7
5
|
require_relative "./support/jekyll_template"
|
8
6
|
require "jekyll-twitter-plugin"
|
@@ -47,16 +45,15 @@ class TwitterRenderer
|
|
47
45
|
def render
|
48
46
|
ERB.new(template)
|
49
47
|
.result(binding)
|
50
|
-
.gsub!("src=\"//", "src=\"https://")
|
51
48
|
end
|
52
49
|
|
53
50
|
private
|
54
51
|
|
55
52
|
attr_reader :options, :jekyll_context
|
56
53
|
|
57
|
-
def render_twitter_tag(
|
58
|
-
say_with_colour "Fetching with
|
59
|
-
TwitterJekyll::TwitterTag.new(nil,
|
54
|
+
def render_twitter_tag(option)
|
55
|
+
say_with_colour "Fetching with option: #{option}", :yellow
|
56
|
+
TwitterJekyll::TwitterTag.new(nil, option, nil).render(jekyll_context)
|
60
57
|
end
|
61
58
|
|
62
59
|
def template
|
@@ -76,9 +73,9 @@ class TwitterRenderer
|
|
76
73
|
end
|
77
74
|
|
78
75
|
def main
|
79
|
-
|
76
|
+
renderer = TwitterRenderer.new(OPTIONS)
|
80
77
|
File.open(OUTPUT_FILENAME, "w") do |f|
|
81
|
-
f.write
|
78
|
+
f.write renderer.render
|
82
79
|
end
|
83
80
|
end
|
84
81
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
3
4
|
require "webmock/rspec"
|
4
5
|
require "support/jekyll_template"
|
5
|
-
require "support/shared_contexts"
|
6
6
|
require "jekyll-twitter-plugin"
|
7
7
|
require "byebug" if RUBY_VERSION >= "2.0"
|
8
8
|
|
data/spec/twitter_tag_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
RSpec.describe TwitterJekyll::TwitterTag do
|
3
|
-
let(:context) { empty_jekyll_context }
|
4
|
-
let(:arguments) { "" }
|
5
4
|
let(:api_response_hash) do
|
6
5
|
{
|
7
6
|
"url" => "https://twitter.com/twitter_user/status/12345",
|
@@ -17,17 +16,77 @@ RSpec.describe TwitterJekyll::TwitterTag do
|
|
17
16
|
"version" => "1.0"
|
18
17
|
}
|
19
18
|
end
|
20
|
-
subject { described_class.new(nil, arguments, nil) }
|
21
19
|
|
22
|
-
|
20
|
+
shared_context "without cached response" do
|
21
|
+
let(:cache) { null_cache }
|
22
|
+
|
23
|
+
before do
|
24
|
+
subject.cache = cache
|
25
|
+
end
|
26
|
+
|
27
|
+
def null_cache
|
28
|
+
double("TwitterJekyll::NullCache", read: nil, write: nil)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
shared_context "called with deprecated oembed argument url" do
|
33
|
+
# {% twitter oembed https://twitter.com/twitter_user/status/12345 option=value %}
|
34
|
+
let(:arguments) { "oembed https://twitter.com/twitter_user/status/12345" }
|
35
|
+
let(:context) { empty_jekyll_context }
|
36
|
+
|
37
|
+
subject { described_class.new(nil, arguments, nil) }
|
38
|
+
end
|
39
|
+
|
40
|
+
shared_context "called with url" do
|
41
|
+
# {% twitter https://twitter.com/twitter_user/status/12345 option=value %}
|
23
42
|
let(:arguments) { "https://twitter.com/twitter_user/status/12345" }
|
43
|
+
let(:context) { empty_jekyll_context }
|
24
44
|
|
45
|
+
subject { described_class.new(nil, arguments, nil) }
|
46
|
+
end
|
47
|
+
|
48
|
+
shared_context "called with a page var" do
|
49
|
+
# {% twitter page.tweet option=value %}
|
50
|
+
let(:arguments) { "page.tweet" }
|
51
|
+
let(:context) { jekyll_context_with(arguments, params) }
|
52
|
+
let(:params) { "https://twitter.com/twitter_user/status/12345" }
|
53
|
+
|
54
|
+
subject { described_class.new(nil, arguments, nil) }
|
55
|
+
end
|
56
|
+
|
57
|
+
shared_context "called in a loop with a local var" do
|
58
|
+
# This is the same as above but ensures that same instance can render different contexts
|
59
|
+
# {% for tweet in page.tweets %}
|
60
|
+
# {% twitter tweet option=value %}
|
61
|
+
# {% endfor %}
|
62
|
+
let(:arguments) { "tweet" }
|
63
|
+
let(:context) { jekyll_context_with(arguments, params) }
|
64
|
+
let(:params) { "https://twitter.com/twitter_user/status/12345" }
|
65
|
+
|
66
|
+
subject { described_class.new(nil, arguments, nil) }
|
67
|
+
end
|
68
|
+
|
69
|
+
shared_examples "it does not allow empty arguments" do
|
70
|
+
context "without any arguments" do
|
71
|
+
let(:arguments) { "" }
|
72
|
+
|
73
|
+
it "raises an exception" do
|
74
|
+
expect_to_raise_invalid_args_error(arguments) do
|
75
|
+
subject.render(context)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
shared_examples "it uses a cached response" do
|
25
82
|
context "with cached response" do
|
26
83
|
let(:cache) { double("TwitterJekyll::FileCache") }
|
27
84
|
before do
|
28
85
|
subject.cache = cache
|
29
86
|
end
|
30
87
|
|
88
|
+
let(:arguments) { "https://twitter.com/twitter_user/status/12345" }
|
89
|
+
|
31
90
|
it "renders response from cache" do
|
32
91
|
expect(cache).to receive(:read).with(an_instance_of(String)).and_return(api_response_hash)
|
33
92
|
|
@@ -35,128 +94,298 @@ RSpec.describe TwitterJekyll::TwitterTag do
|
|
35
94
|
expect_output_to_match_tag_content(output, api_response_hash.fetch("html"))
|
36
95
|
end
|
37
96
|
end
|
97
|
+
end
|
38
98
|
|
39
|
-
|
40
|
-
|
99
|
+
shared_examples "it handles api responses" do
|
100
|
+
context "with successful api request" do
|
41
101
|
before do
|
42
|
-
|
43
|
-
allow(cache).to receive(:read).with(an_instance_of(String)).and_return(nil)
|
102
|
+
stub_api_request(status: 200, body: api_response_hash.to_json, headers: {})
|
44
103
|
end
|
45
104
|
|
46
|
-
|
47
|
-
|
48
|
-
stub_api_request(status: 200, body: api_response_hash.to_json, headers: {})
|
49
|
-
end
|
105
|
+
it "renders response from api and writes to cache" do
|
106
|
+
expect(cache).to receive(:write).with(an_instance_of(String), api_response_hash)
|
50
107
|
|
51
|
-
|
52
|
-
|
108
|
+
output = subject.render(context)
|
109
|
+
expect_output_to_match_tag_content(output, api_response_hash.fetch("html"))
|
110
|
+
end
|
111
|
+
end
|
53
112
|
|
54
|
-
|
55
|
-
|
56
|
-
|
113
|
+
context "with a status not found api request" do
|
114
|
+
before do
|
115
|
+
stub_api_request(status: [404, "Not Found"], body: "", headers: {})
|
57
116
|
end
|
58
117
|
|
59
|
-
|
60
|
-
|
61
|
-
stub_api_request(status: [404, "Not Found"], body: "", headers: {})
|
62
|
-
end
|
118
|
+
it "renders error response and writes to cache" do
|
119
|
+
expect(cache).to receive(:write).with(an_instance_of(String), an_instance_of(Hash))
|
63
120
|
|
64
|
-
|
65
|
-
|
121
|
+
output = subject.render(context)
|
122
|
+
expect_output_to_have_error(output, "Not Found")
|
123
|
+
end
|
124
|
+
end
|
66
125
|
|
67
|
-
|
68
|
-
|
69
|
-
|
126
|
+
context "with a status request not permitted api request" do
|
127
|
+
before do
|
128
|
+
stub_api_request(status: [403, "Forbidden"], body: "", headers: {})
|
70
129
|
end
|
71
130
|
|
72
|
-
|
73
|
-
|
74
|
-
stub_api_request(status: [403, "Forbidden"], body: "", headers: {})
|
75
|
-
end
|
131
|
+
it "renders error response and writes to cache" do
|
132
|
+
expect(cache).to receive(:write).with(an_instance_of(String), an_instance_of(Hash))
|
76
133
|
|
77
|
-
|
78
|
-
|
134
|
+
output = subject.render(context)
|
135
|
+
expect_output_to_have_error(output, "Forbidden")
|
136
|
+
end
|
137
|
+
end
|
79
138
|
|
80
|
-
|
81
|
-
|
82
|
-
|
139
|
+
context "with a server error api request" do
|
140
|
+
before do
|
141
|
+
stub_api_request(status: [500, "Internal Server Error"], body: "", headers: {})
|
83
142
|
end
|
84
143
|
|
85
|
-
|
86
|
-
|
87
|
-
stub_api_request(status: [500, "Internal Server Error"], body: "", headers: {})
|
88
|
-
end
|
144
|
+
it "renders error response and writes to cache" do
|
145
|
+
expect(cache).to receive(:write).with(an_instance_of(String), an_instance_of(Hash))
|
89
146
|
|
90
|
-
|
91
|
-
|
147
|
+
output = subject.render(context)
|
148
|
+
expect_output_to_have_error(output, "Internal Server Error")
|
149
|
+
end
|
150
|
+
end
|
92
151
|
|
93
|
-
|
94
|
-
|
95
|
-
|
152
|
+
context "with api request that times out" do
|
153
|
+
before do
|
154
|
+
stub_api.to_timeout
|
96
155
|
end
|
97
156
|
|
98
|
-
|
99
|
-
|
100
|
-
stub_api.to_timeout
|
101
|
-
end
|
157
|
+
it "renders error response and writes to cache" do
|
158
|
+
expect(cache).to receive(:write).with(an_instance_of(String), an_instance_of(Hash))
|
102
159
|
|
103
|
-
|
104
|
-
|
160
|
+
output = subject.render(context)
|
161
|
+
expect_output_to_have_error(output, "Net::OpenTimeout")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
105
165
|
|
106
|
-
|
107
|
-
|
108
|
-
|
166
|
+
describe "output from oembed request" do
|
167
|
+
include_context "called with deprecated oembed argument url"
|
168
|
+
|
169
|
+
it_behaves_like "it does not allow empty arguments"
|
170
|
+
it_behaves_like "it uses a cached response"
|
171
|
+
|
172
|
+
context "without cached response" do
|
173
|
+
include_context "without cached response"
|
174
|
+
|
175
|
+
it "uses correct twitter url and warns of deprecation" do
|
176
|
+
api_client = api_client_double
|
177
|
+
allow(api_client).to receive(:fetch).and_return({})
|
178
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
179
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", {}).and_call_original
|
180
|
+
allow(cache).to receive(:write)
|
181
|
+
|
182
|
+
expect do
|
183
|
+
subject = described_class.new(nil, arguments, nil)
|
184
|
+
subject.render(context)
|
185
|
+
end.to output(/Passing 'oembed' as the first argument is not required anymore/).to_stderr
|
186
|
+
|
187
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/12345", {})
|
109
188
|
end
|
110
189
|
|
111
|
-
context "with
|
112
|
-
let(:arguments) { "oembed https://twitter.com/twitter_user/status/12345" }
|
113
|
-
|
114
|
-
|
190
|
+
context "with options" do
|
191
|
+
let(:arguments) { "oembed https://twitter.com/twitter_user/status/12345 align=right width=350" }
|
192
|
+
|
193
|
+
it "passes options to api" do
|
194
|
+
api_client = api_client_double
|
195
|
+
allow(api_client).to receive(:fetch).and_return({})
|
196
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
197
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", "align" => "right", "width" => "350").and_call_original
|
198
|
+
allow(cache).to receive(:write)
|
199
|
+
|
200
|
+
subject = described_class.new(nil, arguments, nil)
|
201
|
+
subject.cache = cache
|
202
|
+
subject.render(context)
|
203
|
+
|
204
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new)
|
205
|
+
.with("https://twitter.com/twitter_user/status/12345", "align" => "right", "width" => "350")
|
115
206
|
end
|
207
|
+
end
|
208
|
+
|
209
|
+
it_behaves_like "it handles api responses"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "output from url request" do
|
214
|
+
include_context "called with url"
|
215
|
+
|
216
|
+
it_behaves_like "it does not allow empty arguments"
|
217
|
+
it_behaves_like "it uses a cached response"
|
218
|
+
|
219
|
+
context "without cached response" do
|
220
|
+
include_context "without cached response"
|
221
|
+
|
222
|
+
it "uses correct twitter url" do
|
223
|
+
api_client = api_client_double
|
224
|
+
allow(api_client).to receive(:fetch).and_return({})
|
225
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
226
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", {}).and_call_original
|
227
|
+
allow(cache).to receive(:write)
|
228
|
+
|
229
|
+
subject = described_class.new(nil, arguments, nil)
|
230
|
+
subject.render(context)
|
231
|
+
|
232
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/12345", {})
|
233
|
+
end
|
234
|
+
|
235
|
+
context "with options" do
|
236
|
+
let(:arguments) { "https://twitter.com/twitter_user/status/12345 align=right width=350" }
|
237
|
+
|
238
|
+
it "passes options to api" do
|
239
|
+
api_client = api_client_double
|
240
|
+
allow(api_client).to receive(:fetch).and_return({})
|
241
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
242
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", "align" => "right", "width" => "350").and_call_original
|
243
|
+
allow(cache).to receive(:write)
|
116
244
|
|
117
|
-
|
118
|
-
|
245
|
+
subject = described_class.new(nil, arguments, nil)
|
246
|
+
subject.render(context)
|
119
247
|
|
120
|
-
|
121
|
-
|
248
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new)
|
249
|
+
.with("https://twitter.com/twitter_user/status/12345", "align" => "right", "width" => "350")
|
122
250
|
end
|
123
251
|
end
|
252
|
+
|
253
|
+
it_behaves_like "it handles api responses"
|
124
254
|
end
|
125
255
|
end
|
126
256
|
|
127
|
-
describe "
|
128
|
-
|
129
|
-
let(:arguments) { "" }
|
257
|
+
describe "output from usage with front matter var" do
|
258
|
+
include_context "called with a page var"
|
130
259
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
260
|
+
it_behaves_like "it does not allow empty arguments" do
|
261
|
+
let(:arguments) { "page.tweet" }
|
262
|
+
let(:context) { empty_jekyll_context }
|
263
|
+
let(:params) { "" }
|
264
|
+
end
|
265
|
+
|
266
|
+
it_behaves_like "it uses a cached response"
|
267
|
+
|
268
|
+
context "without cached response" do
|
269
|
+
include_context "without cached response"
|
270
|
+
|
271
|
+
it "uses correct twitter url" do
|
272
|
+
api_client = api_client_double
|
273
|
+
allow(api_client).to receive(:fetch).and_return({})
|
274
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
275
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", {}).and_call_original
|
276
|
+
allow(cache).to receive(:write)
|
277
|
+
|
278
|
+
subject = described_class.new(nil, arguments, nil)
|
279
|
+
subject.render(context)
|
280
|
+
|
281
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/12345", {})
|
282
|
+
end
|
283
|
+
|
284
|
+
context "with options" do
|
285
|
+
let(:arguments) { "page.tweet align=left width=400" }
|
286
|
+
let(:context) { jekyll_context_with("page.tweet", params) }
|
287
|
+
let(:params) { "https://twitter.com/twitter_user/status/12345" }
|
288
|
+
|
289
|
+
it "passes options to api" do
|
290
|
+
api_client = api_client_double
|
291
|
+
allow(api_client).to receive(:fetch).and_return({})
|
292
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
293
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", "align" => "left", "width" => "400").and_call_original
|
294
|
+
allow(cache).to receive(:write)
|
295
|
+
|
296
|
+
subject = described_class.new(nil, arguments, nil)
|
297
|
+
subject.render(context)
|
298
|
+
|
299
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new)
|
300
|
+
.with("https://twitter.com/twitter_user/status/12345", "align" => "left", "width" => "400")
|
135
301
|
end
|
136
302
|
end
|
303
|
+
|
304
|
+
it_behaves_like "it handles api responses"
|
137
305
|
end
|
306
|
+
end
|
138
307
|
|
139
|
-
|
140
|
-
|
308
|
+
describe "output from usage in a loop with a local var" do
|
309
|
+
include_context "called in a loop with a local var"
|
141
310
|
|
142
|
-
|
311
|
+
it_behaves_like "it does not allow empty arguments" do
|
312
|
+
let(:arguments) { "tweet" }
|
313
|
+
let(:context) { empty_jekyll_context }
|
314
|
+
let(:params) { "" }
|
315
|
+
end
|
316
|
+
|
317
|
+
it_behaves_like "it uses a cached response"
|
318
|
+
|
319
|
+
context "without cached response" do
|
320
|
+
include_context "without cached response"
|
321
|
+
|
322
|
+
it "uses correct twitter url" do
|
143
323
|
api_client = api_client_double
|
144
324
|
allow(api_client).to receive(:fetch).and_return({})
|
145
325
|
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
146
|
-
|
326
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", {}).and_call_original
|
327
|
+
allow(cache).to receive(:write)
|
147
328
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
329
|
+
subject = described_class.new(nil, arguments, nil)
|
330
|
+
subject.render(context)
|
331
|
+
|
332
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/12345", {})
|
333
|
+
end
|
334
|
+
|
335
|
+
it "handles many contexts passed to same instance" do
|
336
|
+
api_client = api_client_double
|
337
|
+
allow(api_client).to receive(:fetch).and_return({})
|
338
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
339
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/first_url", {}).and_call_original
|
340
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/second_url", {}).and_call_original
|
341
|
+
allow(cache).to receive(:write)
|
342
|
+
|
343
|
+
context = double("context", registers: { site: double(config: {}) }).tap do |c|
|
344
|
+
allow(c).to receive(:[]).with(arguments).and_return(
|
345
|
+
"https://twitter.com/twitter_user/status/first_url",
|
346
|
+
"https://twitter.com/twitter_user/status/second_url"
|
347
|
+
)
|
348
|
+
end
|
349
|
+
|
350
|
+
subject = described_class.new(nil, arguments, nil)
|
351
|
+
subject.render(context)
|
352
|
+
subject.render(context)
|
353
|
+
|
354
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/first_url", {})
|
355
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new).with("https://twitter.com/twitter_user/status/second_url", {})
|
356
|
+
end
|
357
|
+
|
358
|
+
context "with options" do
|
359
|
+
let(:arguments) { "tweet align=middle width=500" }
|
360
|
+
let(:context) { jekyll_context_with("tweet", params) }
|
361
|
+
let(:params) { "https://twitter.com/twitter_user/status/12345" }
|
362
|
+
|
363
|
+
it "passes options to api" do
|
364
|
+
api_client = api_client_double
|
365
|
+
allow(api_client).to receive(:fetch).and_return({})
|
366
|
+
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
367
|
+
allow(TwitterJekyll::ApiRequest).to receive(:new).with("https://twitter.com/twitter_user/status/12345", "align" => "middle", "width" => "500").and_call_original
|
368
|
+
allow(cache).to receive(:write)
|
369
|
+
|
370
|
+
subject = described_class.new(nil, arguments, nil)
|
371
|
+
subject.render(context)
|
372
|
+
|
373
|
+
expect(TwitterJekyll::ApiRequest).to have_received(:new)
|
374
|
+
.with("https://twitter.com/twitter_user/status/12345", "align" => "middle", "width" => "500")
|
375
|
+
end
|
152
376
|
end
|
377
|
+
|
378
|
+
it_behaves_like "it handles api responses"
|
153
379
|
end
|
154
380
|
end
|
155
381
|
|
156
382
|
describe "parsing api secrets" do
|
383
|
+
include_context "called with url"
|
157
384
|
include_context "without cached response"
|
158
|
-
|
159
|
-
|
385
|
+
|
386
|
+
before do
|
387
|
+
stub_api_request(status: 200, body: api_response_hash.to_json, headers: {})
|
388
|
+
end
|
160
389
|
|
161
390
|
context "with api secrets provided by ENV" do
|
162
391
|
let(:context) { double("context", registers: { site: double(config: {}) }) }
|
@@ -177,7 +406,7 @@ RSpec.describe TwitterJekyll::TwitterTag do
|
|
177
406
|
|
178
407
|
context "with api secrets provided by Jekyll config" do
|
179
408
|
let(:context) do
|
180
|
-
api_secrets = %w
|
409
|
+
api_secrets = %w[consumer_key consumer_secret access_token access_token_secret]
|
181
410
|
.each_with_object({}) { |secret, h| h[secret] = secret }
|
182
411
|
double("context", registers:
|
183
412
|
{ site: double(config: { "twitter" => api_secrets }) })
|
@@ -220,7 +449,13 @@ RSpec.describe TwitterJekyll::TwitterTag do
|
|
220
449
|
end
|
221
450
|
|
222
451
|
def empty_jekyll_context
|
223
|
-
double("context", registers: { site: double(config: {}) })
|
452
|
+
double("context", registers: { site: double(config: {}) }, :[] => nil)
|
453
|
+
end
|
454
|
+
|
455
|
+
def jekyll_context_with(var, params)
|
456
|
+
double("context", registers: { site: double(config: {}) }).tap do |c|
|
457
|
+
allow(c).to receive(:[]).with(var).and_return(params)
|
458
|
+
end
|
224
459
|
end
|
225
460
|
|
226
461
|
def api_client_double
|
@@ -237,10 +472,10 @@ RSpec.describe TwitterJekyll::TwitterTag do
|
|
237
472
|
expect_output_to_match_tag_content(actual, "<p>There was a '#{error}' error fetching URL: '#{tweet_url}'</p>")
|
238
473
|
end
|
239
474
|
|
240
|
-
def expect_to_raise_invalid_args_error(
|
475
|
+
def expect_to_raise_invalid_args_error(arguments)
|
241
476
|
raise unless block_given?
|
242
477
|
|
243
|
-
message = "Invalid arguments '#{
|
478
|
+
message = "Invalid arguments '#{arguments}' passed to 'jekyll-twitter-plugin'. Please see 'https://github.com/rob-murray/jekyll-twitter-plugin' for usage."
|
244
479
|
expect do
|
245
480
|
yield
|
246
481
|
end.to raise_error(ArgumentError, message)
|
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-twitter-plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Murray
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +67,7 @@ dependencies:
|
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: rubocop
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,7 +81,7 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: webmock
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -105,7 +119,6 @@ files:
|
|
105
119
|
- spec/integration_tests.rb
|
106
120
|
- spec/spec_helper.rb
|
107
121
|
- spec/support/jekyll_template.rb
|
108
|
-
- spec/support/shared_contexts.rb
|
109
122
|
- spec/twitter_tag_spec.rb
|
110
123
|
homepage: https://github.com/rob-murray/jekyll-twitter-plugin
|
111
124
|
licenses:
|
@@ -126,8 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
139
|
- !ruby/object:Gem::Version
|
127
140
|
version: '0'
|
128
141
|
requirements: []
|
129
|
-
|
130
|
-
rubygems_version: 2.5.1
|
142
|
+
rubygems_version: 3.0.3
|
131
143
|
signing_key:
|
132
144
|
specification_version: 4
|
133
145
|
summary: A Liquid tag plugin for Jekyll blogging engine that embeds Tweets, Timelines
|
@@ -137,5 +149,4 @@ test_files:
|
|
137
149
|
- spec/integration_tests.rb
|
138
150
|
- spec/spec_helper.rb
|
139
151
|
- spec/support/jekyll_template.rb
|
140
|
-
- spec/support/shared_contexts.rb
|
141
152
|
- spec/twitter_tag_spec.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
RSpec.shared_context "without cached response" do
|
3
|
-
let(:cache) { null_cache }
|
4
|
-
|
5
|
-
before do
|
6
|
-
subject.cache = cache
|
7
|
-
end
|
8
|
-
|
9
|
-
def null_cache
|
10
|
-
double("TwitterJekyll::NullCache", read: nil, write: nil)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
RSpec.shared_context "with a normal request and response" do
|
15
|
-
let(:arguments) { "https://twitter.com/twitter_user/status/12345" }
|
16
|
-
let(:response) { { html: "<p>tweet html</p>" } }
|
17
|
-
|
18
|
-
before do
|
19
|
-
allow(api_client).to receive(:fetch).and_return(response)
|
20
|
-
allow(TwitterJekyll::ApiClient).to receive(:new).and_return(api_client)
|
21
|
-
end
|
22
|
-
end
|