Rewrite twitter_spec.rb

This commit is contained in:
Ryan Lue 2018-12-13 10:06:44 +01:00
parent eed5fe1459
commit d056feae94
11 changed files with 351 additions and 417 deletions

View file

@ -7,5 +7,44 @@ FactoryBot.define do
preferences {} preferences {}
updated_by_id 1 updated_by_id 1
created_by_id 1 created_by_id 1
factory :twitter_channel do
area 'Twitter::Account'
options do
{
adapter: 'twitter',
auth: {
consumer_key: 'some',
consumer_secret: 'some',
oauth_token: 'key',
oauth_token_secret: 'secret',
},
user: {
screen_name: 'system_login',
id: 'system_id',
},
sync: {
import_older_tweets: true,
track_retweets: true,
search: [
{
term: 'zammad',
group_id: Group.first.id,
},
{
term: 'hash_tag1',
group_id: Group.first.id,
},
],
mentions: {
group_id: Group.first.id,
},
direct_messages: {
group_id: Group.first.id,
}
}
}
end
end
end end
end end

View file

@ -7,5 +7,18 @@ FactoryBot.define do
priority { Ticket::Priority.lookup(name: '2 normal') } priority { Ticket::Priority.lookup(name: '2 normal') }
updated_by_id 1 updated_by_id 1
created_by_id 1 created_by_id 1
factory :twitter_ticket do
transient do
channel { create(:twitter_channel) }
end
preferences do
{
channel_id: channel.id,
channel_screen_name: channel.options[:user][:screen_name]
}
end
end
end end
end end

View file

@ -1,14 +1,28 @@
FactoryBot.define do FactoryBot.define do
factory :ticket_article, class: Ticket::Article do factory :ticket_article, class: Ticket::Article do
transient do
type_name 'email'
sender_name 'Customer'
end
from 'factory-customer-1@example.com' from 'factory-customer-1@example.com'
to 'factory-customer-1@example.com' to 'factory-customer-1@example.com'
subject 'factory article' subject 'factory article'
message_id 'factory@id_com_1' message_id 'factory@id_com_1'
body 'some message 123' body 'some message 123'
internal false internal false
sender { Ticket::Article::Sender.find_by(name: 'Customer') } sender { Ticket::Article::Sender.find_by(name: sender_name) }
type { Ticket::Article::Type.find_by(name: 'email') } type { Ticket::Article::Type.find_by(name: type_name) }
updated_by_id 1 updated_by_id 1
created_by_id 1 created_by_id 1
factory :twitter_article do
transient do
type_name 'twitter status'
end
association :ticket, factory: :twitter_ticket
body { Faker::Lorem.sentence }
end
end end
end end

View file

