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',
|
||||
custom_options: {
|
||||
user: {
|
||||
# Must match outgoing tweet author Twitter user ID
|
||||
# "outgoing" tweets = authored by this Twitter user ID
|
||||
id: '1205290247124217856',
|
||||
},
|
||||
})
|
||||
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') }
|
||||
|
||||
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
|
||||
|
||||
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?
|
||||
# It led to hangs & failures elsewhere in test suite.)
|
||||
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
|
||||
expect { channel.fetch }
|
||||
.to not_change(Ticket::Article, :count)
|
||||
.and change(Time, :current).by_at_least(5)
|
||||
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
|
||||
|
||||
|
|
|
@ -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