apigee-platform 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ module ApigeePlatform::Objects
2
+ class Api < Base
3
+
4
+ schema do
5
+ string 'name'
6
+ string 'description'
7
+ end
8
+
9
+ set_primary_key :name
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module ApigeePlatform::Objects
2
+ class Apiproduct < Base
3
+ schema do
4
+ string 'name'
5
+ end
6
+
7
+ set_primary_key :name
8
+
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module ApigeePlatform::Objects
2
+ class App < Base
3
+
4
+ schema do
5
+ string 'name'
6
+ end
7
+
8
+ set_primary_key :appId
9
+
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ module ApigeePlatform::Objects
2
+ class Base < ActiveResource::Base
3
+ include ApigeePlatform::Associations
4
+
5
+ def initialize(*args)
6
+ super(*args)
7
+ @id = self.attributes[self.class.primary_key]
8
+ self
9
+ end
10
+
11
+ def custom_attributes
12
+ @custom_attributes ||= ApigeePlatform::CustomAttributes.new(self)
13
+ end
14
+
15
+ def encode(options={})
16
+ super options.merge(:root => false)
17
+ end
18
+
19
+ def load(*args)
20
+ super(*args)
21
+ self.attributes['attributes'].map!{|r| {'name' => r.name, 'value' => r.value}} if self.attributes['attributes']
22
+
23
+ self.class.prefix_options.each do |k,v|
24
+ self.prefix_options[k] = self.attributes[v]
25
+ end
26
+ self.onload if self.respond_to?(:onload)
27
+ self
28
+ end
29
+
30
+ def id
31
+ # need that to get correct element_path when update resource object
32
+ @id ||= self.attributes[self.class.primary_key]
33
+ end
34
+
35
+ class << self
36
+ attr_reader :config
37
+
38
+ def configure(config)
39
+ @config = config.symbolize_keys.slice(:user, :password, :organization, :url)
40
+ @config[:url] ||= 'https://api.enterprise.apigee.com'
41
+
42
+ self.site = @config[:url] + '/v1/o/' + @config[:organization]
43
+ self.user = @config[:user]
44
+ self.password = @config[:password]
45
+
46
+ require 'apigee-platform/objects/api'
47
+ require 'apigee-platform/objects/apiproduct'
48
+ require 'apigee-platform/objects/app'
49
+ require 'apigee-platform/objects/key'
50
+ require 'apigee-platform/objects/company'
51
+ require 'apigee-platform/objects/company_app'
52
+ require 'apigee-platform/objects/company_app_key'
53
+ require 'apigee-platform/objects/developer'
54
+ require 'apigee-platform/objects/developer_app'
55
+ require 'apigee-platform/objects/developer_app_key'
56
+
57
+ self
58
+ end
59
+
60
+ def set_prefix_options(options)
61
+ @prefix_options = options
62
+ end
63
+
64
+ def prefix_options
65
+ @prefix_options || []
66
+ end
67
+
68
+ def instantiate_record(record, prefix_options = {})
69
+ return record unless record.is_a?(Hash)
70
+ super(record, prefix_options)
71
+ end
72
+
73
+ def collection_path(prefix_options = {}, query_options = nil)
74
+ check_prefix_options(prefix_options)
75
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
76
+ "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
77
+ end
78
+
79
+ def element_path(id, prefix_options = {}, query_options = nil)
80
+ check_prefix_options(prefix_options)
81
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
82
+ "#{prefix(prefix_options)}#{collection_name}/#{URI.parser.escape id.to_s}#{query_string(query_options)}"
83
+ end
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,13 @@
1
+ module ApigeePlatform::Objects
2
+ class Company < Base
3
+
4
+ schema do
5
+ string 'name', 'displayName', 'status'
6
+ end
7
+
8
+ set_primary_key :name
9
+ validates_presence_of :name
10
+ has_many :apps, :company_name => :name
11
+
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module ApigeePlatform::Objects
2
+ class CompanyApp < App
3
+ set_primary_key :name
4
+ set_prefix_options :company_name => :companyName
5
+
6
+ self.site = self.site.to_s + "/companies/:company_name"
7
+ validates_presence_of :name
8
+
9
+ belongs_to :company, :key => :companyName
10
+ has_many :keys, :through => :credentials
11
+
12
+ def self.element_name
13
+ 'app'
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module ApigeePlatform::Objects
2
+ class CompanyAppKey < Key
3
+ set_prefix_options :company_name => :companyName, :app_name => :name
4
+ self.site = self.site.to_s + "/companies/:company_name/apps/:app_name"
5
+ set_primary_key :consumerKey
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module ApigeePlatform::Objects
2
+ class Developer < Base
3
+
4
+ schema do
5
+ string 'name', 'email', 'firstName', 'lastName', 'userName', 'organizationName', 'status'
6
+ end
7
+
8
+ set_primary_key :developerId
9
+
10
+ validates_presence_of :firstName, :lastName, :userName, :email
11
+ validates_format_of :email, :with => /\A(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})\Z/i
12
+
13
+ has_many :apps
14
+
15
+ def id
16
+ developerId || email
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module ApigeePlatform::Objects
2
+ class DeveloperApp < App
3
+ set_primary_key :name
4
+ set_prefix_options :developer_id => :developerId
5
+
6
+ self.site = self.site.to_s + "/developers/:developer_id"
7
+
8
+ validates_presence_of :name
9
+ belongs_to :developer
10
+ has_many :keys, :through => :credentials
11
+
12
+ def self.element_name
13
+ 'app'
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module ApigeePlatform::Objects
2
+ class DeveloperAppKey < Key
3
+ set_prefix_options :developer_id => :developerId, :app_name => :name
4
+ self.site = self.site.to_s + "/developers/:developer_id/apps/:app_name"
5
+ set_primary_key :consumerKey
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ module ApigeePlatform::Objects
2
+ #abstract class, describes behavior of api keys, nested in developer_app and company_app
3
+ class Key < Base
4
+ def self.element_name
5
+ 'key'
6
+ end
7
+
8
+ def approve
9
+ connection.post element_path
10
+ end
11
+
12
+ def add_product(product_name)
13
+ unless apiproducts[product_name]
14
+ connection.post element_path, {
15
+ :apiProducts => apiproducts.keys + [product_name]
16
+ }.to_json
17
+ apiproducts[product_name] = 'pending'
18
+ end
19
+ end
20
+
21
+ def approve_product(product_name)
22
+ return false unless apiproducts[product_name]
23
+ connection.post "#{element_path}/apiproducts/#{product_name}?action=approve", '', {'Content-Type' => 'application/octet-stream'}
24
+ apiproducts[product_name] = 'approved'
25
+ end
26
+
27
+ def revoke_product(product_name)
28
+ return false unless apiproducts[product_name]
29
+ connection.post "#{element_path}/apiproducts/#{product_name}?action=revoke", '', {'Content-Type' => 'application/octet-stream'}
30
+ apiproducts[product_name] = 'revoked'
31
+ end
32
+
33
+ def remove_product(product_name)
34
+ return false unless apiproducts[product_name]
35
+ connection.delete "#{element_path}/apiproducts/#{product_name}"
36
+ apiproducts.delete(product_name)
37
+ true
38
+ end
39
+
40
+ def apiproducts
41
+ self.attributes['apiProducts']
42
+ end
43
+
44
+ def onload
45
+ self.attributes['apiProducts'] = self.attributes['apiProducts'].inject({}){|res, el| res[el.apiproduct] = el.status; res }
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ module ApigeePlatform
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ PATCH = 2
6
+ BUILD = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ end
10
+ end
@@ -0,0 +1,130 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ class MortalKombat
4
+ include ApigeePlatform::Associations
5
+ attr_accessor :mk_id
6
+ has_many :characters
7
+
8
+ def self.primary_key
9
+ :mk_id
10
+ end
11
+
12
+ def self.find(*args)
13
+ x = self.new
14
+ x.mk_id = 9
15
+ if args.first == :all
16
+ [x]
17
+ else
18
+ x
19
+ end
20
+ end
21
+ end
22
+
23
+ class MortalKombatCharacter
24
+ include ApigeePlatform::Associations
25
+ attr_accessor :char_id, :mk_id
26
+
27
+ belongs_to :mortal_kombat
28
+ has_many :locations, :through => 'maps'
29
+
30
+ def initialize(*args)
31
+ @params = args
32
+ end
33
+
34
+ def self.prefix_options
35
+ {:version => :mk_id}
36
+ end
37
+
38
+ def self.find(*args)
39
+ x = self.new
40
+ x.char_id = 'Jax'
41
+ if args.first == :all
42
+ [x]
43
+ else
44
+ x
45
+ end
46
+ end
47
+
48
+ def maps
49
+ [
50
+ OpenStruct.new(:attributes => {:name => 'Kuatan'}),
51
+ OpenStruct.new(:attributes => {:name => 'Street'}),
52
+ OpenStruct.new(:attributes => {:name => 'Swamp'})]
53
+ end
54
+ end
55
+
56
+ class MortalKombatCharacterLocation
57
+ attr_accessor :name
58
+ def initialize(params, prefix_params={})
59
+ params.each{|k,v| instance_variable_set("@#{k}", v)}
60
+ end
61
+
62
+ def self.prefix_options
63
+ {:char_id => :char_id}
64
+ end
65
+
66
+ def self.instantiate_record(params, prefix_params={})
67
+ self.new(params, prefix_params)
68
+ end
69
+ end
70
+
71
+
72
+ describe 'class with has_many association' do
73
+ subject { MortalKombat.new }
74
+ it 'can find all nested objects' do
75
+ subject.should respond_to(:characters)
76
+ subject.characters.should be_kind_of(Array)
77
+ end
78
+
79
+ it 'has method to find subobject' do
80
+ subject.should respond_to(:character)
81
+ end
82
+
83
+ it 'is able to find subobject' do
84
+ subject.character('Jax').should be_kind_of(MortalKombatCharacter)
85
+ end
86
+
87
+ it 'return children' do
88
+ subject.characters.first.should be_kind_of(MortalKombatCharacter)
89
+ end
90
+
91
+ it 'can create subobject by getting requesting object without id' do
92
+ subject.character.should be_kind_of(MortalKombatCharacter)
93
+ end
94
+
95
+ it 'has method for creating subobject' do
96
+ subject.create_character.should be_kind_of(MortalKombatCharacter)
97
+ end
98
+
99
+ it 'sets prefix parameters for subobject' do
100
+ subject.instance_variable_set(:@mk_id, 10)
101
+ pp = subject.create_character.instance_variable_get(:@params)
102
+ pp.should include({:mk_id=>10})
103
+ end
104
+ end
105
+
106
+ describe 'class with belongs_to association' do
107
+ subject { MortalKombatCharacter.new }
108
+ it 'has method to get parent' do
109
+ subject.should respond_to(:mortal_kombat)
110
+ end
111
+
112
+ it 'return object of correct class when getting parent' do
113
+ subject.mortal_kombat.should be_kind_of(MortalKombat)
114
+ end
115
+
116
+ end
117
+
118
+ describe 'class with belongs_to(:through => ..) association' do
119
+ subject { MortalKombatCharacter.new }
120
+ it 'has method to nested collection' do
121
+ subject.should respond_to(:locations)
122
+ end
123
+
124
+ it 'returns nested objects from method passed in \'through\' ' do
125
+ subject.locations.count.should == subject.maps.count
126
+ subject.locations.map(&:name).to_set.should == subject.maps.map{|el| el.attributes[:name]}.to_set
127
+ end
128
+
129
+ end
130
+
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'custom attrs' do
4
+ it 'make data accessible as hash elements' do
5
+ obj = OpenStruct.new :attributes => {'attributes' => [{'name' => 'name', 'value' => 'Kitana'}]}
6
+ c = ApigeePlatform::CustomAttributes.new obj
7
+ c['name'].should == obj.attributes['attributes'].first['value']
8
+ end
9
+
10
+ it 'sets new values in source object' do
11
+ obj = OpenStruct.new :attributes => {'attributes' => []}
12
+ c = ApigeePlatform::CustomAttributes.new obj
13
+ c['name'] = 'Johnny Cage'
14
+ obj.attributes['attributes'].first['name'].should == 'name'
15
+ obj.attributes['attributes'].first['value'].should == 'Johnny Cage'
16
+ end
17
+
18
+ it 'return names of data variables' do
19
+ obj = OpenStruct.new :attributes => {'attributes' => [
20
+ {'name' => 'world', 'value' => 'MK'},
21
+ {'name' => 'fighter', 'value' => 'Kano'}
22
+ ]}
23
+ c = ApigeePlatform::CustomAttributes.new obj
24
+ c.keys.to_set.should == ["world", "fighter"].to_set
25
+ end
26
+
27
+ it 'can delete data from source object' do
28
+ obj = OpenStruct.new :attributes => {'attributes' => [{'name' => 'name', 'value' => 'Kitana'}]}
29
+ c = ApigeePlatform::CustomAttributes.new obj
30
+ c.delete('name')
31
+ obj.attributes['attributes'].should be_empty
32
+ end
33
+
34
+ end
@@ -0,0 +1,112 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+
4
+ describe 'DeveloperAppKey' do
5
+ before :all do
6
+ @app_name = 'testapp'
7
+ @developer_email = 'sampledev@example.com'
8
+ @developer_id = 'F1bPGroWVtO9PATt'
9
+ @apiproduct_name = 'myapiproduct'
10
+ @new_apiproduct_name = 'mytest'
11
+ @consumer_key = 'OOdAwgpyifxXPUeMDGKJBqDDDfDK12AS'
12
+ @credentials = [
13
+ {
14
+ "apiProducts" => [{"apiproduct" => @apiproduct_name, "status" => "approved"}],
15
+ "attributes" => [],
16
+ "consumerKey" => @consumer_key,
17
+ "consumerSecret" => "lkECj1mAUzfBmdtD",
18
+ "scopes" => [],
19
+ "status" => "approved"
20
+ }
21
+ ]
22
+ @app = {
23
+ :name => @app_name,
24
+ :appId => '35eaba24-c340-48a2-819e-34d81993f9ab',
25
+ :developerId => @developer_id,
26
+
27
+ :accessType => "read",
28
+ :appFamily => "default",
29
+ :attributes => [{"name"=>"Developer", "value"=>@developer_email}, {"name"=>"DisplayName", "value"=>@app_name}, {"name"=>"Notes", "value"=>""}, {"name"=>"lastModifier", "value"=>""}],
30
+ :callbackUrl => "http://example.com",
31
+ :createdAt => 1369488501956,
32
+ :createdBy => "adminui@apigee.com",
33
+ :credentials => @credentials,
34
+ :lastModifiedAt => 1369555151917,
35
+ :lastModifiedBy => @developer_email,
36
+ :scopes => [],
37
+ :status => "approved"
38
+ }
39
+
40
+ ActiveResource::HttpMock.respond_to do |mock|
41
+ org = ApigeePlatform::Objects::Base.config[:organization]
42
+ mock.get "/v1/o/#{org}/developers/#{@developer_id}/apps/#{@app_name}", GET_HEADERS, @app.to_json
43
+ mock.post "/v1/o/#{org}/developers/#{@developer_id}/apps/#{@app_name}/keys/#{@consumer_key}", POST_HEADERS, {"apiProducts"=>["smtp_public_api", @new_apiproduct_name]}.to_json
44
+ mock.post "/v1/o/#{org}/developers/#{@developer_id}/apps/#{@app_name}/keys/#{@consumer_key}/apiproducts/mytest?action=approve", NO_CONTENT_HEADERS, nil, 204
45
+ mock.post "/v1/o/#{org}/developers/#{@developer_id}/apps/#{@app_name}/keys/#{@consumer_key}/apiproducts/mytest?action=revoke", NO_CONTENT_HEADERS, nil, 204
46
+ mock.delete "/v1/o/#{org}/developers/#{@developer_id}/apps/#{@app_name}/keys/#{@consumer_key}/apiproducts/mytest", GET_HEADERS, nil, 204
47
+ end
48
+ end
49
+
50
+ subject { ApigeePlatform::Objects::DeveloperApp.find(@app_name, :params => {:developer_id => @developer_id}) }
51
+
52
+ it 'has keys' do
53
+ subject.should respond_to(:keys)
54
+ end
55
+
56
+ describe 'Key' do
57
+ subject { ApigeePlatform::Objects::DeveloperApp.find(@app_name, :params => {:developer_id => @developer_id}).keys.first }
58
+ it 'has api products from nested credentials' do
59
+ subject.apiproducts[@credentials.first['apiProducts'].first['apiproduct']].should == @credentials.first['apiProducts'].first['status']
60
+ end
61
+
62
+ it 'can add product' do
63
+ subject.should respond_to(:add_product)
64
+ end
65
+
66
+ it 'can approve product' do
67
+ subject.should respond_to(:approve_product)
68
+ end
69
+
70
+ it 'can revoke product' do
71
+ subject.should respond_to(:revoke_product)
72
+ end
73
+
74
+ it 'can remove product' do
75
+ subject.should respond_to(:remove_product)
76
+ end
77
+
78
+ it 'saves new product' do
79
+ subject.add_product(@new_apiproduct_name)
80
+ subject.apiproducts[@new_apiproduct_name].should be_present
81
+ end
82
+
83
+ it 'saves new product' do
84
+ subject.add_product(@new_apiproduct_name)
85
+ subject.apiproducts[@new_apiproduct_name].should be_present
86
+ end
87
+
88
+ it 'approves product' do
89
+ subject.add_product(@new_apiproduct_name)
90
+ subject.approve_product(@new_apiproduct_name)
91
+ subject.apiproducts[@new_apiproduct_name].should == 'approved'
92
+ end
93
+
94
+ it 'revokes product' do
95
+ subject.add_product(@new_apiproduct_name)
96
+ subject.revoke_product(@new_apiproduct_name)
97
+ subject.apiproducts[@new_apiproduct_name].should == 'revoked'
98
+ end
99
+
100
+ it 'removes product' do
101
+ subject.add_product(@new_apiproduct_name)
102
+ subject.remove_product(@new_apiproduct_name)
103
+ subject.apiproducts[@new_apiproduct_name].should_not be_present
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
110
+
111
+
112
+