@ -0,0 +1,75 @@
require 'rails_helper'
RSpec.describe TwitterSync do
describe '.preferences_cleanup' do
describe 'sanitizing Twitter preferences' do
context 'when given as a bare hash' do
it 'automatically adds empty hashes at :geo and :place' do
expect(described_class.preferences_cleanup({}))
.to eq({ geo: {}, place: {} })
end
it 'does not modify values at :mention_ids' do
expect(described_class.preferences_cleanup({ mention_ids: [1_234_567_890] }))
.to include({ mention_ids: [1_234_567_890] })
end
it 'converts geo: instance_of(Twitter::NullOjbect) to empty hash' do
expect(described_class.preferences_cleanup({ geo: Twitter::NullObject.new }))
.to include(geo: {})
end
it 'converts geo: instance_of(Twitter::Geo.new) to matching hash' do
expect(described_class.preferences_cleanup({ geo: Twitter::Geo.new(coordinates: [1, 1]) }))
.to include(geo: { coordinates: [1, 1] })
end
it 'converts place: instance_of(Twitter::NullOjbect) to empty hash' do
expect(described_class.preferences_cleanup({ place: Twitter::NullObject.new }))
.to include(place: {})
end
it 'converts place: instance_of(Twitter::Place.new) to matching hash' do
place_data = { country: 'da', name: 'do', woeid: 1, id: 1 }
expect(described_class.preferences_cleanup({ place: Twitter::Place.new(place_data) }))
.to include(place: place_data)
end
end
context 'when given nested in an article preferences hash' do
it 'automatically adds empty hashes at :geo and :place' do
expect(described_class.preferences_cleanup({ twitter: {} }))
.to eq(twitter: { geo: {}, place: {} })
end
it 'does not modify values at :mention_ids' do
expect(described_class.preferences_cleanup({ twitter: { mention_ids: [1_234_567_890] } }))
.to include(twitter: hash_including(mention_ids: [1_234_567_890]))
end
it 'converts geo: instance_of(Twitter::NullOjbect) to empty hash' do
expect(described_class.preferences_cleanup({ twitter: { geo: Twitter::NullObject.new } }))
.to include(twitter: hash_including(geo: {}))
end
it 'converts geo: instance_of(Twitter::Geo.new) to matching hash' do
expect(described_class.preferences_cleanup({ twitter: { geo: Twitter::Geo.new(coordinates: [1, 1]) } }))
.to include(twitter: hash_including(geo: { coordinates: [1, 1] }))
end
it 'converts place: instance_of(Twitter::NullOjbect) to empty hash' do
expect(described_class.preferences_cleanup({ twitter: { place: Twitter::NullObject.new } }))
.to include(twitter: hash_including(place: {}))
end
it 'converts place: instance_of(Twitter::Place.new) to matching hash' do
place_data = { country: 'da', name: 'do', woeid: 1, id: 1 }
expect(described_class.preferences_cleanup({ twitter: { place: Twitter::Place.new(place_data) } }))
.to include(twitter: hash_including(place: place_data))
end
end
end
end
end

View file

