Testing: Fix false positive and cover edge case for Channel::Driver::Twitter#fetch
Originally, a spec for race condition handling in Channel::Driver::Twitter#fetch used a `travel_back` call in the wrong place: it needed to be called _after_ `subject!(:channel)` was created, but since it was placed in an `around` block, it ran before all preceding setup blocks. Moving it to a `before` block changed the order in which it was called, thus fixing a false positive in the test. An additional expectation was added to prevent this false positive in the future, and a new test case was added to capture yet another edge case.
This commit is contained in:
parent
3f28c5f54e
commit
29670cd05a
2 changed files with 107 additions and 14 deletions
|
@ -934,12 +934,25 @@ RSpec.describe Channel::Driver::Twitter do
|
||||||
search_term: 'zammadzammadzammad',
|
search_term: 'zammadzammadzammad',
|
||||||
custom_options: {
|
custom_options: {
|
||||||
user: {
|
user: {
|
||||||
# Must match outgoing tweet author Twitter user ID
|
# "outgoing" tweets = authored by this Twitter user ID
|
||||||
id: '1205290247124217856',
|
id: '1205290247124217856',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This test case requires the use_vcr: :time_sensitive option
|
||||||
|
# to travel_to(when the VCR cassette was recorded).
|
||||||
|
#
|
||||||
|
# This ensures that #fetch doesn't ignore
|
||||||
|
# the "older" tweets stored in the VCR cassette,
|
||||||
|
# but it also freezes time,
|
||||||
|
# which breaks this test expectation logic:
|
||||||
|
#
|
||||||
|
# expect { channel.fetch }.to change(Time, :current).by_at_least(5)
|
||||||
|
#
|
||||||
|
# So, we unfreeze time here.
|
||||||
|
before { travel_back }
|
||||||
|
|
||||||
let!(:tweet) { create(:twitter_article, body: 'zammadzammadzammad') }
|
let!(:tweet) { create(:twitter_article, body: 'zammadzammadzammad') }
|
||||||
|
|
||||||
context '(i.e., after the BG job has posted the article to Twitter…' do
|
context '(i.e., after the BG job has posted the article to Twitter…' do
|
||||||
|
@ -954,19 +967,6 @@ RSpec.describe Channel::Driver::Twitter do
|
||||||
YML
|
YML
|
||||||
|
|
||||||
around do |example|
|
around do |example|
|
||||||
# This test case requires the use_vcr: :time_sensitive option
|
|
||||||
# to travel_to(when the VCR cassette was recorded).
|
|
||||||
#
|
|
||||||
# This ensures that #fetch doesn't ignore
|
|
||||||
# the "older" tweets stored in the VCR cassette,
|
|
||||||
# but it also freezes time,
|
|
||||||
# which breaks this race condition handling logic:
|
|
||||||
#
|
|
||||||
# break if Delayed::Job.where('created_at < ?', Time.current).none?
|
|
||||||
#
|
|
||||||
# So, we unfreeze time here.
|
|
||||||
travel_back
|
|
||||||
|
|
||||||
# Run BG job (Why not use Scheduler.worker?
|
# Run BG job (Why not use Scheduler.worker?
|
||||||
# It led to hangs & failures elsewhere in test suite.)
|
# It led to hangs & failures elsewhere in test suite.)
|
||||||
Thread.new do
|
Thread.new do
|
||||||
|
@ -978,9 +978,18 @@ RSpec.describe Channel::Driver::Twitter do
|
||||||
it 'does not import the duplicate tweet (waits up to 60s for BG job to finish)' do
|
it 'does not import the duplicate tweet (waits up to 60s for BG job to finish)' do
|
||||||
expect { channel.fetch }
|
expect { channel.fetch }
|
||||||
.to not_change(Ticket::Article, :count)
|
.to not_change(Ticket::Article, :count)
|
||||||
|
.and change(Time, :current).by_at_least(5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# To reproduce this test case, the VCR cassette has been modified
|
||||||
|
# so that the fetched tweet has a different ("incoming") author user ID.
|
||||||
|
it 'skips race condition handling for incoming tweets' do
|
||||||
|
expect { channel.fetch }
|
||||||
|
.to change(Ticket::Article, :count)
|
||||||
|
.and change(Time, :current).by_at_most(1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
http_interactions:
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://api.twitter.com/1.1/search/tweets.json?count=100&q=zammadzammadzammad&result_type=mixed
|
||||||
|
body:
|
||||||
|
encoding: UTF-8
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- TwitterRubyGem/6.2.0
|
||||||
|
Authorization:
|
||||||
|
- OAuth oauth_consumer_key="REDACTED", oauth_nonce="37876a49fa0c474bd7732dea70083056",
|
||||||
|
oauth_signature="f159trPoyOipHcp%2BPlL33Kh2nO4%3D", oauth_signature_method="HMAC-SHA1",
|
||||||
|
oauth_timestamp="1583840887", oauth_token="REDACTED",
|
||||||
|
oauth_version="1.0"
|
||||||
|
Connection:
|
||||||
|
- close
|
||||||
|
Host:
|
||||||
|
- api.twitter.com
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: OK
|
||||||
|
headers:
|
||||||
|
Cache-Control:
|
||||||
|
- no-cache, no-store, must-revalidate, pre-check=0, post-check=0
|
||||||
|
Connection:
|
||||||
|
- close
|
||||||
|
Content-Disposition:
|
||||||
|
- attachment; filename=json.json
|
||||||
|
Content-Length:
|
||||||
|
- '2346'
|
||||||
|
Content-Type:
|
||||||
|
- application/json;charset=utf-8
|
||||||
|
Date:
|
||||||
|
- Tue, 10 Mar 2020 11:48:07 GMT
|
||||||
|
Expires:
|
||||||
|
- Tue, 31 Mar 1981 05:00:00 GMT
|
||||||
|
Last-Modified:
|
||||||
|
- Tue, 10 Mar 2020 11:48:07 GMT
|
||||||
|
Pragma:
|
||||||
|
- no-cache
|
||||||
|
Server:
|
||||||
|
- tsa_m
|
||||||
|
Set-Cookie:
|
||||||
|
- guest_id=v1%3A158384088754038008; Max-Age=63072000; Expires=Thu, 10 Mar 2022
|
||||||
|
11:48:07 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
|
||||||
|
- lang=en; Path=/
|
||||||
|
- personalization_id="v1_N5oIKIuBSmkhNAVvuM7dWQ=="; Max-Age=63072000; Expires=Thu,
|
||||||
|
10 Mar 2022 11:48:07 GMT; Path=/; Domain=.twitter.com; Secure; SameSite=None
|
||||||
|
Status:
|
||||||
|
- 200 OK
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=631138519
|
||||||
|
X-Access-Level:
|
||||||
|
- read-write-directmessages
|
||||||
|
X-Connection-Hash:
|
||||||
|
- a615db05b45fdf48368de9e967c599c2
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Rate-Limit-Limit:
|
||||||
|
- '180'
|
||||||
|
X-Rate-Limit-Remaining:
|
||||||
|
- '177'
|
||||||
|
X-Rate-Limit-Reset:
|
||||||
|
- '1583841131'
|
||||||
|
X-Response-Time:
|
||||||
|
- '134'
|
||||||
|
X-Transaction:
|
||||||
|
- '004926c000957504'
|
||||||
|
X-Twitter-Response-Tags:
|
||||||
|
- BouncerCompliant
|
||||||
|
X-Xss-Protection:
|
||||||
|
- '0'
|
||||||
|
body:
|
||||||
|
encoding: UTF-8
|
||||||
|
string: '{"statuses":[{"created_at":"Tue Mar 10 11:48:05 +0000 2020","id":1237344473199153152,"id_str":"1237344473199153152","text":"zammadzammadzammad","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"metadata":{"iso_language_code":"lv","result_type":"recent"},"source":"\u003ca
|
||||||
|
href=\"https:\/\/zammad.com\/\" rel=\"nofollow\"\u003ezammad\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":1205290247124217857,"id_str":"1205290247124217857","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
|
||||||
|
Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":19,"lang":null,"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none"},"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"lv"}],"search_metadata":{"completed_in":0.017,"max_id":1237344473199153152,"max_id_str":"1237344473199153152","next_results":"?max_id=1237344473199153151&q=zammadzammadzammad&count=100&include_entities=1&result_type=mixed","query":"zammadzammadzammad","refresh_url":"?since_id=1237344473199153152&q=zammadzammadzammad&result_type=mixed&include_entities=1","count":100,"since_id":0,"since_id_str":"0"}}'
|
||||||
|
http_version:
|
||||||
|
recorded_at: Tue, 10 Mar 2020 11:48:07 GMT
|
Loading…
Reference in a new issue