patient_zero 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/lib/patient_zero/analytics/base.rb +35 -0
- data/lib/patient_zero/analytics/facebook.rb +25 -0
- data/lib/patient_zero/analytics/instagram.rb +13 -0
- data/lib/patient_zero/analytics/twitter.rb +13 -0
- data/lib/patient_zero/analytics.rb +16 -0
- data/lib/patient_zero/authorization.rb +8 -0
- data/lib/patient_zero/client.rb +35 -0
- data/lib/patient_zero/configurable.rb +21 -0
- data/lib/patient_zero/errors.rb +4 -0
- data/lib/patient_zero/message/base.rb +11 -0
- data/lib/patient_zero/message/facebook.rb +29 -0
- data/lib/patient_zero/message/instagram.rb +29 -0
- data/lib/patient_zero/message/twitter.rb +21 -0
- data/lib/patient_zero/message.rb +16 -0
- data/lib/patient_zero/organization.rb +27 -0
- data/lib/patient_zero/source.rb +36 -0
- data/lib/patient_zero/version.rb +1 -1
- data/lib/patient_zero.rb +19 -2
- data/patient_zero.gemspec +13 -8
- data/spec/patient_zero/analytics/base_spec.rb +54 -0
- data/spec/patient_zero/analytics/facebook_spec.rb +40 -0
- data/spec/patient_zero/analytics/instagram_spec.rb +35 -0
- data/spec/patient_zero/analytics/twitter_spec.rb +34 -0
- data/spec/patient_zero/analytics_spec.rb +29 -0
- data/spec/patient_zero/authorization_spec.rb +26 -0
- data/spec/patient_zero/client_spec.rb +31 -0
- data/spec/patient_zero/message/facebook_spec.rb +52 -0
- data/spec/patient_zero/message/instagram_spec.rb +53 -0
- data/spec/patient_zero/message/twitter_spec.rb +40 -0
- data/spec/patient_zero/message_spec.rb +29 -0
- data/spec/patient_zero/organization_spec.rb +67 -0
- data/spec/patient_zero/source_spec.rb +83 -0
- data/spec/spec_helper.rb +14 -0
- metadata +106 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44dbcc4b6d6cf236eb77f548a0b764e7816b7962
|
4
|
+
data.tar.gz: 33e6b2e9170ebe01eb61ddb7bb3ddd61661e4e16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7129206bd4afe74fdb1708a02d6fcfc8040845cd04fec49b67916f8aa928193b27976905a24f0db7dd784d9195c2bc9099c8ce278ffd2cc3897c332bd88d76fe
|
7
|
+
data.tar.gz: 10c63b464b5426341cd6393be167ff564ff5dc99a5356fe1493fcd6cc435e52b3fbbe8587ff12761b91437a8b0c7a881c33cd37cb477c51e4809c9d44336f3f2
|
data/.rspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Analytics
|
3
|
+
class Base < Client
|
4
|
+
attr_accessor :token, :source_id, :start_date, :end_date
|
5
|
+
|
6
|
+
def initialize token:, source_id:, start_date: nil, end_date: nil
|
7
|
+
@token = token
|
8
|
+
@source_id = source_id
|
9
|
+
@end_date = end_date || Date.today.to_s
|
10
|
+
@start_date = start_date || Date.today.prev_day(7).to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
analytical_data['name']
|
15
|
+
end
|
16
|
+
|
17
|
+
def platform
|
18
|
+
analytical_data['platform']
|
19
|
+
end
|
20
|
+
|
21
|
+
def messages
|
22
|
+
analytical_data['messages'].map { |message| Message.for_platform message['platform'], message }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def analytical_data
|
28
|
+
@analytical_data ||= get('/mobile/api/v1/analytics', client_token: token,
|
29
|
+
social_object_uid: source_id,
|
30
|
+
start_date: start_date,
|
31
|
+
end_date: end_date)['stats'].first
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Analytics
|
3
|
+
class Facebook < Base
|
4
|
+
def engagements
|
5
|
+
@engagements ||= messages.reduce(0) { |sum, message| sum + message.engagements }
|
6
|
+
end
|
7
|
+
|
8
|
+
def impressions
|
9
|
+
page_impressions + message_impressions
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def message_impressions
|
15
|
+
messages.reduce(0) { |sum, message| sum + message.impressions }
|
16
|
+
end
|
17
|
+
|
18
|
+
def page_impressions
|
19
|
+
analytical_data['page_impressions'].find do |impressions_hash|
|
20
|
+
impressions_hash['key'] == 'Total'
|
21
|
+
end['values'].each_value.reduce(:+)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Analytics
|
3
|
+
class Instagram < Base
|
4
|
+
def engagements
|
5
|
+
@engagements ||= messages.reduce(0) { |sum, message| sum + message.engagements }
|
6
|
+
end
|
7
|
+
|
8
|
+
def impressions
|
9
|
+
@impressions ||= messages.reduce(0) { |sum, message| sum + message.impressions }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'patient_zero/analytics/base'
|
2
|
+
require 'patient_zero/analytics/twitter'
|
3
|
+
require 'patient_zero/analytics/facebook'
|
4
|
+
require 'patient_zero/analytics/instagram'
|
5
|
+
|
6
|
+
module PatientZero
|
7
|
+
module Analytics
|
8
|
+
SOURCE_TYPES = {'twitter' => Twitter,
|
9
|
+
'facebook' => Facebook,
|
10
|
+
'instagram' => Instagram}
|
11
|
+
|
12
|
+
def self.for_platform platform, params={}
|
13
|
+
SOURCE_TYPES[platform].new params
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module PatientZero
|
2
|
+
class Client
|
3
|
+
def self.connection
|
4
|
+
@@connection ||= Faraday.new(PatientZero.url) do |faraday|
|
5
|
+
faraday.request :url_encoded
|
6
|
+
faraday.response :logger
|
7
|
+
faraday.adapter Faraday.default_adapter
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parse request
|
12
|
+
response = JSON.parse request.body
|
13
|
+
raise Error, response['error'] unless response['error'].nil?
|
14
|
+
response
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get *args
|
18
|
+
parse connection.get *args
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.post *args
|
22
|
+
parse connection.post *args
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def get *args
|
28
|
+
self.class.get *args
|
29
|
+
end
|
30
|
+
|
31
|
+
def post *args
|
32
|
+
self.class.post *args
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Configurable
|
3
|
+
attr_accessor :url, :api_key, :email, :password
|
4
|
+
|
5
|
+
def self.extended(base)
|
6
|
+
base.reset
|
7
|
+
end
|
8
|
+
|
9
|
+
def configure
|
10
|
+
yield self
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset
|
15
|
+
self.url = 'https://app.viralheat.com'
|
16
|
+
self.api_key = ENV['VIRAL_HEAT_API_KEY']
|
17
|
+
self.email = ENV['VIRAL_HEAT_EMAIL']
|
18
|
+
self.password = ENV['VIRAL_HEAT_PASSWORD']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Message
|
3
|
+
class Facebook < Base
|
4
|
+
def engagements
|
5
|
+
@engagements ||= likes + comments + shares + clicks
|
6
|
+
end
|
7
|
+
|
8
|
+
def impressions
|
9
|
+
data.fetch 'impressions'
|
10
|
+
end
|
11
|
+
|
12
|
+
def likes
|
13
|
+
data.fetch 'likes'
|
14
|
+
end
|
15
|
+
|
16
|
+
def comments
|
17
|
+
data.fetch 'comments'
|
18
|
+
end
|
19
|
+
|
20
|
+
def shares
|
21
|
+
data.fetch 'shares'
|
22
|
+
end
|
23
|
+
|
24
|
+
def clicks
|
25
|
+
data.fetch 'clicks'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Message
|
3
|
+
class Instagram < Base
|
4
|
+
def engagements
|
5
|
+
@engagements ||= likes + comments + clicks + shares
|
6
|
+
end
|
7
|
+
|
8
|
+
def impressions
|
9
|
+
data.fetch 'impressions'
|
10
|
+
end
|
11
|
+
|
12
|
+
def likes
|
13
|
+
data.fetch 'likes'
|
14
|
+
end
|
15
|
+
|
16
|
+
def comments
|
17
|
+
data.fetch 'comments'
|
18
|
+
end
|
19
|
+
|
20
|
+
def clicks
|
21
|
+
data.fetch 'clicks'
|
22
|
+
end
|
23
|
+
|
24
|
+
def shares
|
25
|
+
data.fetch('shares').to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PatientZero
|
2
|
+
module Message
|
3
|
+
class Twitter < Base
|
4
|
+
def engagements
|
5
|
+
@engagements ||= retweets + favorites + clicks
|
6
|
+
end
|
7
|
+
|
8
|
+
def retweets
|
9
|
+
data.fetch 'retweets'
|
10
|
+
end
|
11
|
+
|
12
|
+
def favorites
|
13
|
+
data.fetch 'favorites'
|
14
|
+
end
|
15
|
+
|
16
|
+
def clicks
|
17
|
+
data.fetch 'clicks'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'patient_zero/message/base'
|
2
|
+
require 'patient_zero/message/facebook'
|
3
|
+
require 'patient_zero/message/twitter'
|
4
|
+
require 'patient_zero/message/instagram'
|
5
|
+
|
6
|
+
module PatientZero
|
7
|
+
module Message
|
8
|
+
SOURCE_TYPES = {'TW' => Twitter,
|
9
|
+
'FB' => Facebook,
|
10
|
+
'IG' => Instagram}
|
11
|
+
|
12
|
+
def self.for_platform platform, params={}
|
13
|
+
SOURCE_TYPES[platform].new params
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PatientZero
|
2
|
+
class Organization < Client
|
3
|
+
attr_accessor :id, :name, :avatar
|
4
|
+
|
5
|
+
def initialize attributes
|
6
|
+
@id = attributes.fetch 'id'
|
7
|
+
@name = attributes.fetch 'name'
|
8
|
+
@avatar = attributes.fetch 'avatar'
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.all
|
12
|
+
response = get '/mobile/api/v1/organizations', client_token: Authorization.token
|
13
|
+
response['organizations'].map do |organization_attributes|
|
14
|
+
new organization_attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def sources
|
19
|
+
Source.all token
|
20
|
+
end
|
21
|
+
|
22
|
+
def token
|
23
|
+
response = get "/mobile/api/v1/organizations/#{id}/switch", client_token: Authorization.token
|
24
|
+
response['user_token']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module PatientZero
|
2
|
+
class Source < Client
|
3
|
+
attr_accessor :id, :name, :platform, :token
|
4
|
+
|
5
|
+
def initialize attributes, token
|
6
|
+
@id = attributes.fetch 'id'
|
7
|
+
@name = attributes.fetch 'name'
|
8
|
+
@invalid = attributes.fetch 'is_invalid'
|
9
|
+
@tracked = attributes.fetch 'is_tracked'
|
10
|
+
@platform = attributes.fetch 'platform'
|
11
|
+
@token = token
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.all token=Authorization.token
|
15
|
+
response = get '/mobile/api/v1/sources/', client_token: token
|
16
|
+
response['sources'].map do |source_attributes|
|
17
|
+
new source_attributes, token
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.find source_id, token=Authorization.token
|
22
|
+
response = get '/mobile/api/v1/sources/show/', id: source_id, client_token: token
|
23
|
+
new response['source'], token
|
24
|
+
rescue Error => e
|
25
|
+
raise NotFoundError, e
|
26
|
+
end
|
27
|
+
|
28
|
+
def profile_id
|
29
|
+
id.split('#').last
|
30
|
+
end
|
31
|
+
|
32
|
+
def analytics start_date: nil, end_date: nil
|
33
|
+
@analytics ||= Analytics.for_platform platform, token: token, source_id: id, start_date: start_date, end_date: end_date
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/patient_zero/version.rb
CHANGED
data/lib/patient_zero.rb
CHANGED
@@ -1,5 +1,22 @@
|
|
1
|
-
require
|
1
|
+
require 'json'
|
2
|
+
require 'faraday'
|
3
|
+
require 'patient_zero/version'
|
4
|
+
require 'patient_zero/errors'
|
5
|
+
require 'patient_zero/client'
|
6
|
+
require 'patient_zero/configurable'
|
7
|
+
require 'patient_zero/authorization'
|
8
|
+
require 'patient_zero/organization'
|
9
|
+
require 'patient_zero/analytics'
|
10
|
+
require 'patient_zero/source'
|
11
|
+
require 'patient_zero/message'
|
2
12
|
|
3
13
|
module PatientZero
|
4
|
-
|
14
|
+
extend PatientZero::Configurable
|
5
15
|
end
|
16
|
+
|
17
|
+
# Configuration Example
|
18
|
+
# PatientZero.configure do |config|
|
19
|
+
# config.api_key = 'somethingsomethingdangerzone'
|
20
|
+
# config.email = 'duchess@cia.gov'
|
21
|
+
# config.password = 'password'
|
22
|
+
# end
|
data/patient_zero.gemspec
CHANGED
@@ -4,20 +4,25 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'patient_zero/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'patient_zero'
|
8
8
|
spec.version = PatientZero::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Adam Zaninovich','Devin Clark']
|
10
|
+
spec.email = ['adam.zaninovich@gmail.com', 'notdevinclark@gmail.com']
|
11
11
|
spec.summary = %q{A gem to use the Viral Heat API}
|
12
12
|
spec.description = %q{A gem to use the Viral Heat API}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'pry'
|
25
|
+
|
26
|
+
spec.add_dependency 'faraday'
|
27
|
+
spec.add_dependency 'json'
|
23
28
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Analytics
|
5
|
+
describe Base do
|
6
|
+
let(:source_id) { "12345##{platform}#1234567890" }
|
7
|
+
let(:name) { 'account_name' }
|
8
|
+
let(:platform) { 'account_type' }
|
9
|
+
let(:messages) { [ { 'platform' => 'FB' } ] }
|
10
|
+
let(:token) { 'token-shmoken' }
|
11
|
+
let(:analytical_data) { { 'stats' => [ { 'id' => source_id, 'platform' => platform, 'name' => name, 'messages' => messages } ] } }
|
12
|
+
subject(:analytics_base) { Base.new token: token, source_id: source_id }
|
13
|
+
before { allow(Client).to receive(:get).with('/mobile/api/v1/analytics', anything).and_return analytical_data }
|
14
|
+
|
15
|
+
describe '#name' do
|
16
|
+
it 'calls the analytics API endpoint' do
|
17
|
+
expect(Client).to receive(:get).with('/mobile/api/v1/analytics', anything)
|
18
|
+
analytics_base.name
|
19
|
+
end
|
20
|
+
it 'pulls the name from the analytical_data hash' do
|
21
|
+
expect(analytics_base.name).to be name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#platform' do
|
26
|
+
it 'calls the analytics API endpoint' do
|
27
|
+
expect(Client).to receive(:get).with('/mobile/api/v1/analytics', anything)
|
28
|
+
analytics_base.name
|
29
|
+
end
|
30
|
+
it 'pulls the platform from the analytical_data hash' do
|
31
|
+
expect(analytics_base.platform).to be platform
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#messages' do
|
36
|
+
it 'calls the analytics API endpoint' do
|
37
|
+
expect(Client).to receive(:get).with('/mobile/api/v1/analytics', anything)
|
38
|
+
analytics_base.name
|
39
|
+
end
|
40
|
+
context 'when there are messages' do
|
41
|
+
it 'returns an array of messages' do
|
42
|
+
expect(analytics_base.messages.first).to be_a Message::Facebook
|
43
|
+
end
|
44
|
+
end
|
45
|
+
context 'when there are no messages' do
|
46
|
+
let(:messages) { [] }
|
47
|
+
it 'returns an empty array' do
|
48
|
+
expect(analytics_base.messages).to be_empty
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Analytics
|
5
|
+
describe Facebook do
|
6
|
+
let(:source_id) { "12345##{platform}#1234567890" }
|
7
|
+
let(:platform) { 'facebook' }
|
8
|
+
let(:message) do
|
9
|
+
{ 'platform' => 'FB',
|
10
|
+
'likes' => 93,
|
11
|
+
'comments' => 7,
|
12
|
+
'impressions' => 345,
|
13
|
+
'shares' => 22,
|
14
|
+
'clicks' => 38 }
|
15
|
+
end
|
16
|
+
let(:messages) { [ message ] }
|
17
|
+
let(:page_impressions) do
|
18
|
+
[ { 'key'=>'Total',
|
19
|
+
'values'=>
|
20
|
+
{ '2010-10-10'=> 99 } } ]
|
21
|
+
end
|
22
|
+
let(:token) { 'token-shmoken' }
|
23
|
+
let(:analytical_data) { { 'messages' => messages, 'page_impressions' => page_impressions } }
|
24
|
+
let(:facebook_analytics) { Facebook.new token: token, source_id: source_id }
|
25
|
+
before{ allow(facebook_analytics).to receive(:analytical_data).and_return analytical_data }
|
26
|
+
|
27
|
+
describe '#impressions' do
|
28
|
+
it 'returns the total for message and page impressions' do
|
29
|
+
expect(facebook_analytics.impressions).to eq 444
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#engagements' do
|
34
|
+
it 'returns the sum of likes, comments, shares, and clicks' do
|
35
|
+
expect(facebook_analytics.engagements).to eq 160
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Analytics
|
5
|
+
describe Instagram do
|
6
|
+
let(:source_id) { "12345##{platform}#1234567890" }
|
7
|
+
let(:platform) { 'instagram' }
|
8
|
+
let(:message) do
|
9
|
+
{ 'platform' => 'IG',
|
10
|
+
'impressions' => 10101,
|
11
|
+
'shares'=>'3',
|
12
|
+
'likes'=>52,
|
13
|
+
'comments'=>3,
|
14
|
+
'clicks'=>14 }
|
15
|
+
end
|
16
|
+
let(:messages) { [ message ] }
|
17
|
+
let(:token) { 'token-shmoken' }
|
18
|
+
let(:analytical_data) { { 'messages' => messages } }
|
19
|
+
let(:instagram_analytics) { Instagram.new token: token, source_id: source_id }
|
20
|
+
before{ allow(instagram_analytics).to receive(:analytical_data).and_return analytical_data }
|
21
|
+
|
22
|
+
describe '#impressions' do
|
23
|
+
it 'returns the sum of impressions for all messages' do
|
24
|
+
expect(instagram_analytics.impressions).to eq 10101
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#engagements' do
|
29
|
+
it 'returns the sum of retweets, favorites, and clicks for all messages' do
|
30
|
+
expect(instagram_analytics.engagements).to eq 72
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Analytics
|
5
|
+
describe Twitter do
|
6
|
+
let(:source_id) { "12345##{platform}#1234567890" }
|
7
|
+
let(:platform) { 'twitter' }
|
8
|
+
let(:message) do
|
9
|
+
{ 'platform' => 'TW',
|
10
|
+
'retweets' => 6,
|
11
|
+
'impressions' => 13,
|
12
|
+
'favorites' => 2,
|
13
|
+
'clicks' => 12 }
|
14
|
+
end
|
15
|
+
let(:messages) { [ message ] }
|
16
|
+
let(:token) { 'token-shmoken' }
|
17
|
+
let(:analytical_data) { { 'messages' => messages, 'total_impressions' => 13 } }
|
18
|
+
let(:twitter_analytics) { Twitter.new token: token, source_id: source_id }
|
19
|
+
before{ allow(twitter_analytics).to receive(:analytical_data).and_return analytical_data }
|
20
|
+
|
21
|
+
describe '#impressions' do
|
22
|
+
it 'returns the total_impressions value from the analytical_data hash' do
|
23
|
+
expect(twitter_analytics.impressions).to eq 13
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#engagements' do
|
28
|
+
it 'returns the sum of retweets, favorites, and clicks for all messages' do
|
29
|
+
expect(twitter_analytics.engagements).to eq 20
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Analytics do
|
5
|
+
describe '.for_platform' do
|
6
|
+
let(:data_hash) { { token: "", source_id: "" } }
|
7
|
+
context 'when platform is Facebook' do
|
8
|
+
let(:platform) { 'facebook' }
|
9
|
+
it 'news up a Analytics::Facebook object' do
|
10
|
+
expect(Analytics.for_platform(platform, data_hash)).to be_a Analytics::Facebook
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when platform is Twitter' do
|
15
|
+
let(:platform) { 'twitter' }
|
16
|
+
it 'news up a Analytics::Twitter object' do
|
17
|
+
expect(Analytics.for_platform(platform, data_hash)).to be_a Analytics::Twitter
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when platform is Instagram' do
|
22
|
+
let(:platform) { 'instagram' }
|
23
|
+
it 'news up a Analytics::Instagram object' do
|
24
|
+
expect(Analytics.for_platform(platform, data_hash)).to be_a Analytics::Instagram
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Authorization do
|
5
|
+
describe '.token' do
|
6
|
+
let(:token) { 'token-shmoken' }
|
7
|
+
let(:authorization_response) { response_with_body user_token: token }
|
8
|
+
before{ allow(Client.connection).to receive(:post).with('/mobile/api/v1/user/login', anything).and_return authorization_response }
|
9
|
+
it 'calls the login api endpoint' do
|
10
|
+
expect(Client.connection).to receive(:post).with('/mobile/api/v1/user/login', anything)
|
11
|
+
Authorization.token
|
12
|
+
end
|
13
|
+
context 'when email and password are correct' do
|
14
|
+
it 'returns a user_token' do
|
15
|
+
expect(Authorization.token).to eq token
|
16
|
+
end
|
17
|
+
end
|
18
|
+
context 'when email and password are incorrect' do
|
19
|
+
let(:authorization_response) { response_with_body error: 'Invalid login/password' }
|
20
|
+
it 'raises a PatientZero::Error error' do
|
21
|
+
expect{ Authorization.token }.to raise_error PatientZero::Error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Client do
|
5
|
+
let(:token) { 'token-shmoken' }
|
6
|
+
let(:body) { "{}" }
|
7
|
+
let(:response) { double body: body }
|
8
|
+
|
9
|
+
describe '.connection' do
|
10
|
+
it 'news up a connection to the Viral Heat API' do
|
11
|
+
expect(Client.connection).to be_a Faraday::Connection
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.parse' do
|
16
|
+
subject(:parse) { Client.parse response }
|
17
|
+
context 'when the response contains an error key with nil' do
|
18
|
+
let(:body) { "{\"status\":200,\"error\":null,\"user_token\":\"#{token}\"}" }
|
19
|
+
it 'returns a hash of data' do
|
20
|
+
expect(parse).to be_a Hash
|
21
|
+
end
|
22
|
+
end
|
23
|
+
context 'when the response contains an error key that is not nil' do
|
24
|
+
let(:body) { "{\"status\":403,\"error\":\"Invalid login/password\",\"user_token\":null}" }
|
25
|
+
it 'raises an error' do
|
26
|
+
expect { parse }.to raise_error Error
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Message
|
5
|
+
describe Facebook do
|
6
|
+
let(:data) do
|
7
|
+
{ 'platform' => 'FB',
|
8
|
+
'likes' => 93,
|
9
|
+
'comments' => 7,
|
10
|
+
'impressions' => 345,
|
11
|
+
'shares' => 22,
|
12
|
+
'clicks' => 38 }
|
13
|
+
end
|
14
|
+
subject(:facebook_message) { Facebook.new data }
|
15
|
+
describe '#engagements' do
|
16
|
+
it 'returns the sum of likes, comments, shares, and clicks' do
|
17
|
+
expect(facebook_message.engagements).to eq 160
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#impressions' do
|
22
|
+
it 'returns the impression variable from the data hash' do
|
23
|
+
expect(facebook_message.impressions).to eq 345
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#likes' do
|
28
|
+
it 'returns the likes variable from the data hash' do
|
29
|
+
expect(facebook_message.likes).to eq 93
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#comments' do
|
34
|
+
it 'returns the comments variable from the data hash' do
|
35
|
+
expect(facebook_message.comments).to eq 7
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#shares' do
|
40
|
+
it 'returns the shares variable from the data hash' do
|
41
|
+
expect(facebook_message.shares).to eq 22
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#clicks' do
|
46
|
+
it 'returns the clicks variable from the data hash' do
|
47
|
+
expect(facebook_message.clicks).to eq 38
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Message
|
5
|
+
describe Instagram do
|
6
|
+
let(:data) do
|
7
|
+
{ 'platform' => 'IG',
|
8
|
+
'likes' => 93,
|
9
|
+
'comments' => 7,
|
10
|
+
'impressions' => 345,
|
11
|
+
'shares' => '22',
|
12
|
+
'clicks' => 38 }
|
13
|
+
end
|
14
|
+
subject(:instagram_message) { Instagram.new data }
|
15
|
+
|
16
|
+
describe '#engagements' do
|
17
|
+
it 'returns the sum of likes, comments, shares, and clicks' do
|
18
|
+
expect(instagram_message.engagements).to eq 160
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#impressions' do
|
23
|
+
it 'returns the impression variable from the data hash' do
|
24
|
+
expect(instagram_message.impressions).to eq 345
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#likes' do
|
29
|
+
it 'returns the likes variable from the data hash' do
|
30
|
+
expect(instagram_message.likes).to eq 93
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#comments' do
|
35
|
+
it 'returns the comments variable from the data hash' do
|
36
|
+
expect(instagram_message.comments).to eq 7
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#shares' do
|
41
|
+
it 'returns the shares variable from the data hash' do
|
42
|
+
expect(instagram_message.shares).to eq 22
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#clicks' do
|
47
|
+
it 'returns the clicks variable from the data hash' do
|
48
|
+
expect(instagram_message.clicks).to eq 38
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
module Message
|
5
|
+
describe Twitter do
|
6
|
+
let(:data) do
|
7
|
+
{ 'platform' => 'TW',
|
8
|
+
'favorites' => 7,
|
9
|
+
'impressions' => 345,
|
10
|
+
'retweets' => 22,
|
11
|
+
'clicks' => 38 }
|
12
|
+
end
|
13
|
+
subject(:twitter_message) { Twitter.new data }
|
14
|
+
|
15
|
+
describe '#engagements' do
|
16
|
+
it 'returns the sum of retweets, favorites, and clicks' do
|
17
|
+
expect(twitter_message.engagements).to eq 67
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#retweets' do
|
22
|
+
it 'returns the retweets variable from the data hash' do
|
23
|
+
expect(twitter_message.retweets).to eq 22
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#favorites' do
|
28
|
+
it 'returns the favorites variable from the data hash' do
|
29
|
+
expect(twitter_message.favorites).to eq 7
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#clicks' do
|
34
|
+
it 'returns the clicks variable from the data hash' do
|
35
|
+
expect(twitter_message.clicks).to eq 38
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Message do
|
5
|
+
describe '.for_platform' do
|
6
|
+
let(:data_hash) { { } }
|
7
|
+
context 'when platform is Facebook' do
|
8
|
+
let(:platform) { 'FB' }
|
9
|
+
it 'news up a Message::Facebook object' do
|
10
|
+
expect(Message.for_platform(platform, data_hash)).to be_a Message::Facebook
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when platform is Twitter' do
|
15
|
+
let(:platform) { 'TW' }
|
16
|
+
it 'news up a Message::Twitter object' do
|
17
|
+
expect(Message.for_platform(platform, data_hash)).to be_a Message::Twitter
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when platform is Instagram' do
|
22
|
+
let(:platform) { 'IG' }
|
23
|
+
it 'news up a Message::Instagram object' do
|
24
|
+
expect(Message.for_platform(platform, data_hash)).to be_a Message::Instagram
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Organization do
|
5
|
+
let(:id) { 12345 }
|
6
|
+
let(:token) { 'token-shmoken' }
|
7
|
+
let(:organization) { Organization.new organization_response_data }
|
8
|
+
let(:organizations_response_data) { [organization_response_data] }
|
9
|
+
let(:organization_response_data) do
|
10
|
+
{ "id"=>id,
|
11
|
+
"name"=>"Organization One",
|
12
|
+
"avatar"=>
|
13
|
+
{ "thumbnail"=>"https://s3.amazonaws.com/viralheat/avatars/organizations/12345/thumb/fake_img_1.png",
|
14
|
+
"medium"=>"https://s3.amazonaws.com/viralheat/avatars/organizations/12345/medium/fake_img_1.png",
|
15
|
+
"large"=>"https://s3.amazonaws.com/viralheat/avatars/organizations/12345/large/fake_img_1.png" } }
|
16
|
+
end
|
17
|
+
|
18
|
+
before { allow(Authorization).to receive(:token).and_return token }
|
19
|
+
|
20
|
+
describe '.all' do
|
21
|
+
let(:organizations) { [organization] }
|
22
|
+
let(:organizations_response) { response_with_body organizations: organizations_response_data }
|
23
|
+
before { allow(Client.connection).to receive(:get).with('/mobile/api/v1/organizations', anything) { organizations_response } }
|
24
|
+
|
25
|
+
it 'calls the organizations api endpoint' do
|
26
|
+
expect(Client.connection).to receive(:get).with('/mobile/api/v1/organizations', anything)
|
27
|
+
Organization.all
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'if the user has organizations' do
|
31
|
+
it 'returns an array of all organizations available' do
|
32
|
+
expect(Organization.all.map(&:id)).to eq organizations.map(&:id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'if the user has no organizations' do
|
37
|
+
let(:organizations_response_data) { [] }
|
38
|
+
it 'returns an empty array' do
|
39
|
+
expect(Organization.all).to be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#sources' do
|
45
|
+
it 'calls Source.all and passes its own organization user_token' do
|
46
|
+
allow(organization).to receive(:token).and_return token
|
47
|
+
expect(Source).to receive(:all).with(token)
|
48
|
+
organization.sources
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#token' do
|
53
|
+
let(:organization_specific_token) { 'organization-token' }
|
54
|
+
let(:switch_response) { response_with_body user_token: organization_specific_token }
|
55
|
+
before { allow(Client.connection).to receive(:get).with("/mobile/api/v1/organizations/#{id}/switch", anything).and_return switch_response }
|
56
|
+
|
57
|
+
it 'calls the organization switch api endpoint' do
|
58
|
+
expect(Client.connection).to receive(:get).with("/mobile/api/v1/organizations/#{id}/switch", anything)
|
59
|
+
organization.token
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns the organization specific user_token' do
|
63
|
+
expect(organization.token).to eq organization_specific_token
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module PatientZero
|
4
|
+
describe Source do
|
5
|
+
let(:id) { '12345#instagram_account#1234567890' }
|
6
|
+
let(:token) { 'token-shmoken' }
|
7
|
+
let(:sources_response_data) { [source_response_data] }
|
8
|
+
let(:source_response_data) do
|
9
|
+
{'id'=> id,
|
10
|
+
'name' => 'account_name',
|
11
|
+
'is_invalid' => false,
|
12
|
+
'is_tracked' => true,
|
13
|
+
'platform' => 'instagram',
|
14
|
+
'delete_id' => id }
|
15
|
+
end
|
16
|
+
let(:source) { Source.new source_response_data, token }
|
17
|
+
|
18
|
+
describe '.all' do
|
19
|
+
before do
|
20
|
+
allow(Authorization).to receive(:token).and_return token
|
21
|
+
allow(Client.connection).to receive(:get).with('/mobile/api/v1/sources/', anything).and_return response_with_body sources: sources_response_data
|
22
|
+
end
|
23
|
+
it 'calls the sources index api' do
|
24
|
+
expect(Client.connection).to receive(:get).with('/mobile/api/v1/sources/', anything)
|
25
|
+
Source.all
|
26
|
+
end
|
27
|
+
it 'calls Authorization.token if no token is passed in' do
|
28
|
+
expect(Authorization).to receive(:token)
|
29
|
+
Source.all
|
30
|
+
end
|
31
|
+
context 'when the associated organization token has sources' do
|
32
|
+
it 'returns an array of sources' do
|
33
|
+
expect(Source.all.first.id).to eq source.id
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context 'when the associated organization token has no sources' do
|
37
|
+
it 'returns an empty array' do
|
38
|
+
allow(Client.connection).to receive(:get).with('/mobile/api/v1/sources/', anything).and_return response_with_body sources: []
|
39
|
+
expect(Source.all).to be_empty
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.find' do
|
45
|
+
before do
|
46
|
+
allow(Authorization).to receive(:token).and_return token
|
47
|
+
allow(Client.connection).to receive(:get).with('/mobile/api/v1/sources/show/', anything).and_return response_with_body source: source_response_data
|
48
|
+
end
|
49
|
+
it 'calls the sources show api' do
|
50
|
+
expect(Client.connection).to receive(:get).with('/mobile/api/v1/sources/show/', anything)
|
51
|
+
Source.find id
|
52
|
+
end
|
53
|
+
it 'calls Authorization.token if no token is passed in' do
|
54
|
+
expect(Authorization).to receive(:token)
|
55
|
+
Source.find id
|
56
|
+
end
|
57
|
+
context 'when the source exists' do
|
58
|
+
it 'returns a source' do
|
59
|
+
expect(Source.find(id).id).to eq source.id
|
60
|
+
end
|
61
|
+
end
|
62
|
+
context 'when no source exists' do
|
63
|
+
it 'throws an PatientZero::Error' do
|
64
|
+
allow(Client).to receive(:get).and_raise Error, 'The source could not be found. Please check your inputs.'
|
65
|
+
expect{ Source.find id }.to raise_error PatientZero::NotFoundError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#profile_id' do
|
71
|
+
it 'returns the number at the end of the id' do
|
72
|
+
expect(source.profile_id).to eq '1234567890'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#analytics' do
|
77
|
+
it 'calls Analytics.for_platorm to create an analytics object' do
|
78
|
+
expect(Analytics).to receive(:for_platform).with(source.platform, { token: source.token, source_id: source.id, start_date: nil, end_date: nil })
|
79
|
+
source.analytics
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: patient_zero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Zaninovich
|
8
|
+
- Devin Clark
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-
|
12
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
@@ -38,21 +39,109 @@ dependencies:
|
|
38
39
|
- - "~>"
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '10.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: faraday
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: json
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
41
98
|
description: A gem to use the Viral Heat API
|
42
99
|
email:
|
43
100
|
- adam.zaninovich@gmail.com
|
101
|
+
- notdevinclark@gmail.com
|
44
102
|
executables: []
|
45
103
|
extensions: []
|
46
104
|
extra_rdoc_files: []
|
47
105
|
files:
|
48
106
|
- ".gitignore"
|
107
|
+
- ".rspec"
|
49
108
|
- Gemfile
|
50
109
|
- LICENSE.txt
|
51
110
|
- README.md
|
52
111
|
- Rakefile
|
53
112
|
- lib/patient_zero.rb
|
113
|
+
- lib/patient_zero/analytics.rb
|
114
|
+
- lib/patient_zero/analytics/base.rb
|
115
|
+
- lib/patient_zero/analytics/facebook.rb
|
116
|
+
- lib/patient_zero/analytics/instagram.rb
|
117
|
+
- lib/patient_zero/analytics/twitter.rb
|
118
|
+
- lib/patient_zero/authorization.rb
|
119
|
+
- lib/patient_zero/client.rb
|
120
|
+
- lib/patient_zero/configurable.rb
|
121
|
+
- lib/patient_zero/errors.rb
|
122
|
+
- lib/patient_zero/message.rb
|
123
|
+
- lib/patient_zero/message/base.rb
|
124
|
+
- lib/patient_zero/message/facebook.rb
|
125
|
+
- lib/patient_zero/message/instagram.rb
|
126
|
+
- lib/patient_zero/message/twitter.rb
|
127
|
+
- lib/patient_zero/organization.rb
|
128
|
+
- lib/patient_zero/source.rb
|
54
129
|
- lib/patient_zero/version.rb
|
55
130
|
- patient_zero.gemspec
|
131
|
+
- spec/patient_zero/analytics/base_spec.rb
|
132
|
+
- spec/patient_zero/analytics/facebook_spec.rb
|
133
|
+
- spec/patient_zero/analytics/instagram_spec.rb
|
134
|
+
- spec/patient_zero/analytics/twitter_spec.rb
|
135
|
+
- spec/patient_zero/analytics_spec.rb
|
136
|
+
- spec/patient_zero/authorization_spec.rb
|
137
|
+
- spec/patient_zero/client_spec.rb
|
138
|
+
- spec/patient_zero/message/facebook_spec.rb
|
139
|
+
- spec/patient_zero/message/instagram_spec.rb
|
140
|
+
- spec/patient_zero/message/twitter_spec.rb
|
141
|
+
- spec/patient_zero/message_spec.rb
|
142
|
+
- spec/patient_zero/organization_spec.rb
|
143
|
+
- spec/patient_zero/source_spec.rb
|
144
|
+
- spec/spec_helper.rb
|
56
145
|
homepage: ''
|
57
146
|
licenses:
|
58
147
|
- MIT
|
@@ -77,4 +166,18 @@ rubygems_version: 2.4.5
|
|
77
166
|
signing_key:
|
78
167
|
specification_version: 4
|
79
168
|
summary: A gem to use the Viral Heat API
|
80
|
-
test_files:
|
169
|
+
test_files:
|
170
|
+
- spec/patient_zero/analytics/base_spec.rb
|
171
|
+
- spec/patient_zero/analytics/facebook_spec.rb
|
172
|
+
- spec/patient_zero/analytics/instagram_spec.rb
|
173
|
+
- spec/patient_zero/analytics/twitter_spec.rb
|
174
|
+
- spec/patient_zero/analytics_spec.rb
|
175
|
+
- spec/patient_zero/authorization_spec.rb
|
176
|
+
- spec/patient_zero/client_spec.rb
|
177
|
+
- spec/patient_zero/message/facebook_spec.rb
|
178
|
+
- spec/patient_zero/message/instagram_spec.rb
|
179
|
+
- spec/patient_zero/message/twitter_spec.rb
|
180
|
+
- spec/patient_zero/message_spec.rb
|
181
|
+
- spec/patient_zero/organization_spec.rb
|
182
|
+
- spec/patient_zero/source_spec.rb
|
183
|
+
- spec/spec_helper.rb
|