apigee-platform 0.0.2

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.
@@ -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
+