@ -1,395 +0,0 @@
require 'rails_helper'
require_dependency 'channel/driver/twitter'
RSpec.describe ::Channel::Driver::Twitter do
let(:channel) do
create(
:channel,
area: 'Twitter::Account',
options: {
adapter: 'twitter',
auth: {
consumer_key: 'some',
consumer_secret: 'some',
oauth_token: 'key',
oauth_token_secret: 'secret',
},
user: {
screen_name: 'system_login',
id: 'system_id',
},
sync: {
import_older_tweets: true,
track_retweets: true,
search: [
{
term: 'zammad',
group_id: Group.first.id,
},
{
term: 'hash_tag1',
group_id: Group.first.id,
},
],
mentions: {
group_id: Group.first.id,
},
direct_messages: {
group_id: Group.first.id,
}
}
},
active: true,
created_by_id: 1,
updated_by_id: 1
)
end
it 'fetch channel with invalid token' do
VCR.use_cassette('models/channel/driver/twitter/fetch_channel_invalid') do
expect(channel.fetch(true)).to be false
end
channel.reload
expect(channel.status_in).to eq('error')
expect(channel.last_log_in).to eq('Can\'t use Channel::Driver::Twitter: #<Twitter::Error::Unauthorized: Invalid or expired token.>')
expect(channel.status_out).to be nil
expect(channel.last_log_out).to be nil
end
it 'fetch channel with valid token' do
expect(Ticket.count).to eq(1)
VCR.use_cassette('models/channel/driver/twitter/fetch_channel_valid') do
expect(channel.fetch(true)).to be true
end
expect(Ticket.count).to eq(27)
ticket = Ticket.last
expect(ticket.title).to eq('Wir haben unsere DMs deaktiviert. Leider können wir dank der neuen Twitter API k...')
expect(ticket.preferences[:channel_id]).to eq(channel.id)
expect(ticket.preferences[:channel_screen_name]).to eq(channel.options[:user][:screen_name])
expect(ticket.customer.firstname).to eq('Ccc')
expect(ticket.customer.lastname).to eq('Event Logistics')
channel.reload
expect(channel.status_in).to eq('ok')
expect(channel.last_log_in).to eq('')
expect(channel.status_out).to be nil
expect(channel.last_log_out).to be nil
end
it 'send tweet based on article - outbound' do
user = User.find(2)
text = 'Today the weather is really...'
ticket = Ticket.create!(
title: text[0, 40],
customer_id: user.id,
group_id: Group.first.id,
state: Ticket::State.find_by(name: 'new'),
priority: Ticket::Priority.find_by(name: '2 normal'),
preferences: {
channel_id: channel.id,
channel_screen_name: 'system_login',
},
updated_by_id: 1,
created_by_id: 1,
)
assert(ticket, "outbound ticket created, text: #{text}")
article = Ticket::Article.create!(
ticket_id: ticket.id,
body: text,
type: Ticket::Article::Type.find_by(name: 'twitter status'),
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
internal: false,
updated_by_id: 1,
created_by_id: 1,
)
VCR.use_cassette('models/channel/driver/twitter/article_to_tweet') do
Scheduler.worker(true)
end
ticket.reload
expect(ticket.state.name).to eq('open')
expect(ticket.group.name).to eq(Group.first.name)
expect(ticket.title).to eq('Today the weather is really...')
article.reload
expect(article.from).to eq('@example')
expect(article.to).to eq('')
expect(article.cc).to be nil
expect(article.subject).to be nil
expect(article.sender.name).to eq('Agent')
expect(article.type.name).to eq('twitter status')
expect(article.message_id).to eq('1069382411899817990')
expect(article.content_type).to eq('text/plain')
expect(article.body).to eq('Today the weather is really...')
expect(article.preferences[:links][0][:url]).to eq('https://twitter.com/statuses/1069382411899817990')
expect(article.preferences[:links][0][:target]).to eq('_blank')
expect(article.preferences[:links][0][:name]).to eq('on Twitter')
channel.reload
expect(channel.status_in).to be nil
expect(channel.last_log_in).to be nil
expect(channel.status_out).to eq('ok')
expect(channel.last_log_out).to eq('')
end
it 'send tweet based on article - with replaced channel' do
user = User.find(2)
text = 'Today and tomorrow the weather is really...'
ticket = Ticket.create!(
title: text[0, 40],
customer_id: user.id,
group_id: Group.first.id,
state: Ticket::State.find_by(name: 'new'),
priority: Ticket::Priority.find_by(name: '2 normal'),
preferences: {
channel_id: 'some_other_id',
channel_screen_name: 'system_login',
},
updated_by_id: 1,
created_by_id: 1,
)
assert(ticket, "outbound ticket created, text: #{text}")
article = Ticket::Article.create!(
ticket_id: ticket.id,
body: text,
type: Ticket::Article::Type.find_by(name: 'twitter status'),
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
internal: false,
updated_by_id: 1,
created_by_id: 1,
)
channel.reload
expect(channel.options[:user][:screen_name]).not_to be ticket.preferences[:channel_screen_name]
expect(channel.status_in).to be nil
expect(channel.last_log_in).to be nil
expect(channel.status_out).to be nil
expect(channel.last_log_out).to be nil
VCR.use_cassette('models/channel/driver/twitter/article_to_tweet_channel_replace') do
Scheduler.worker(true)
end
ticket.reload
expect(ticket.state.name).to eq('open')
expect(ticket.group.name).to eq(Group.first.name)
expect(ticket.title).to eq('Today and tomorrow the weather is really')
article.reload
expect(article.from).to eq('@example')
expect(article.to).to eq('')
expect(article.cc).to be nil
expect(article.subject).to be nil
expect(article.sender.name).to eq('Agent')
expect(article.type.name).to eq('twitter status')
expect(article.message_id).to eq('1069382411899817991')
expect(article.content_type).to eq('text/plain')
expect(article.body).to eq('Today and tomorrow the weather is really...')
expect(article.preferences[:links][0][:url]).to eq('https://twitter.com/statuses/1069382411899817991')
expect(article.preferences[:links][0][:target]).to eq('_blank')
expect(article.preferences[:links][0][:name]).to eq('on Twitter')
channel.reload
expect(channel.status_in).to be nil
expect(channel.last_log_in).to be nil
expect(channel.status_out).to eq('ok')
expect(channel.last_log_out).to eq('')
end
it 'article preferences' do
org_community = Organization.create_if_not_exists(
name: 'Zammad Foundation',
)
user_community = User.create_or_update(
login: 'article.twitter@example.org',
firstname: 'Article',
lastname: 'Twitter',
email: 'article.twitter@example.org',
password: '',
active: true,
roles: [ Role.find_by(name: 'Customer') ],
organization_id: org_community.id,
updated_by_id: 1,
created_by_id: 1,
)
ticket1 = Ticket.create!(
group_id: Group.first.id,
customer_id: user_community.id,
title: 'Tweet 1!',
updated_by_id: 1,
created_by_id: 1,
)
twitter_preferences = {
mention_ids: [1_234_567_890],
geo: Twitter::NullObject.new,
retweeted: false,
possibly_sensitive: false,
in_reply_to_user_id: 1_234_567_890,
place: Twitter::NullObject.new,
retweet_count: 0,
source: '<a href="http://example.com/software/tweetbot/mac" rel="nofollow">Tweetbot for Mac</a>',
favorited: false,
truncated: false
}
preferences = {
twitter: TwitterSync.preferences_cleanup(twitter_preferences),
links: [
{
url: 'https://twitter.com/statuses/123',
target: '_blank',
name: 'on Twitter',
},
],
}
article1 = Ticket::Article.create!(
ticket_id: ticket1.id,
type_id: Ticket::Article::Type.find_by(name: 'twitter status').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: '@example',
body: 'some tweet',
internal: false,
preferences: TwitterSync.preferences_cleanup(preferences),
updated_by_id: 1,
created_by_id: 1,
)
expect(article1.preferences[:twitter]).to be_truthy
expect(article1.preferences[:twitter][:mention_ids][0]).to eq(1_234_567_890)
expect(article1.preferences[:twitter][:geo].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article1.preferences[:twitter][:geo].blank?).to be true
expect(article1.preferences[:twitter][:place].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article1.preferences[:twitter][:place].blank?).to be true
twitter_preferences = {
mention_ids: [1_234_567_890],
geo: Twitter::NullObject.new,
retweeted: false,
possibly_sensitive: false,
in_reply_to_user_id: 1_234_567_890,
place: Twitter::NullObject.new,
retweet_count: 0,
source: '<a href="http://example.com/software/tweetbot/mac" rel="nofollow">Tweetbot for Mac</a>',
favorited: false,
truncated: false
}
preferences = TwitterSync.preferences_cleanup(
twitter: twitter_preferences,
links: [
{
url: 'https://twitter.com/statuses/123',
target: '_blank',
name: 'on Twitter',
},
],
)
article2 = Ticket::Article.create!(
ticket_id: ticket1.id,
type_id: Ticket::Article::Type.find_by(name: 'twitter status').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: '@example',
body: 'some tweet',
internal: false,
preferences: TwitterSync.preferences_cleanup(preferences),
updated_by_id: 1,
created_by_id: 1,
)
expect(article2.preferences[:twitter]).to be_truthy
expect(article2.preferences[:twitter][:mention_ids][0]).to eq(1_234_567_890)
expect(article1.preferences[:twitter][:geo].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article1.preferences[:twitter][:geo].blank?).to be true
expect(article1.preferences[:twitter][:place].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article1.preferences[:twitter][:place].blank?).to be true
twitter_preferences = {
mention_ids: [1_234_567_890],
geo: Twitter::Geo.new(coordinates: [1, 1]),
retweeted: false,
possibly_sensitive: false,
in_reply_to_user_id: 1_234_567_890,
place: Twitter::Place.new(country: 'da', name: 'do', woeid: 1, id: 1),
retweet_count: 0,
source: '<a href="http://example.com/software/tweetbot/mac" rel="nofollow">Tweetbot for Mac</a>',
favorited: false,
truncated: false
}
preferences = {
twitter: TwitterSync.preferences_cleanup(twitter_preferences),
links: [
{
url: 'https://twitter.com/statuses/123',
target: '_blank',
name: 'on Twitter',
},
],
}
article3 = Ticket::Article.create!(
ticket_id: ticket1.id,
type_id: Ticket::Article::Type.find_by(name: 'twitter status').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: '@example',
body: 'some tweet',
internal: false,
preferences: preferences,
updated_by_id: 1,
created_by_id: 1,
)
expect(article3.preferences[:twitter]).to be_truthy
expect(article3.preferences[:twitter][:mention_ids][0]).to eq(1_234_567_890)
expect(article3.preferences[:twitter][:geo].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article3.preferences[:twitter][:geo]).to eq({ 'coordinates' => [1, 1] })
expect(article3.preferences[:twitter][:place].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article3.preferences[:twitter][:place]).to eq({ 'country' => 'da', 'name' => 'do', 'woeid' => 1, 'id' => 1 })
twitter_preferences = {
mention_ids: [1_234_567_890],
geo: Twitter::Geo.new(coordinates: [1, 1]),
retweeted: false,
possibly_sensitive: false,
in_reply_to_user_id: 1_234_567_890,
place: Twitter::Place.new(country: 'da', name: 'do', woeid: 1, id: 1),
retweet_count: 0,
source: '<a href="http://example.com/software/tweetbot/mac" rel="nofollow">Tweetbot for Mac</a>',
favorited: false,
truncated: false
}
preferences = TwitterSync.preferences_cleanup(
twitter: twitter_preferences,
links: [
{
url: 'https://twitter.com/statuses/123',
target: '_blank',
name: 'on Twitter',
},
],
)
article4 = Ticket::Article.create!(
ticket_id: ticket1.id,
type_id: Ticket::Article::Type.find_by(name: 'twitter status').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
from: '@example',
body: 'some tweet',
internal: false,
preferences: preferences,
updated_by_id: 1,
created_by_id: 1,
)
expect(article4.preferences[:twitter]).to be_truthy
expect(article4.preferences[:twitter]).to be_truthy
expect(article4.preferences[:twitter][:mention_ids][0]).to eq(1_234_567_890)
expect(article4.preferences[:twitter][:geo].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article4.preferences[:twitter][:geo]).to eq({ 'coordinates' => [1, 1] })
expect(article4.preferences[:twitter][:place].class).to be ActiveSupport::HashWithIndifferentAccess
expect(article4.preferences[:twitter][:place]).to eq({ 'country' => 'da', 'name' => 'do', 'woeid' => 1, 'id' => 1 })
end
end

