lexervariables 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 +7 -0
- data/.gitignore +38 -0
- data/Gemfile +4 -0
- data/README.md +25 -0
- data/Rakefile +9 -0
- data/lexervariables.gemspec +30 -0
- data/lib/lexervariables.rb +85 -0
- data/lib/lexervariables/api.rb +90 -0
- data/lib/lexervariables/attribute_generator.rb +15 -0
- data/lib/lexervariables/attribute_geo_region.rb +7 -0
- data/lib/lexervariables/attribute_page.rb +7 -0
- data/lib/lexervariables/attribute_user.rb +7 -0
- data/lib/lexervariables/dashboard_object.rb +34 -0
- data/lib/lexervariables/error.rb +7 -0
- data/lib/lexervariables/monitored_account.rb +85 -0
- data/lib/lexervariables/monitored_geo_region.rb +7 -0
- data/lib/lexervariables/monitored_object.rb +21 -0
- data/lib/lexervariables/monitored_page.rb +7 -0
- data/lib/lexervariables/monitored_term.rb +7 -0
- data/lib/lexervariables/monitored_url.rb +7 -0
- data/lib/lexervariables/monitored_user.rb +7 -0
- data/lib/lexervariables/oauth.rb +29 -0
- data/lib/lexervariables/version.rb +3 -0
- data/test/attribute_generator_test.rb +45 -0
- data/test/docker-launch-tests.sh +4 -0
- data/test/docker-run-tests.sh +9 -0
- data/test/factories/monitored_accounts.rb +21 -0
- data/test/factories/monitored_terms.rb +9 -0
- data/test/factories/oauths.rb +9 -0
- data/test/lexer_variables_test.rb +19 -0
- data/test/monitored_account_test.rb +106 -0
- data/test/monitored_object_test.rb +62 -0
- data/test/oauth_test.rb +22 -0
- data/test/test_helper.rb +38 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 866f1bc83bd911c1870c91da77d7acd725f2961f
|
4
|
+
data.tar.gz: 55286b7635617c451c6c535488330e57a1cacdc6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d66dc4d6676cc0f4c66596970599ab3c6d63954078e1c5c44862288fbf07a0ef7a2c6ad1763a7b43cc4a73ff1d37194a798210279bd0d2316d0b9ef5e6665f51
|
7
|
+
data.tar.gz: c5c21c4c76e322a513b5ff3fa6b145cb939841e9bba7166ede0b114f6619ba109275713fe4ee6a9ee7eac8c29c4adc3df72441e96c7cb20b0568163f17d77d23
|
data/.gitignore
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
/.config
|
5
|
+
/coverage/
|
6
|
+
/InstalledFiles
|
7
|
+
/pkg/
|
8
|
+
/test/reports/
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
## Specific to RubyMotion:
|
14
|
+
.dat*
|
15
|
+
.repl_history
|
16
|
+
build/
|
17
|
+
|
18
|
+
## Documentation cache and generated files:
|
19
|
+
/.yardoc/
|
20
|
+
/_yardoc/
|
21
|
+
/doc/
|
22
|
+
/rdoc/
|
23
|
+
|
24
|
+
## Environment normalisation:
|
25
|
+
/.bundle/
|
26
|
+
/lib/bundler/man/
|
27
|
+
|
28
|
+
# for a library or gem, you might want to ignore these files since the code is
|
29
|
+
# intended to run in multiple environments; otherwise, check them in:
|
30
|
+
Gemfile.lock
|
31
|
+
.ruby-version
|
32
|
+
.ruby-gemset
|
33
|
+
|
34
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
35
|
+
.rvmrc
|
36
|
+
|
37
|
+
.swp
|
38
|
+
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# lexer-variables.gem
|
2
|
+
|
3
|
+
Gem for loading variables (terms, geographies, authors, pages, oauths) to monitor
|
4
|
+
|
5
|
+
Communicates with the [lexer-dashboard-app](http://github.com/lexerdev/lexer-dashboard-app) to lease:
|
6
|
+
* Monitored Terms
|
7
|
+
* Monitored Geo Regions
|
8
|
+
* Monitored Authors
|
9
|
+
* Monitored Pages
|
10
|
+
* OAuths (with associations to above)
|
11
|
+
|
12
|
+
This gem and the functionality held in the dashboard-app aims to retire the current implementation whereby variables and oauths are loaded from the Lexer-API thorugh the Lexer-API.gem.
|
13
|
+
|
14
|
+
# Tests
|
15
|
+
|
16
|
+
Run tests:
|
17
|
+
bundle exec rake test
|
18
|
+
|
19
|
+
# IRB
|
20
|
+
|
21
|
+
Need to have a tinker?
|
22
|
+
|
23
|
+
irb -rubygems -I lib -r $PWD/lib/lexervariables.rb
|
24
|
+
|
25
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "lexervariables/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "lexervariables"
|
7
|
+
s.version = LexerVariables::VERSION
|
8
|
+
s.authors = ["Aaron Wallis"]
|
9
|
+
s.email = ["aaron.wallis@lexer.com.au"]
|
10
|
+
s.homepage = "http://lexer.com.au"
|
11
|
+
s.summary = "Gem for loading variables (terms, geographies, authors, pages, oauths) to monitor"
|
12
|
+
s.description = "Gem for loading variables (terms, geographies, authors, pages, oauths) to monitor"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency 'faraday'
|
20
|
+
s.add_dependency 'multi_json'
|
21
|
+
s.add_dependency 'oj'
|
22
|
+
|
23
|
+
s.add_development_dependency 'minitest'
|
24
|
+
s.add_development_dependency 'minitest-reporters'
|
25
|
+
s.add_development_dependency 'factory_girl'
|
26
|
+
s.add_development_dependency 'faker'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'webmock'
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'oj'
|
2
|
+
require 'multi_json'
|
3
|
+
require 'lexervariables/error'
|
4
|
+
require 'lexervariables/version'
|
5
|
+
|
6
|
+
module LexerVariables
|
7
|
+
module_function
|
8
|
+
|
9
|
+
DEFAULT_ENDPOINT = 'https://lexer-dashboard/api/system/'
|
10
|
+
USER_AGENT = 'Lexer Worker'
|
11
|
+
SECRET_TOKEN = 'MLXTblicbwEVqyWXXrtz2DccoEuoqx9h5VFKZfBsP48QCOQ2hEcWvPDYoWwY4sQj'
|
12
|
+
|
13
|
+
def validate_provider(provider)
|
14
|
+
fail LexerVariables::UnknownProvider, "Unknown provider: #{provider}" unless [:facebook, :twitter, :instagram, :spinn3r, :yammer].include?(provider)
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
class Configuration
|
19
|
+
class << self
|
20
|
+
attr_accessor :endpoint
|
21
|
+
attr_accessor :api_key
|
22
|
+
end
|
23
|
+
|
24
|
+
@endpoint = DEFAULT_ENDPOINT
|
25
|
+
@api_key = SECRET_TOKEN
|
26
|
+
|
27
|
+
def self.default_options
|
28
|
+
{'api_token' => self.api_key}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class LexerModel
|
33
|
+
attr_accessor :attrs
|
34
|
+
alias :to_hash :attrs
|
35
|
+
|
36
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
37
|
+
#
|
38
|
+
# @overload self.lazy_attr_reader(attr)
|
39
|
+
# @param attr [Symbol]
|
40
|
+
# @overload self.lazy_attr_reader(attrs)
|
41
|
+
# @param attrs [Array<Symbol>]
|
42
|
+
def self.lazy_attr_reader(*attrs)
|
43
|
+
attrs.each do |attribute|
|
44
|
+
class_eval do
|
45
|
+
define_method attribute do
|
46
|
+
@attrs[attribute.to_s]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initializes a new Base object
|
53
|
+
#
|
54
|
+
# @param attrs [Hash]
|
55
|
+
# @return [LexerModel]
|
56
|
+
def initialize(attrs={})
|
57
|
+
@attrs = attrs.dup
|
58
|
+
end
|
59
|
+
|
60
|
+
# Initializes a new Base object
|
61
|
+
#
|
62
|
+
# @param method [String, Symbol] Message to send to the object
|
63
|
+
def [](method)
|
64
|
+
self.__send__(method.to_sym)
|
65
|
+
rescue NoMethodError
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
require 'lexervariables/api'
|
73
|
+
require 'lexervariables/dashboard_object'
|
74
|
+
require 'lexervariables/attribute_generator'
|
75
|
+
require 'lexervariables/attribute_geo_region'
|
76
|
+
require 'lexervariables/attribute_page'
|
77
|
+
require 'lexervariables/attribute_user'
|
78
|
+
require 'lexervariables/monitored_account'
|
79
|
+
require 'lexervariables/monitored_object'
|
80
|
+
require 'lexervariables/monitored_geo_region'
|
81
|
+
require 'lexervariables/monitored_page'
|
82
|
+
require 'lexervariables/monitored_term'
|
83
|
+
require 'lexervariables/monitored_user'
|
84
|
+
require 'lexervariables/monitored_url'
|
85
|
+
require 'lexervariables/oauth'
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'oj'
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module LexerVariables
|
6
|
+
|
7
|
+
class ParseJson < ::Faraday::Response::Middleware
|
8
|
+
def parse(body)
|
9
|
+
case body
|
10
|
+
when '', 'null'
|
11
|
+
nil
|
12
|
+
when 'true'
|
13
|
+
true
|
14
|
+
when 'false'
|
15
|
+
false
|
16
|
+
else
|
17
|
+
MultiJson.decode(body)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_complete(env)
|
22
|
+
if env[:status] >= 300
|
23
|
+
fail ::LexerVariables::RequestError, "API Request error #{env[:status]} : #{env[:url]} : #{MultiJson.encode(env[:request_headers])} #{env[:body]}"
|
24
|
+
elsif env[:status] == 204
|
25
|
+
env[:body] = nil
|
26
|
+
else
|
27
|
+
env[:body] = parse(env[:body])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.api_connection(options={})
|
33
|
+
default_options = {
|
34
|
+
:headers => {
|
35
|
+
:accept => 'application/json'
|
36
|
+
},
|
37
|
+
:ssl => {
|
38
|
+
:verify => false
|
39
|
+
}
|
40
|
+
}
|
41
|
+
@__api_connection ||= Faraday.new(default_options.merge(options)) do |builder|
|
42
|
+
builder.use(Faraday::Request::UrlEncoded) # convert request params as "www-form-urlencoded"
|
43
|
+
builder.use(LexerVariables::ParseJson) # Decode the response as JSON
|
44
|
+
builder.use(Faraday::Adapter::NetHttp) # make http requests with Net::HTTP
|
45
|
+
|
46
|
+
# Enable if you want super noisy (but informative) logs
|
47
|
+
# builder.use Faraday::Response::Logger # log the request to STDOUT
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.reset_connection
|
52
|
+
@__api_connection = nil
|
53
|
+
end
|
54
|
+
|
55
|
+
module Request
|
56
|
+
module_function
|
57
|
+
|
58
|
+
# Perform an HTTP GET request
|
59
|
+
def get(path, params={}, options={})
|
60
|
+
request(:get, path, params, options)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Perform an HTTP POST request
|
64
|
+
def self.post(path, params={}, options={})
|
65
|
+
request(:post, path, params, options)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
# Perform an HTTP request
|
70
|
+
def self.request(method, path, params, options)
|
71
|
+
params.merge!(LexerVariables::Configuration.default_options)
|
72
|
+
path = "#{LexerVariables::Configuration.endpoint}#{path}"
|
73
|
+
response = LexerVariables::api_connection(options).run_request(method, nil, nil, nil) do |request|
|
74
|
+
case method.to_sym
|
75
|
+
when :delete, :get
|
76
|
+
request.url(path, params)
|
77
|
+
when :post, :put
|
78
|
+
request.path = path
|
79
|
+
request.body = params unless params.empty?
|
80
|
+
request.options.timeout = 20
|
81
|
+
request.options.open_timeout = 30
|
82
|
+
else
|
83
|
+
fail LexerVariables::RequestError, "Request method '#{method}' is unsupported"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
response.body
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class LexerVariables::AttributeGenerator < LexerVariables::DashboardObject
|
2
|
+
ENDPOINT = "attribute_generators"
|
3
|
+
|
4
|
+
lazy_attr_reader :object, :attributes
|
5
|
+
|
6
|
+
def self.format_object(objects)
|
7
|
+
objects.collect do |object|
|
8
|
+
{
|
9
|
+
'object' => object.fetch('monitored_object', {})['object'],
|
10
|
+
'attributes' => object['attributes']
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class LexerVariables::DashboardObject < LexerVariables::LexerModel
|
2
|
+
def self.all(provider:, shards: 0)
|
3
|
+
LexerVariables.validate_provider(provider)
|
4
|
+
|
5
|
+
objects = LexerVariables::Request.get("#{self::ENDPOINT}/#{provider}/#{self.object_type}")
|
6
|
+
formatted_objects = format_object(objects)
|
7
|
+
shard_objects(objects:formatted_objects, shards:shards)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.format_object(objects)
|
11
|
+
objects
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.shard_objects(objects:, shards:)
|
15
|
+
return objects if shards == 0
|
16
|
+
|
17
|
+
# If we don't have enough objects to shard, every shard gets all the objects
|
18
|
+
return shards.times.collect{objects} if objects.size.to_f <= (shards * 2)
|
19
|
+
|
20
|
+
slice_size = (objects.size.to_f / shards).ceil
|
21
|
+
object_distribution = objects.each_slice(slice_size).collect{|i| i}
|
22
|
+
number_of_objects_to_shift = slice_size - object_distribution.last.size - 1
|
23
|
+
number_of_objects_to_shift.times do |i|
|
24
|
+
object_distribution.last << object_distribution[i].pop
|
25
|
+
end
|
26
|
+
|
27
|
+
object_distribution
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
self.object
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
class LexerVariables::MonitoredAccount < LexerVariables::LexerModel
|
4
|
+
attr_reader :key
|
5
|
+
attr_reader :secret
|
6
|
+
attr_reader :username
|
7
|
+
attr_reader :email
|
8
|
+
attr_reader :client_id
|
9
|
+
attr_reader :id
|
10
|
+
attr_reader :monitored_object
|
11
|
+
|
12
|
+
def initialize(data)
|
13
|
+
|
14
|
+
unless data.key?('access_token_key') && data.key?('access_token_secret')
|
15
|
+
fail LexerVariables::InvalidObject, "JSON OAuth returned (#{data}) was not usable due to missing fields."
|
16
|
+
end
|
17
|
+
|
18
|
+
@key = data['access_token_key']
|
19
|
+
@secret = data['access_token_secret']
|
20
|
+
@username = data['username']
|
21
|
+
@email = data['email']
|
22
|
+
@client_id = data['client_id']
|
23
|
+
@monitored_object = data['monitored_object']
|
24
|
+
@id = data['id']
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.lease(provider)
|
28
|
+
self.lease_object(provider, nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.lease_object(provider, monitored_object)
|
32
|
+
LexerVariables.validate_provider(provider)
|
33
|
+
|
34
|
+
options = {}
|
35
|
+
if monitored_object
|
36
|
+
options['monitored_object'] = monitored_object
|
37
|
+
end
|
38
|
+
|
39
|
+
response = LexerVariables::Request.get("monitored_accounts/#{provider}/lease", options)
|
40
|
+
return nil if response == {}
|
41
|
+
LexerVariables::MonitoredAccount.new(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.all(provider)
|
45
|
+
LexerVariables.validate_provider(provider)
|
46
|
+
|
47
|
+
monitored_accounts = LexerVariables::Request.get("monitored_accounts/#{provider}")
|
48
|
+
return nil if monitored_accounts == []
|
49
|
+
|
50
|
+
response = []
|
51
|
+
monitored_accounts.each do |monitored_account|
|
52
|
+
response << LexerVariables::MonitoredAccount.new(monitored_account)
|
53
|
+
end
|
54
|
+
#Sort as lowest MonitoredAccount.id going to worker 0
|
55
|
+
response = response.sort_by{|account| account.id }
|
56
|
+
|
57
|
+
return response
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.send_error(provider, error_message, id)
|
61
|
+
LexerVariables.validate_provider(provider)
|
62
|
+
|
63
|
+
options = {
|
64
|
+
"provider" => provider,
|
65
|
+
"id" => id,
|
66
|
+
"error_message" => error_message
|
67
|
+
}
|
68
|
+
|
69
|
+
response = LexerVariables::Request.post('monitored_accounts/error', options)
|
70
|
+
if response.nil?
|
71
|
+
response = "Successfully posted email"
|
72
|
+
end
|
73
|
+
return response
|
74
|
+
end
|
75
|
+
|
76
|
+
def <=>(account)
|
77
|
+
if self.id < account.id
|
78
|
+
-1
|
79
|
+
elsif self.id > account.id
|
80
|
+
1
|
81
|
+
else
|
82
|
+
0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
class LexerVariables::MonitoredObject < LexerVariables::DashboardObject
|
4
|
+
ENDPOINT = "monitored_objects"
|
5
|
+
|
6
|
+
lazy_attr_reader :object
|
7
|
+
|
8
|
+
def self.pop(provider:)
|
9
|
+
LexerVariables.validate_provider(provider)
|
10
|
+
|
11
|
+
response = LexerVariables::Request.get("#{ENDPOINT}/#{provider}/#{self.object_type}/pop")
|
12
|
+
self.new(response)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.format_object(objects)
|
16
|
+
objects.collect do |object|
|
17
|
+
object['object']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
|
3
|
+
class LexerVariables::OAuth < LexerVariables::MonitoredObject
|
4
|
+
attr_reader :key
|
5
|
+
attr_reader :secret
|
6
|
+
attr_reader :username
|
7
|
+
attr_reader :email
|
8
|
+
|
9
|
+
def initialize(attrs)
|
10
|
+
super(attrs)
|
11
|
+
data = MultiJson::decode(object)
|
12
|
+
|
13
|
+
unless data.key?('access_token') && data.key?('access_token_secret')
|
14
|
+
fail LexerVariables::InvalidObject, "JSON OAuth returned (#{object}) was not usable due to missing fields."
|
15
|
+
end
|
16
|
+
|
17
|
+
@key = data['access_token']
|
18
|
+
@secret = data['access_token_secret']
|
19
|
+
@username = data['username']
|
20
|
+
@email = data['email']
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.object_type
|
26
|
+
'oauths'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe LexerVariables::AttributeGenerator do
|
4
|
+
|
5
|
+
describe 'no objects to acquire' do
|
6
|
+
before do
|
7
|
+
stub_get("/api/system/attribute_generators/twitter/regions?api_token=#{LexerVariables::SECRET_TOKEN}").
|
8
|
+
to_return(body: MultiJson.dump('Not found'), status: 404) if $should_stub
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail for an unpopulated type' do
|
12
|
+
assert_raises LexerVariables::RequestError do
|
13
|
+
LexerVariables::AttributeGeoRegion.all(provider: :twitter)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#all' do
|
19
|
+
let(:attribute_users) {
|
20
|
+
(1..10).collect { |x| test_attribute_user }
|
21
|
+
}
|
22
|
+
|
23
|
+
before do
|
24
|
+
stub_get("/api/system/attribute_generators/twitter/users?api_token=#{LexerVariables::SECRET_TOKEN}").
|
25
|
+
to_return(body: MultiJson.dump(attribute_users), status: 200) if $should_stub
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should get all attribute generator users for single provider' do
|
29
|
+
users = LexerVariables::AttributeUser.all(provider: :twitter)
|
30
|
+
users.must_be_instance_of(Array)
|
31
|
+
users.size.must_equal(10)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should shard attribute generator users' do
|
35
|
+
users = LexerVariables::AttributeUser.all(provider: :twitter, shards: 4)
|
36
|
+
users.must_be_instance_of(Array)
|
37
|
+
users.size.must_equal(4)
|
38
|
+
users[0].must_be_instance_of(Array)
|
39
|
+
users[0].size.must_equal(2)
|
40
|
+
users[1].must_be_instance_of(Array)
|
41
|
+
users[1].size.must_equal(3)
|
42
|
+
users.flatten.size.must_equal(10)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
|
3
|
+
factory :monitored_account, class:Hash do
|
4
|
+
id { Faker::Number.number(4).to_i }
|
5
|
+
provider { "twitter" }
|
6
|
+
client_id { Faker::Number.digit }
|
7
|
+
username { Faker::Internet.user_name }
|
8
|
+
email { Faker::Internet.email }
|
9
|
+
access_token_key { Faker::Internet.password(8) }
|
10
|
+
access_token_secret { Faker::Internet.password(16) }
|
11
|
+
monitored_object { Faker::Lorem::words(1)[0] }
|
12
|
+
last_used { DateTime.now.iso8601 }
|
13
|
+
expires { DateTime.now.iso8601 }
|
14
|
+
created_time { DateTime.now.iso8601 }
|
15
|
+
updated_time { DateTime.now.iso8601 }
|
16
|
+
is_priority { false }
|
17
|
+
|
18
|
+
initialize_with { attributes }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe LexerVariables do
|
4
|
+
describe '#validate_provider' do
|
5
|
+
it 'should reject invalid network' do
|
6
|
+
assert_raises LexerVariables::UnknownProvider do
|
7
|
+
LexerVariables.validate_provider(:lexer)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should accept valid networks' do
|
12
|
+
assert LexerVariables.validate_provider(:twitter)
|
13
|
+
assert LexerVariables.validate_provider(:spinn3r)
|
14
|
+
assert LexerVariables.validate_provider(:instagram)
|
15
|
+
assert LexerVariables.validate_provider(:facebook)
|
16
|
+
assert LexerVariables.validate_provider(:yammer)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe LexerVariables::MonitoredAccount do
|
4
|
+
|
5
|
+
describe 'no accounts to monitor' do
|
6
|
+
before do
|
7
|
+
stub_get("/api/system/monitored_accounts/twitter/lease?api_token=#{LexerVariables::SECRET_TOKEN}").
|
8
|
+
to_return(body: MultiJson.dump('Not found'), status: 404) if $should_stub
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'fails' do
|
12
|
+
assert_raises LexerVariables::RequestError do
|
13
|
+
LexerVariables::MonitoredAccount.lease(:twitter)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#all' do
|
19
|
+
let(:monitored_accounts) {[
|
20
|
+
FactoryGirl.build(:monitored_account),
|
21
|
+
FactoryGirl.build(:monitored_account),
|
22
|
+
FactoryGirl.build(:monitored_account),
|
23
|
+
FactoryGirl.build(:monitored_account),
|
24
|
+
FactoryGirl.build(:monitored_account)
|
25
|
+
]}
|
26
|
+
|
27
|
+
before do
|
28
|
+
stub_get("/api/system/monitored_accounts/twitter?api_token=#{LexerVariables::SECRET_TOKEN}").
|
29
|
+
to_return(body: MultiJson.dump(monitored_accounts)) if $should_stub
|
30
|
+
|
31
|
+
stub_get("/api/system/monitored_accounts/facebook?api_token=#{LexerVariables::SECRET_TOKEN}").
|
32
|
+
to_return(body: MultiJson.dump([])) if $should_stub
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should get all monitored accounts for single provider' do
|
36
|
+
accounts = LexerVariables::MonitoredAccount.all(:twitter)
|
37
|
+
accounts.must_be_instance_of(Array)
|
38
|
+
accounts.size.must_equal(5)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should return nil for provider with no accounts' do
|
42
|
+
accounts = LexerVariables::MonitoredAccount.all(:facebook)
|
43
|
+
accounts.must_be_instance_of(NilClass)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should return monitored accounts in sorted order' do
|
47
|
+
accounts = LexerVariables::MonitoredAccount.all(:twitter)
|
48
|
+
accounts.must_be_instance_of(Array)
|
49
|
+
accounts.size.must_equal(5)
|
50
|
+
last_id = -1
|
51
|
+
sorted = true
|
52
|
+
accounts.each do |account|
|
53
|
+
sorted &= account.id > last_id
|
54
|
+
last_id = account.id if sorted
|
55
|
+
end
|
56
|
+
assert(sorted, 'monitored_accounts are not sorted by .id')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'twitter' do
|
61
|
+
let(:monitored_account) {
|
62
|
+
FactoryGirl.build(:monitored_account)
|
63
|
+
}
|
64
|
+
|
65
|
+
describe 'get accounts to monitor' do
|
66
|
+
before do
|
67
|
+
stub_get("/api/system/monitored_accounts/twitter/lease?api_token=#{LexerVariables::SECRET_TOKEN}").
|
68
|
+
to_return(body: MultiJson.dump(monitored_account)) if $should_stub
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'leases a single account' do
|
72
|
+
account = LexerVariables::MonitoredAccount.lease(:twitter)
|
73
|
+
account.must_be_instance_of(LexerVariables::MonitoredAccount)
|
74
|
+
account.monitored_object.must_equal(monitored_account[:monitored_object])
|
75
|
+
account.key.must_equal(monitored_account[:access_token_key])
|
76
|
+
account.secret.must_equal(monitored_account[:access_token_secret])
|
77
|
+
account.client_id.must_equal(monitored_account[:client_id])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'facebook' do
|
83
|
+
let(:monitored_account) {
|
84
|
+
FactoryGirl.build(:monitored_account)
|
85
|
+
}
|
86
|
+
|
87
|
+
let(:facebook_page_id) {
|
88
|
+
Faker::Internet.password(8)
|
89
|
+
}
|
90
|
+
|
91
|
+
describe 'get accounts to monitor' do
|
92
|
+
before do
|
93
|
+
stub_get("/api/system/monitored_accounts/facebook/lease?api_token=#{LexerVariables::SECRET_TOKEN}&monitored_object=#{facebook_page_id}").
|
94
|
+
to_return(body: MultiJson.dump(monitored_account)) if $should_stub
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'leases a single account' do
|
98
|
+
account = LexerVariables::MonitoredAccount.lease_object(:facebook, facebook_page_id)
|
99
|
+
account.must_be_instance_of(LexerVariables::MonitoredAccount)
|
100
|
+
account.monitored_object.must_equal(monitored_account[:monitored_object])
|
101
|
+
account.key.must_equal(monitored_account[:access_token_key])
|
102
|
+
account.secret.must_equal(monitored_account[:access_token_secret])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe LexerVariables::MonitoredObject do
|
4
|
+
|
5
|
+
describe 'no objects to acquire' do
|
6
|
+
before do
|
7
|
+
stub_get("/api/system/monitored_objects/twitter/regions/pop?api_token=#{LexerVariables::SECRET_TOKEN}").
|
8
|
+
to_return(body: MultiJson.dump('Not found'), status: 404) if $should_stub
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should fail for an unpopulated type' do
|
12
|
+
assert_raises LexerVariables::RequestError do
|
13
|
+
LexerVariables::MonitoredGeoRegion.pop(provider: :twitter)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#all' do
|
19
|
+
let(:monitored_terms) {
|
20
|
+
(1..10).collect { |x| FactoryGirl.build(:monitored_term, object: x.to_s) }
|
21
|
+
}
|
22
|
+
|
23
|
+
before do
|
24
|
+
stub_get("/api/system/monitored_objects/twitter/terms?api_token=#{LexerVariables::SECRET_TOKEN}").
|
25
|
+
to_return(body: MultiJson.dump(monitored_terms), status: 200) if $should_stub
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should get all monitored terms for single provider' do
|
29
|
+
terms = LexerVariables::MonitoredTerm.all(provider: :twitter)
|
30
|
+
terms.must_be_instance_of(Array)
|
31
|
+
terms.size.must_equal(10)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should shard monitored terms' do
|
35
|
+
terms = LexerVariables::MonitoredTerm.all(provider: :twitter, shards: 4)
|
36
|
+
terms.must_be_instance_of(Array)
|
37
|
+
terms.size.must_equal(4)
|
38
|
+
terms[0].must_be_instance_of(Array)
|
39
|
+
terms[0].size.must_equal(2)
|
40
|
+
terms[1].must_be_instance_of(Array)
|
41
|
+
terms[1].size.must_equal(3)
|
42
|
+
terms.flatten.size.must_equal(10)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#pop' do
|
48
|
+
let(:monitored_term) { |x| FactoryGirl.build(:monitored_term) }
|
49
|
+
|
50
|
+
before do
|
51
|
+
stub_get("/api/system/monitored_objects/twitter/terms/pop?api_token=#{LexerVariables::SECRET_TOKEN}").
|
52
|
+
to_return(body: MultiJson.dump(monitored_term), status: 200) if $should_stub
|
53
|
+
stub_get("/api/system/monitored_objects/twitter/regions/pop?api_token=#{LexerVariables::SECRET_TOKEN}").
|
54
|
+
to_return(body: '{"error":"404 Not Found"}', status: 404) if $should_stub
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should acquire a term' do
|
58
|
+
term1 = LexerVariables::MonitoredTerm.pop(provider: :twitter)
|
59
|
+
term1.to_s.must_equal(monitored_term[:object])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/test/oauth_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe LexerVariables::OAuth do
|
4
|
+
|
5
|
+
describe '#pop' do
|
6
|
+
let(:oauth) { |x| FactoryGirl.build(:oauth) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_get("/api/system/monitored_objects/twitter/oauths/pop?api_token=#{LexerVariables::SECRET_TOKEN}").
|
10
|
+
to_return(body: MultiJson.dump(oauth), status: 200) if $should_stub
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should acquire an OAuth' do
|
14
|
+
oauth = LexerVariables::OAuth.pop(provider: :twitter)
|
15
|
+
oauth.key.must_equal('abcdef')
|
16
|
+
oauth.secret.must_equal('ghi')
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/reporters'
|
5
|
+
require 'minitest/spec'
|
6
|
+
require 'webmock/minitest'
|
7
|
+
require 'faker'
|
8
|
+
require 'factory_girl'
|
9
|
+
|
10
|
+
MiniTest::Reporters.use! [Minitest::Reporters::SpecReporter.new, MiniTest::Reporters::JUnitReporter.new]
|
11
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'lexervariables')
|
12
|
+
FactoryGirl.find_definitions
|
13
|
+
|
14
|
+
$should_stub = true
|
15
|
+
if $should_stub
|
16
|
+
WebMock.disable_net_connect!
|
17
|
+
else
|
18
|
+
WebMock.allow_net_connect!
|
19
|
+
end
|
20
|
+
|
21
|
+
def request_path(path)
|
22
|
+
"https://lexer-dashboard#{path}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def stub_get(path)
|
26
|
+
WebMock::API.stub_http_request(:get, request_path(path))
|
27
|
+
end
|
28
|
+
|
29
|
+
# As the hash requires a key called 'attributes', this breaks factory call as when you call
|
30
|
+
# ```initialise_with { attributes }``` in FactoryGirl, it becomes infinitely recursive.
|
31
|
+
def test_attribute_user
|
32
|
+
{
|
33
|
+
monitored_object: {
|
34
|
+
object: Faker::Number.number(10)
|
35
|
+
},
|
36
|
+
attributes: ['io.company.' + Faker::Lorem::words(1)[0]] * 3
|
37
|
+
}
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lexervariables
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Wallis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: oj
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-reporters
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: factory_girl
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: faker
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description: Gem for loading variables (terms, geographies, authors, pages, oauths)
|
140
|
+
to monitor
|
141
|
+
email:
|
142
|
+
- aaron.wallis@lexer.com.au
|
143
|
+
executables: []
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- Gemfile
|
149
|
+
- README.md
|
150
|
+
- Rakefile
|
151
|
+
- lexervariables.gemspec
|
152
|
+
- lib/lexervariables.rb
|
153
|
+
- lib/lexervariables/api.rb
|
154
|
+
- lib/lexervariables/attribute_generator.rb
|
155
|
+
- lib/lexervariables/attribute_geo_region.rb
|
156
|
+
- lib/lexervariables/attribute_page.rb
|
157
|
+
- lib/lexervariables/attribute_user.rb
|
158
|
+
- lib/lexervariables/dashboard_object.rb
|
159
|
+
- lib/lexervariables/error.rb
|
160
|
+
- lib/lexervariables/monitored_account.rb
|
161
|
+
- lib/lexervariables/monitored_geo_region.rb
|
162
|
+
- lib/lexervariables/monitored_object.rb
|
163
|
+
- lib/lexervariables/monitored_page.rb
|
164
|
+
- lib/lexervariables/monitored_term.rb
|
165
|
+
- lib/lexervariables/monitored_url.rb
|
166
|
+
- lib/lexervariables/monitored_user.rb
|
167
|
+
- lib/lexervariables/oauth.rb
|
168
|
+
- lib/lexervariables/version.rb
|
169
|
+
- test/attribute_generator_test.rb
|
170
|
+
- test/docker-launch-tests.sh
|
171
|
+
- test/docker-run-tests.sh
|
172
|
+
- test/factories/monitored_accounts.rb
|
173
|
+
- test/factories/monitored_terms.rb
|
174
|
+
- test/factories/oauths.rb
|
175
|
+
- test/lexer_variables_test.rb
|
176
|
+
- test/monitored_account_test.rb
|
177
|
+
- test/monitored_object_test.rb
|
178
|
+
- test/oauth_test.rb
|
179
|
+
- test/test_helper.rb
|
180
|
+
homepage: http://lexer.com.au
|
181
|
+
licenses: []
|
182
|
+
metadata: {}
|
183
|
+
post_install_message:
|
184
|
+
rdoc_options: []
|
185
|
+
require_paths:
|
186
|
+
- lib
|
187
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
requirements: []
|
198
|
+
rubyforge_project:
|
199
|
+
rubygems_version: 2.2.2
|
200
|
+
signing_key:
|
201
|
+
specification_version: 4
|
202
|
+
summary: Gem for loading variables (terms, geographies, authors, pages, oauths) to
|
203
|
+
monitor
|
204
|
+
test_files: []
|