mashery_rails 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +12 -0
  3. data/.yardoc/checksums +17 -0
  4. data/.yardoc/object_types +0 -0
  5. data/.yardoc/objects/root.dat +0 -0
  6. data/.yardoc/proxy_types +0 -0
  7. data/Gemfile +21 -0
  8. data/Gemfile.devtools +55 -0
  9. data/Gemfile.lock +215 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +63 -0
  12. data/Rakefile +9 -0
  13. data/VERSION +1 -0
  14. data/config/devtools.yml +2 -0
  15. data/config/flay.yml +3 -0
  16. data/config/flog.yml +2 -0
  17. data/config/mutant.yml +3 -0
  18. data/config/reek.yml +103 -0
  19. data/config/rubocop.yml +58 -0
  20. data/config/yardstick.yml +2 -0
  21. data/lib/mashery.rb +55 -0
  22. data/lib/mashery/config.rb +71 -0
  23. data/lib/mashery/exceptions.rb +46 -0
  24. data/lib/mashery/key.rb +7 -0
  25. data/lib/mashery/local.rb +3 -0
  26. data/lib/mashery/member.rb +8 -0
  27. data/lib/mashery/query_builder.rb +173 -0
  28. data/lib/mashery/rails.rb +19 -0
  29. data/lib/mashery/rest_client.rb +31 -0
  30. data/lib/mashery/rest_client/query.rb +77 -0
  31. data/lib/mashery/rpc_client.rb +58 -0
  32. data/lib/mashery/rpc_client/base.rb +51 -0
  33. data/lib/mashery/rpc_client/response.rb +79 -0
  34. data/lib/mashery/service.rb +9 -0
  35. data/masheri.gemspec +26 -0
  36. data/mashery_rails.gemspec +25 -0
  37. data/spec/fixtures/config.no_host.yml +4 -0
  38. data/spec/fixtures/config.no_key.yml +4 -0
  39. data/spec/fixtures/config.no_secret.yml +4 -0
  40. data/spec/fixtures/config.no_site_id.yml +4 -0
  41. data/spec/fixtures/config.yml +5 -0
  42. data/spec/fixtures/services.json +3 -0
  43. data/spec/mashery/config_spec.rb +38 -0
  44. data/spec/mashery/member_spec.rb +47 -0
  45. data/spec/mashery/query_builder_spec.rb +13 -0
  46. data/spec/mashery/rest_client_spec.rb +47 -0
  47. data/spec/mashery/rpc_client_spec.rb +28 -0
  48. data/spec/mashery/service_spec.rb +101 -0
  49. data/spec/mashery_spec.rb +5 -0
  50. data/spec/spec_helper.rb +50 -0
  51. data/tasks/mashery.thor +200 -0
  52. metadata +147 -0
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery::Member do
4
+ let(:url) { Mashery.rpc.url }
5
+
6
+ let(:items) {
7
+ [{"name" => "Name"}] * 10
8
+ }
9
+
10
+ let(:params) {
11
+ {
12
+ 'method' => "object.query",
13
+ 'params' => [query],
14
+ 'id' => 1
15
+ }
16
+ }
17
+
18
+ let(:headers) {
19
+ {
20
+ "Content-Type" => "application/json",
21
+ "Accept" => "text/plain",
22
+ "Content-Length" => params.size
23
+ }
24
+ }
25
+
26
+ let(:json) {
27
+ {
28
+ "result" => {
29
+ "items" => items
30
+ }
31
+ }.to_json
32
+ }
33
+
34
+
35
+ context "with standard query" do
36
+ let(:query) {
37
+ "SELECT * FROM members ITEMS 100"
38
+ }
39
+
40
+ it "should grab all the members" do
41
+ ::RestClient.should_receive(:post).with(url, params.to_json, headers).and_return(json)
42
+ objects = Mashery::Member.all
43
+ objects.length.should == 10
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery::QueryBuilder do
4
+ it "should build a simple query" do
5
+ builder = Mashery::QueryBuilder.new
6
+ builder.from("members").to_s.should == "SELECT * FROM members"
7
+ end
8
+
9
+ it "should build a query with pagination" do
10
+ builder = Mashery::QueryBuilder.new
11
+ builder.from("members").page(25).items(100).to_s.should == "SELECT * FROM members PAGE 25 ITEMS 100"
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery::RestClient do
4
+ let(:service_key) do
5
+ "12345"
6
+ end
7
+
8
+ let(:url) do
9
+ Mashery::RestClient::Query.new(query_params).url
10
+ end
11
+
12
+ let(:query_params) do
13
+ {service_id: service_key}.merge(options)
14
+ end
15
+
16
+
17
+ context "reasonable date range" do
18
+ let(:options) do
19
+ {
20
+ start_date: 1.day.ago,
21
+ end_date: 0.days.ago,
22
+ resource: "developer_activity"
23
+ }
24
+ end
25
+
26
+ it "should request the service data, given a service key" do
27
+ ::RestClient.should_receive(:get).with(url).and_return("whatever")
28
+ Mashery.activity("developer_activity", service_key, options).should == "whatever"
29
+ end
30
+ end
31
+
32
+ context "invalid date range" do
33
+ let(:options) do
34
+ {
35
+ start_date: 8.day.ago,
36
+ end_date: 0.days.ago,
37
+ resource: "developer_activity"
38
+ }
39
+ end
40
+
41
+ it "should raise an InvalidDateRange error" do
42
+ expect do
43
+ Mashery.activity("developer_activity", service_key, options)
44
+ end.to raise_error(Mashery::InvalidDateRange)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery::RpcClient do
4
+ let(:query) {
5
+ "SELECT * FROM whatevers"
6
+ }
7
+
8
+ let(:params) {
9
+ {
10
+ 'method' => "object.query",
11
+ 'params' => [query],
12
+ 'id' => 1
13
+ }
14
+ }
15
+
16
+ let(:headers) {
17
+ {
18
+ "Content-Type" => "application/json",
19
+ "Accept" => "text/plain",
20
+ "Content-Length" => params.size
21
+ }
22
+ }
23
+
24
+ it "should post to RpcClient with the proper arguments" do
25
+ ::RestClient.should_receive(:post).with(Mashery.rpc.url, params.to_json, headers).and_return({hello: 'world'}.to_json)
26
+ Mashery.rpc.query(query)
27
+ end
28
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery::Service do
4
+ let(:url) { Mashery.rpc.url }
5
+
6
+ let(:items) {
7
+ [{"name" => "Name"}] * 10
8
+ }
9
+
10
+ let(:params) {
11
+ {
12
+ 'method' => "object.query",
13
+ 'params' => [query],
14
+ 'id' => 1
15
+ }
16
+ }
17
+
18
+ let(:headers) {
19
+ {
20
+ "Content-Type" => "application/json",
21
+ "Accept" => "text/plain",
22
+ "Content-Length" => params.size
23
+ }
24
+ }
25
+
26
+ let(:json) {
27
+ {
28
+ "result" => {
29
+ "items" => items
30
+ }
31
+ }.to_json
32
+ }
33
+
34
+ context "with standard query" do
35
+ let(:query) { "SELECT * FROM services ITEMS 100" }
36
+
37
+ it "should grab all the services" do
38
+ ::RestClient.should_receive(:post).with(url, params.to_json, headers).and_return(json)
39
+ objects = Mashery::Service.all
40
+ objects.length.should == 10
41
+ end
42
+ end
43
+
44
+ context "with pagination query" do
45
+ let(:query) { "SELECT * FROM services PAGE 3 ITEMS 100"}
46
+
47
+ it "should grab the 3rd page of services" do
48
+ ::RestClient.should_receive(:post).with(url, params.to_json, headers).and_return(json)
49
+ objects = Mashery::Service.page(3).all
50
+ objects.length.should == 10
51
+ end
52
+ end
53
+
54
+ context "with auto-pagination via find_each" do
55
+ let(:total_pages) { 5 }
56
+
57
+ def query(page)
58
+ if page == 1
59
+ "SELECT * FROM services ITEMS 100"
60
+ else
61
+ "SELECT * FROM services PAGE #{page} ITEMS 100"
62
+ end
63
+ end
64
+
65
+ def params(page)
66
+ {
67
+ 'method' => "object.query",
68
+ 'params' => [query(page)],
69
+ 'id' => 1
70
+ }
71
+ end
72
+
73
+ def json(page)
74
+ {
75
+ "result" => {
76
+ "total_pages" => total_pages,
77
+ "current_page" => page,
78
+ "items" => items
79
+ }
80
+ }.to_json
81
+ end
82
+
83
+ def headers(page)
84
+ {
85
+ "Content-Type" => "application/json",
86
+ "Accept" => "text/plain",
87
+ "Content-Length" => params(page).size
88
+ }
89
+ end
90
+
91
+ it "should invoke a new query for each page" do
92
+ (1..total_pages).each do |n|
93
+ ::RestClient.should_receive(:post).with(url, params(n).to_json, headers(n)).and_return(json(n))
94
+ end
95
+
96
+ Mashery::Service.find_each do |entry|
97
+ entry.should be_a(Mashery::Service)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mashery do
4
+ # Test configuration?
5
+ end
@@ -0,0 +1,50 @@
1
+ require 'bundler'
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start
5
+
6
+ $LOAD_PATH.unshift File.expand_path("./lib")
7
+ require 'mashery'
8
+
9
+ Bundler.require(:test)
10
+
11
+ require 'coveralls'
12
+ Coveralls.wear!
13
+
14
+ RSpec.configure do |config|
15
+ config.treat_symbols_as_metadata_keys_with_true_values = true
16
+ config.run_all_when_everything_filtered = true
17
+ config.filter_run :focus
18
+
19
+ # Run specs in random order to surface order dependencies. If you find an
20
+ # order dependency and want to debug it, you can fix the order by providing
21
+ # the seed, which is printed after each run.
22
+ # --seed 1234
23
+ config.order = 'random'
24
+
25
+ config.before do
26
+ Timecop.freeze Time.now
27
+ end
28
+
29
+ config.before do
30
+ config = double("config")
31
+
32
+ key = "regular_key"
33
+ secret = "super_long_secret"
34
+ signature = Digest::MD5.hexdigest(key + secret + Time.now.to_f.to_i.to_s)
35
+
36
+ config.stub({
37
+ site_id: "987",
38
+ key: key,
39
+ secret: secret,
40
+ signature: signature,
41
+ host: "masheri.example.com",
42
+ })
43
+
44
+ Mashery.config = config
45
+ end
46
+
47
+ config.after do
48
+ Timecop.return
49
+ end
50
+ end
@@ -0,0 +1,200 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+ # XXX: only do this when the task has not been installed
6
+ $: << 'lib'
7
+
8
+ require 'mashery'
9
+
10
+ module Mashery
11
+ class CLI < Thor
12
+ namespace :mashery
13
+
14
+ desc "echo VALUE", "Echo the provided value (tests connectivity and authentication)"
15
+ def echo(value)
16
+ run { ok(::Mashery.client.echo(value)) }
17
+ end
18
+
19
+ protected
20
+ def run(&block)
21
+ site_id = ENV['MASHERY_SITE_ID'] or
22
+ raise Exception, "Please set the MASHERY_SITE_ID environment variable."
23
+ key = ENV['MASHERY_API_KEY'] or
24
+ raise Exception, "Please set the MASHERY_API_KEY environment variable."
25
+ secret = ENV['MASHERY_SHARED_SECRET'] or
26
+ raise Exception, "Please set the MASHERY_SHARED_SECRET environment variable."
27
+ ::Mashery.test_mode = ENV['MASHERY_PRODUCTION_MODE'].blank?
28
+ ::Mashery.logger.level = Logger::DEBUG
29
+ ::Mashery.client = ::Mashery::Client.new(site_id, key, secret)
30
+ begin
31
+ yield
32
+ rescue ::Mashery::HttpException => e
33
+ error("HTTP error: #{e.message}")
34
+ rescue ::Mashery::JsonRpcException => e
35
+ error(e.message)
36
+ rescue ::Mashery::ValidationException => e
37
+ e.errors.each {|err| warn("#{err['field']}: #{err['message']}")}
38
+ error("Unable to execute method due to validation errors")
39
+ end
40
+ end
41
+
42
+ def warn(msg)
43
+ say_status :WARN, msg, :yellow
44
+ end
45
+
46
+ def ok(msg)
47
+ say_status :OK, msg
48
+ end
49
+
50
+ def error(msg)
51
+ say_status :ERROR, msg, :red
52
+ end
53
+
54
+ def debug(msg)
55
+ say_status :DEBUG, msg, :cyan
56
+ end
57
+ end
58
+
59
+ class MemberCLI < CLI
60
+ namespace 'mashery:member'
61
+
62
+ desc "create USERNAME DISPLAY_NAME EMAIL [--fields ...]", "Create a member"
63
+ method_option :fields, :type => :hash
64
+ def create(username, display_name, email)
65
+ run do
66
+ begin
67
+ member = ::Mashery::Member.create(username, display_name, email, options[:fields])
68
+ ok("Member #{member.username} created")
69
+ rescue ::Mashery::DuplicateObjectException
70
+ error("The username #{username} has already been claimed")
71
+ end
72
+ end
73
+ end
74
+
75
+ desc "fetch USERNAME", "Fetch a member"
76
+ def fetch(username)
77
+ run do
78
+ member = ::Mashery::Member.fetch(username)
79
+ if member
80
+ ok("Member #{username} found")
81
+ say(member.to_yaml)
82
+ else
83
+ warn("Member #{username} not found")
84
+ end
85
+ end
86
+ end
87
+
88
+ desc "addrole USERNAME ROLE_ID", "Assign a role to a member"
89
+ def addrole(username, role_id)
90
+ run do
91
+ member = ::Mashery::Member.fetch(username)
92
+ if member
93
+ role = ::Mashery::Role.fetch(role_id.to_i)
94
+ if role
95
+ member.add_role(role)
96
+ ok("Role #{role.name} assigned to member #{username}")
97
+ else
98
+ warn("Role #{role_id} not found")
99
+ end
100
+ else
101
+ warn("Member #{username} not found")
102
+ end
103
+ end
104
+ end
105
+
106
+ desc "rmrole USERNAME ROLE_ID", "Revoke a role from a member"
107
+ def rmrole(username, role_id)
108
+ run do
109
+ member = ::Mashery::Member.fetch(username)
110
+ if member
111
+ role = ::Mashery::Role.fetch(role_id.to_i)
112
+ if role
113
+ member.remove_role(role)
114
+ ok("Role #{role.name} revoked from member #{username}")
115
+ else
116
+ warn("Role #{role_id} not found")
117
+ end
118
+ else
119
+ warn("Member #{username} not found")
120
+ end
121
+ end
122
+ end
123
+
124
+ desc "delete USERNAME", "Delete a member"
125
+ def delete(username)
126
+ run do
127
+ ::Mashery::Member.delete(username)
128
+ ok("Member #{username} deleted")
129
+ end
130
+ end
131
+ end
132
+
133
+ class KeyCLI < CLI
134
+ namespace 'mashery:key'
135
+
136
+ desc "create SERVICE_KEY USERNAME [--fields ...]", "Create a key"
137
+ method_option :fields, :type => :hash
138
+ def create(service_key, username)
139
+ run do
140
+ key = ::Mashery::Key.create(service_key, username, options[:fields])
141
+ ok("Key #{key.id} created for member #{username} and service #{service_key}")
142
+ end
143
+ end
144
+
145
+ desc "fetch ID", "Fetch a key"
146
+ def fetch(id)
147
+ run do
148
+ key = ::Mashery::Key.fetch(id.to_i)
149
+ if key
150
+ ok("Key #{id} found")
151
+ say(key.to_yaml)
152
+ else
153
+ warn("Key #{id} not found")
154
+ end
155
+ end
156
+ end
157
+
158
+ desc "delete ID", "Delete a key"
159
+ def delete(id)
160
+ run do
161
+ ::Mashery::Key.delete(id.to_i)
162
+ ok("Key #{id} deleted")
163
+ end
164
+ end
165
+ end
166
+
167
+ class RoleCLI < CLI
168
+ namespace 'mashery:role'
169
+
170
+ desc "create NAME [--fields ...]", "Create a role"
171
+ method_option :fields, :type => :hash
172
+ def create(name)
173
+ run do
174
+ role = ::Mashery::Role.create(name, options[:fields])
175
+ ok("Role #{role.id} created with name #{name}")
176
+ end
177
+ end
178
+
179
+ desc "fetch ID", "Fetch a role"
180
+ def fetch(id)
181
+ run do
182
+ role = ::Mashery::Role.fetch(id.to_i)
183
+ if role
184
+ ok("Role #{id} found")
185
+ say(role.to_yaml)
186
+ else
187
+ warn("Role #{id} not found")
188
+ end
189
+ end
190
+ end
191
+
192
+ desc "delete ID", "Delete a role"
193
+ def delete(id)
194
+ run do
195
+ ::Mashery::Role.delete(id.to_i)
196
+ ok("Role #{id} deleted")
197
+ end
198
+ end
199
+ end
200
+ end