View file

@ -0,0 +1,65 @@
require 'rails_helper'
RSpec.describe Channel do
describe '#fetch' do
around do |example|
VCR.use_cassette(cassette, match_requests_on: %i[method uri oauth_headers]) { example.run }
end
context 'for Twitter driver' do
subject(:twitter_channel) { create(:twitter_channel) }
context 'with invalid token' do
let(:cassette) { 'models/channel/driver/twitter/fetch_channel_invalid' }
it 'returns false' do
expect(twitter_channel.fetch(true)).to be(false)
end
it 'sets error/nil status attributes' do
expect { twitter_channel.fetch(true) }
.to change { twitter_channel.reload.attributes }
.to hash_including(
'status_in' => 'error',
'last_log_in' => "Can't use Channel::Driver::Twitter: " \
'#<Twitter::Error::Unauthorized: Invalid or expired token.>',
'status_out' => nil,
'last_log_out' => nil
)
end
end
context 'with valid token' do
let(:cassette) { 'models/channel/driver/twitter/fetch_channel_valid' }
it 'returns true' do
expect(twitter_channel.fetch(true)).to be(true)
end
it 'sets successful status attributes' do
expect { twitter_channel.fetch(true) }
.to change { twitter_channel.reload.attributes }
.to hash_including(
'status_in' => 'ok',
'last_log_in' => '',
'status_out' => nil,
'last_log_out' => nil
)
end
it 'adds tickets as appropriate' do
expect { twitter_channel.fetch(true) }
.to change { Ticket.count }.by(26)
expect(Ticket.last.attributes).to include(
'title' => 'Wir haben unsere DMs deaktiviert. ' \
'Leider können wir dank der neuen Twitter API k...',
'preferences' => { 'channel_id' => twitter_channel.id,
'channel_screen_name' => twitter_channel.options[:user][:screen_name] },
'customer_id' => User.find_by(firstname: 'Ccc', lastname: 'Event Logistics').id
)
end
end
end
end
end

