lexervariables 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in lexervariables.gemspec
4
+ gemspec
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,9 @@
1
+ # encoding: UTF-8
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |task|
5
+ task.libs << %w(test lib)
6
+ task.pattern = 'test/*.rb'
7
+ end
8
+
9
+ task :default => :test
@@ -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,7 @@
1
+ class LexerVariables::AttributeGeoRegion < LexerVariables::AttributeGenerator
2
+ private
3
+ def self.object_type
4
+ 'regions'
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ class LexerVariables::AttributePage < LexerVariables::AttributeGenerator
2
+ private
3
+ def self.object_type
4
+ 'pages'
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ class LexerVariables::AttributeUser < LexerVariables::AttributeGenerator
2
+ private
3
+ def self.object_type
4
+ 'users'
5
+ end
6
+ end
7
+
@@ -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,7 @@
1
+ module LexerVariables
2
+ Error = Class.new(StandardError)
3
+
4
+ UnknownProvider = Class.new(Error)
5
+ RequestError = Class.new(Error)
6
+ InvalidObject = Class.new(Error)
7
+ end
@@ -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,7 @@
1
+ class LexerVariables::MonitoredGeoRegion < LexerVariables::MonitoredObject
2
+ private
3
+ def self.object_type
4
+ 'regions'
5
+ end
6
+ end
7
+
@@ -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,7 @@
1
+ class LexerVariables::MonitoredPage < LexerVariables::MonitoredObject
2
+ private
3
+ def self.object_type
4
+ 'pages'
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ class LexerVariables::MonitoredTerm < LexerVariables::MonitoredObject
2
+ private
3
+ def self.object_type
4
+ 'terms'
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ class LexerVariables::MonitoredURL < LexerVariables::MonitoredObject
2
+ private
3
+ def self.object_type
4
+ 'urls'
5
+ end
6
+ end
7
+
@@ -0,0 +1,7 @@
1
+ class LexerVariables::MonitoredUser < LexerVariables::MonitoredObject
2
+ private
3
+ def self.object_type
4
+ 'users'
5
+ end
6
+ end
7
+
@@ -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,3 @@
1
+ module LexerVariables
2
+ VERSION = "0.1.0"
3
+ end
@@ -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,4 @@
1
+ #!/bin/bash
2
+
3
+ # Script (*external*) to launch a Docker container and run tests
4
+ docker run --rm -v $(pwd):/code -w /code phusion/passenger-ruby22 /code/test/docker-run-tests.sh
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ # Script to execute lexer-variables.gem tests *inside* a Docker container
4
+ #
5
+ # Expectations:
6
+ # - lexer-variables.gem checkout is mounted at /code
7
+
8
+ bundle install --standalone &&\
9
+ bundle exec rake test
@@ -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,9 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :monitored_term, class:Hash do
4
+ object { Faker::Lorem::words(1)[0] }
5
+
6
+ initialize_with { attributes }
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :oauth, class:Hash do
4
+ object { MultiJson::encode({access_token: 'abcdef', access_token_secret:'ghi'}) }
5
+
6
+ initialize_with { attributes }
7
+ end
8
+
9
+ 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
@@ -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
@@ -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: []