View file

@ -0,0 +1,115 @@
require 'rails_helper'
RSpec.describe Ticket::Article do
describe 'hooks on creation' do
context 'of outgoing article' do
context 'over Twitter' do
subject!(:twitter_article) { create(:twitter_article, sender_name: 'Agent') }
let(:channel) { Channel.find(twitter_article.ticket.preferences[:channel_id]) }
describe 'background job actions' do
let(:run_bg_jobs) do
lambda do
VCR.use_cassette(cassette, match_requests_on: %i[method uri oauth_headers]) do
Scheduler.worker(true)
end
end
end
let(:cassette) { 'models/channel/driver/twitter/article_to_tweet' }
it 'sets #from attribute to senders Twitter handle' do
expect(&run_bg_jobs)
.to change { twitter_article.reload.from }
.to('@example')
end
it 'sets #to attribute to recipients Twitter handle' do
expect(&run_bg_jobs)
.to change { twitter_article.reload.to }
.to('') # Tweet in VCR cassette is addressed to no one
end
it 'sets #message_id attribute to tweet ID (https://twitter.com/statuses/<id>)' do
expect(&run_bg_jobs)
.to change { twitter_article.reload.message_id }
.to('1069382411899817990')
end
it 'sets #preferences hash with tweet metadata' do
expect(&run_bg_jobs)
.to change { twitter_article.reload.preferences }
.to(hash_including('twitter', 'links'))
expect(twitter_article.preferences[:links].first)
.to include(
'name' => 'on Twitter',
'target' => '_blank',
'url' => "https://twitter.com/statuses/#{twitter_article.message_id}"
)
end
it 'does not change #cc attribute' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.cc }
end
it 'does not change #subject attribute' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.subject }
end
it 'does not change #content_type attribute' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.content_type }
end
it 'does not change #body attribute' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.body }
end
it 'does not change #sender association' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.sender }
end
it 'does not change #type association' do
expect(&run_bg_jobs).not_to change { twitter_article.reload.type }
end
it 'sets appropriate status attributes on the tickets channel' do
expect(&run_bg_jobs)
.to change { channel.reload.attributes }
.to hash_including(
'status_in' => nil,
'last_log_in' => nil,
'status_out' => 'ok',
'last_log_out' => ''
)
end
context 'when the original channel (specified in ticket.preferences) was deleted' do
context 'but a new one with the same screen_name exists' do
let(:cassette) { 'models/channel/driver/twitter/article_to_tweet_channel_replace' }
let(:new_channel) { create(:twitter_channel) }
before do
channel.destroy
expect(new_channel.options[:user][:screen_name])
.to eq(channel.options[:user][:screen_name])
end
it 'sets appropriate status attributes on the new channel' do
expect(&run_bg_jobs)
.to change { new_channel.reload.attributes }
.to hash_including(
'status_in' => nil,
'last_log_in' => nil,
'status_out' => 'ok',
'last_log_out' => ''
)
end
end
end
end
end
end
end
end

View file

@ -10,4 +10,12 @@ VCR.configure do |config|
uri.host.include?(site) uri.host.include?(site)
end end
end end
config.register_request_matcher(:oauth_headers) do |r1, r2|
without_onetime_oauth_params = ->(params) { params.gsub(/oauth_(nonce|signature|timestamp)="[^"]+", /, '') }
r1.headers.except('Authorization') == r2.headers.except('Authorization') &&
r1.headers['Authorization']&.map(&without_onetime_oauth_params) ==
r2.headers['Authorization']&.map(&without_onetime_oauth_params)
end
end end

View file

@ -12,7 +12,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="some", - OAuth oauth_consumer_key="some", oauth_nonce="some",
oauth_signature="some%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="some%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795610", oauth_token="some", oauth_timestamp="1543795610", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close

View file

@ -12,7 +12,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="some", - OAuth oauth_consumer_key="some", oauth_nonce="some",
oauth_signature="some%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="some%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795610", oauth_token="some", oauth_timestamp="1543795610", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close

View file

@ -12,7 +12,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="8efb0d12349b48e6acaa2ec6ff224cc2", - OAuth oauth_consumer_key="some", oauth_nonce="8efb0d12349b48e6acaa2ec6ff224cc2",
oauth_signature="uABvZoC5sN%2F68E4oxp6Qk6SxO2Y%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="uABvZoC5sN%2F68E4oxp6Qk6SxO2Y%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795852", oauth_token="some", oauth_timestamp="1543795852", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -526,7 +526,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="83003a1356235c21998dbe47bd20e034", - OAuth oauth_consumer_key="some", oauth_nonce="83003a1356235c21998dbe47bd20e034",
oauth_signature="KtBt4mbxUM9pQeEHXi%2BywugYuqk%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="KtBt4mbxUM9pQeEHXi%2BywugYuqk%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795853", oauth_token="some", oauth_timestamp="1543795853", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -771,7 +771,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="bb5275ca035610773ca6172601e35be6", - OAuth oauth_consumer_key="some", oauth_nonce="bb5275ca035610773ca6172601e35be6",
oauth_signature="yk2RDPjsEnljxqdWfmCOjS01ylg%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="yk2RDPjsEnljxqdWfmCOjS01ylg%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795854", oauth_token="some", oauth_timestamp="1543795854", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -1229,7 +1229,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="756b2ebc88106059e7afdec3979455ed", - OAuth oauth_consumer_key="some", oauth_nonce="756b2ebc88106059e7afdec3979455ed",
oauth_signature="KYRdmzJiODGS%2BYqqmYUPhwq2Fwc%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="KYRdmzJiODGS%2BYqqmYUPhwq2Fwc%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795855", oauth_token="some", oauth_timestamp="1543795855", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -1421,7 +1421,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="de1e719ccd92c862ad99062c09332301", - OAuth oauth_consumer_key="some", oauth_nonce="de1e719ccd92c862ad99062c09332301",
oauth_signature="ueto3kSV%2BcRxu%2FXOod5N4CqW%2BNk%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="ueto3kSV%2BcRxu%2FXOod5N4CqW%2BNk%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795855", oauth_token="some", oauth_timestamp="1543795855", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -1666,7 +1666,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="4b3ceecc83d55c1b720580fb1e3d36db", - OAuth oauth_consumer_key="some", oauth_nonce="4b3ceecc83d55c1b720580fb1e3d36db",
oauth_signature="sYaGT3aj%2BUSwTMuTWouWuQti3BQ%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="sYaGT3aj%2BUSwTMuTWouWuQti3BQ%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795856", oauth_token="some", oauth_timestamp="1543795856", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -1966,7 +1966,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="9778307d17972ae3edc5b5d2a5530bb4", - OAuth oauth_consumer_key="some", oauth_nonce="9778307d17972ae3edc5b5d2a5530bb4",
oauth_signature="qf8Acv3oYLzER%2BF53HL%2F7xQfbvM%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="qf8Acv3oYLzER%2BF53HL%2F7xQfbvM%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795857", oauth_token="some", oauth_timestamp="1543795857", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -2215,7 +2215,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="7ff1412c085625c63956f13fee4a0066", - OAuth oauth_consumer_key="some", oauth_nonce="7ff1412c085625c63956f13fee4a0066",
oauth_signature="XTJJazMUukMF7V0QJysnt0RIbV0%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="XTJJazMUukMF7V0QJysnt0RIbV0%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795857", oauth_token="some", oauth_timestamp="1543795857", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -3371,7 +3371,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="db0fdd3eedd9c9a4c4a7dea0f6dd3cc9", - OAuth oauth_consumer_key="some", oauth_nonce="db0fdd3eedd9c9a4c4a7dea0f6dd3cc9",
oauth_signature="5OrIGadCeuoU%2BpDkNkUYviu0awo%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="5OrIGadCeuoU%2BpDkNkUYviu0awo%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795861", oauth_token="some", oauth_timestamp="1543795861", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -3511,7 +3511,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="12ed1f52923c07c7a35ea78d2d177e7d", - OAuth oauth_consumer_key="some", oauth_nonce="12ed1f52923c07c7a35ea78d2d177e7d",
oauth_signature="UEKkeqCiwZnRNZK2xL9yFh2jYLA%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="UEKkeqCiwZnRNZK2xL9yFh2jYLA%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795862", oauth_token="some", oauth_timestamp="1543795862", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -4498,7 +4498,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="df1d4b0020304d719b581ad2a89ac722", - OAuth oauth_consumer_key="some", oauth_nonce="df1d4b0020304d719b581ad2a89ac722",
oauth_signature="ZVjS8VWcWdYXZpr2I3ZX56DOWTE%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="ZVjS8VWcWdYXZpr2I3ZX56DOWTE%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795865", oauth_token="some", oauth_timestamp="1543795865", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -4746,7 +4746,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="2dbf57fffac364cfd3d3bb63b01ca49f", - OAuth oauth_consumer_key="some", oauth_nonce="2dbf57fffac364cfd3d3bb63b01ca49f",
oauth_signature="DoKz2xUY3qPs%2Bnscylkyemx7acY%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="DoKz2xUY3qPs%2Bnscylkyemx7acY%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795866", oauth_token="some", oauth_timestamp="1543795866", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -5046,7 +5046,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="43788c0bf65af0ea0e0e59b029a98a58", - OAuth oauth_consumer_key="some", oauth_nonce="43788c0bf65af0ea0e0e59b029a98a58",
oauth_signature="8H%2Bw00OP0m9rjOpLRdQia%2BOjtIo%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="8H%2Bw00OP0m9rjOpLRdQia%2BOjtIo%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795866", oauth_token="some", oauth_timestamp="1543795866", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -5298,7 +5298,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="813d8700f25ff78f741b2c778b312cf7", - OAuth oauth_consumer_key="some", oauth_nonce="813d8700f25ff78f741b2c778b312cf7",
oauth_signature="Ha0OSsfG5yFKzMdNbRHC2Fn9tKo%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="Ha0OSsfG5yFKzMdNbRHC2Fn9tKo%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795867", oauth_token="some", oauth_timestamp="1543795867", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -5861,7 +5861,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="6ba7598ee7171aa89d5172a75b5e7634", - OAuth oauth_consumer_key="some", oauth_nonce="6ba7598ee7171aa89d5172a75b5e7634",
oauth_signature="RrL7Yjl6GE4OJ4IJX4H5GiYLFJU%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="RrL7Yjl6GE4OJ4IJX4H5GiYLFJU%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795868", oauth_token="some", oauth_timestamp="1543795868", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -6107,7 +6107,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="3a2fab4325efb72a9fe7f466fdb96910", - OAuth oauth_consumer_key="some", oauth_nonce="3a2fab4325efb72a9fe7f466fdb96910",
oauth_signature="%2BwYKPEqhsVvUK7IDnOSZpB4J1h0%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="%2BwYKPEqhsVvUK7IDnOSZpB4J1h0%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795869", oauth_token="some", oauth_timestamp="1543795869", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -6301,7 +6301,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="bab0a69fdb7b4718244cb9e3a86f28d4", - OAuth oauth_consumer_key="some", oauth_nonce="bab0a69fdb7b4718244cb9e3a86f28d4",
oauth_signature="WrbLQ6TcP7153IxnujSFyoJ462w%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="WrbLQ6TcP7153IxnujSFyoJ462w%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795870", oauth_token="some", oauth_timestamp="1543795870", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close
@ -6495,7 +6495,7 @@ http_interactions:
Authorization: Authorization:
- OAuth oauth_consumer_key="some", oauth_nonce="b88d83169c5ad58749312e180ccb580a", - OAuth oauth_consumer_key="some", oauth_nonce="b88d83169c5ad58749312e180ccb580a",
oauth_signature="mwtfaPm2G4x5pRnOr79wWj%2F4UOc%3D", oauth_signature_method="HMAC-SHA1", oauth_signature="mwtfaPm2G4x5pRnOr79wWj%2F4UOc%3D", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1543795870", oauth_token="some", oauth_timestamp="1543795870", oauth_token="key",
oauth_version="1.0" oauth_version="1.0"
Connection: Connection:
- close - close