ey_services_fake 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ey_services_fake/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ey_services_fake"
7
+ s.version = EyServicesFake::VERSION
8
+ s.authors = ["Jacob Burkhart & Josh Lane"]
9
+ s.email = ["jacob@engineyard.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A fake for use when writting tests against the ey_services_api}
12
+ s.description = %q{A fake for use when writting tests against the ey_services_api}
13
+
14
+ s.rubyforge_project = "ey_services_fake"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "sinatra"
22
+ s.add_dependency "cubbyhole", ">= 0.2.0"
23
+ end
@@ -0,0 +1,151 @@
1
+ module EyServicesFake
2
+ class MockBackend
3
+
4
+ def self.tresfiestas_fake
5
+ require 'ey_services_fake/tresfiestas_fake'
6
+ TresfiestasFake
7
+ end
8
+
9
+ def self.setup!(actors = {})
10
+ unless actors[:awsm]
11
+ require 'ey_services_fake/reacharound_awsm'
12
+ actors[:awsm] = ReacharoundAwsm.new
13
+ end
14
+ unless actors[:service_provider]
15
+ require 'ey_services_fake/mocking_bird_service'
16
+ actors[:service_provider] = MockingBirdService.new
17
+ end
18
+ unless actors[:tresfiestas]
19
+ actors[:tresfiestas] = tresfiestas_fake.new
20
+ end
21
+ new(actors)
22
+ end
23
+
24
+ def initialize(actors)
25
+ @actors = actors
26
+ end
27
+
28
+ def actor(role)
29
+ @actors[role] or raise "No actor registered as #{role}, I have #{@actors.keys.inspect}"
30
+ end
31
+
32
+ def reset!
33
+ @actors.values.each do |v|
34
+ v.reset!
35
+ end
36
+ end
37
+
38
+ def awsm
39
+ awsm_hash = actor(:tresfiestas).find_awsm
40
+ unless awsm_hash
41
+ awsm_hash = actor(:tresfiestas).create_awsm(actor(:awsm).base_url, actor(:awsm).app)
42
+ actor(:awsm).setup(awsm_hash[:auth_id], awsm_hash[:auth_key], actor(:tresfiestas).base_url, actor(:tresfiestas).app)
43
+ end
44
+ awsm_hash
45
+ end
46
+
47
+ def partner
48
+ partner_hash = actor(:tresfiestas).find_partner(sso_user)
49
+ unless partner_hash
50
+ partner_hash = actor(:tresfiestas).create_partner(sso_user, actor(:service_provider).base_url, actor(:service_provider).app)
51
+ @actors.values.each do |actor|
52
+ if actor.respond_to?(:service_provider_setup)
53
+ actor.service_provider_setup(partner_hash[:auth_id], partner_hash[:auth_key], actor(:service_provider).base_url, actor(:service_provider).app)
54
+ end
55
+ end
56
+ actor(:service_provider).setup(partner_hash[:auth_id], partner_hash[:auth_key], actor(:tresfiestas).base_url, actor(:tresfiestas).app)
57
+ end
58
+ partner_hash
59
+ end
60
+
61
+ def service
62
+ partner_hash = self.partner
63
+ service_hash = actor(:tresfiestas).find_service(partner_hash[:id])
64
+ unless service_hash
65
+ actor(:service_provider).register_service(partner_hash[:registration_url])
66
+ service_hash = actor(:tresfiestas).find_service(partner_hash[:id])
67
+ end
68
+ service_hash.merge(:partner => partner_hash)
69
+ end
70
+
71
+ def sso_user
72
+ actor(:awsm).sso_user #allows for nils (some implementations of AWSM may decide this is ok)
73
+ end
74
+
75
+ def sso_account
76
+ awsm #need to have setup awsm before you can create accounts!
77
+ sso_user_something = sso_user #the sso_user is a somehting, not necessarily a hash
78
+ sso_account_hash = actor(:awsm).find_sso_account(sso_user_something)
79
+ unless sso_account_hash
80
+ sso_account_hash = actor(:awsm).create_sso_account(sso_user_something)
81
+ end
82
+ sso_account_hash
83
+ end
84
+
85
+ def service_enablement
86
+ sso_account_hash = self.sso_account
87
+ service_hash = self.service
88
+ unless actor(:tresfiestas).service_available_for_account?(service_hash[:id], sso_account_hash[:id])
89
+ actor(:tresfiestas).make_service_available_for_account(service_hash[:id], sso_account_hash[:id])
90
+ end
91
+ {
92
+ :service => service_hash,
93
+ :sso_account => sso_account_hash,
94
+ }
95
+ end
96
+
97
+ def service_account
98
+ service_enablement_hash = self.service_enablement
99
+ sso_account_hash = service_enablement_hash[:sso_account]
100
+ service_hash = service_enablement_hash[:service]
101
+ service_account_hash = actor(:tresfiestas).find_service_account(service_hash[:id], sso_account_hash[:id])
102
+ unless service_account_hash
103
+ actor(:awsm).enable_service(service_hash[:id], sso_account_hash[:id])
104
+ service_account_hash = actor(:tresfiestas).find_service_account(service_hash[:id], sso_account_hash[:id])
105
+ end
106
+ service_account_hash.merge(:name => sso_account_hash[:name], :service => service_hash, :sso_account => sso_account_hash)
107
+ end
108
+
109
+ def destroy_service_account
110
+ actor(:awsm).disable_service(service_account[:id])
111
+ end
112
+
113
+ def app_deployment
114
+ app_deployment_hash = actor(:awsm).find_app_deployment(sso_account[:id])
115
+ unless app_deployment_hash
116
+ actor(:awsm).create_app_deployment(sso_account[:id], "myapp", "myenv", "production")
117
+ app_deployment_hash = actor(:awsm).find_app_deployment(sso_account[:id])
118
+ end
119
+ app_deployment_hash
120
+ end
121
+
122
+ def provisioned_service
123
+ service_account_hash = self.service_account
124
+ sso_account_hash = service_account_hash[:sso_account]
125
+ app_deployment_hash = self.app_deployment
126
+ provisioned_service_hash = actor(:tresfiestas).find_provisioned_service(service_account_hash[:id], app_deployment_hash[:id])
127
+ unless provisioned_service_hash
128
+ actor(:awsm).provision_service(sso_account_hash[:id], service_account_hash[:id], app_deployment_hash[:id])
129
+ provisioned_service_hash = actor(:tresfiestas).find_provisioned_service(service_account_hash[:id], app_deployment_hash[:id])
130
+ end
131
+ provisioned_service_hash.merge(:service_account => service_account_hash, :app_deployment => app_deployment_hash)
132
+ end
133
+
134
+ def destroy_provisioned_service
135
+ actor(:awsm).deprovision_service(provisioned_service[:id])
136
+ end
137
+
138
+ def latest_invoice
139
+ actor(:tresfiestas).latest_invoice
140
+ end
141
+
142
+ def latest_status_message
143
+ actor(:tresfiestas).latest_status_message
144
+ end
145
+
146
+ def send_message(message_url, message_type, message_subject, message_body = nil)
147
+ actor(:service_provider).send_message(message_url, message_type, message_subject, message_body)
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,122 @@
1
+ require 'sinatra/base'
2
+
3
+ module EyServicesFake
4
+ class MockingBirdService
5
+ class Application < Sinatra::Base
6
+ enable :raise_errors
7
+ disable :dump_errors
8
+ disable :show_exceptions
9
+
10
+ delete '/api/1/some_provisioned_service' do
11
+ {}.to_json
12
+ end
13
+
14
+ delete '/api/1/some_service_account' do
15
+ {}.to_json
16
+ end
17
+
18
+ post '/api/1/service_accounts_callback' do
19
+ service_account = EY::ServicesAPI::ServiceAccountCreation.from_request(request.body.read)
20
+ standard_response_params = MockingBirdService.service_account_creation_params
21
+ EY::ServicesAPI::ServiceAccountResponse.new(
22
+ :provisioned_services_url => standard_response_params[:provisioned_services_url],
23
+ :url => standard_response_params[:url],
24
+ :configuration_url => standard_response_params[:configuration_url],
25
+ :configuration_required => standard_response_params[:configuration_required],
26
+ :message => EY::ServicesAPI::Message.new(:message_type => "status", :subject => "some messages")
27
+ ).to_hash.to_json
28
+ end
29
+
30
+ post '/api/1/provisioned_services_callback' do
31
+ provisioned_service = EY::ServicesAPI::ProvisionedServiceCreation.from_request(request.body.read)
32
+ standard_response_params = MockingBirdService.service_provisioned_params
33
+ EY::ServicesAPI::ProvisionedServiceResponse.new(
34
+ :url => standard_response_params[:url],
35
+ :vars => standard_response_params[:vars],
36
+ :configuration_required => false,
37
+ :configuration_url => standard_response_params[:configuration_url],
38
+ :message => EY::ServicesAPI::Message.new(:message_type => "status", :subject => "some provisioned service messages")
39
+ ).to_hash.to_json
40
+ end
41
+
42
+ get '/sso/some_service_account' do
43
+ "SSO Hello Service Account"
44
+ end
45
+
46
+ get '/sso/some_provisioned_service' do
47
+ "SSO Hello Provisioned Service"
48
+ end
49
+ end
50
+
51
+ def reset!
52
+ #no-op
53
+ end
54
+
55
+ def app
56
+ Application
57
+ end
58
+
59
+ def setup(auth_id, auth_key, base_url = nil, backend = nil)
60
+ require 'ey_services_api'
61
+ connection = EY::ServicesAPI.setup!(:auth_id => auth_id, :auth_key => auth_key)
62
+ if backend
63
+ connection.backend = backend
64
+ end
65
+ end
66
+
67
+ def base_url
68
+ self.class.base_url
69
+ end
70
+ def self.base_url
71
+ "http://mock.service/"
72
+ end
73
+
74
+ def registration_params
75
+ self.class.registration_params
76
+ end
77
+ def self.registration_params
78
+ {
79
+ :name => "Mocking Bird",
80
+ :description => "a mock service",
81
+ :service_accounts_url => "#{base_url}api/1/service_accounts_callback",
82
+ :home_url => "#{base_url}",
83
+ :terms_and_conditions_url => "#{base_url}terms",
84
+ :vars => ["SOME_ENV_VAR", "OTHER_VAR"]
85
+ }
86
+ end
87
+
88
+ def service_account_creation_params
89
+ self.class.service_account_creation_params
90
+ end
91
+ def self.service_account_creation_params
92
+ {
93
+ :provisioned_services_url => "#{base_url}api/1/provisioned_services_callback",
94
+ :url => "#{base_url}api/1/some_service_account",
95
+ :configuration_url => "#{base_url}sso/some_service_account",
96
+ :configuration_required => false
97
+ }
98
+ end
99
+
100
+ def service_provisioned_params
101
+ self.class.service_provisioned_params
102
+ end
103
+ def self.service_provisioned_params
104
+ {
105
+ :vars => {"SOME_ENV_VAR" => "value", "OTHER_VAR" => "blah"},
106
+ :configuration_url => "#{base_url}sso/some_provisioned_service",
107
+ :configuration_required => false,
108
+ :url => "#{base_url}api/1/some_provisioned_service",
109
+ }
110
+ end
111
+
112
+ def register_service(registration_url)
113
+ EY::ServicesAPI.connection.register_service(registration_url, MockingBirdService.registration_params)
114
+ end
115
+
116
+ def send_message(message_url, message_type, message_subject, message_body)
117
+ message = EY::ServicesAPI::Message.new(:message_type => message_type, :subject => message_subject, :body => message_body)
118
+ EY::ServicesAPI.connection.send_message(message_url, message)
119
+ end
120
+
121
+ end
122
+ end
@@ -0,0 +1,64 @@
1
+ require 'cubbyhole/base'
2
+
3
+ module EyServicesFake
4
+ class Model < Cubbyhole::Base
5
+ def self.inherited(klass)
6
+ decendants << klass
7
+ end
8
+ def self.nuke_all
9
+ decendants.map(&:nuke)
10
+ end
11
+ def self.backend
12
+ @backend ||= Hash.new
13
+ end
14
+ def self.decendants
15
+ @decendants ||= []
16
+ end
17
+ def self.belongs_to(model, name, key)
18
+ search_context = self.to_s.split("::")
19
+ search_context.pop
20
+ search_context = eval(search_context.join("::").to_s)
21
+ self.class_eval do
22
+ define_method(name) do
23
+ klass = search_context.const_get(model)
24
+ klass.all.find{|s| self.send(key).to_i == s.id.to_i }
25
+ end
26
+ end
27
+ end
28
+ def self.has_many(model, name, key)
29
+ search_context = self.to_s.split("::")
30
+ search_context.pop
31
+ search_context = eval(search_context.join("::").to_s)
32
+ self.class_eval do
33
+ define_method(name) do
34
+ klass = search_context.const_get(model)
35
+ Cubbyhole::Collection.new(klass.all.select{|s| s.send(key).to_s == self.id.to_s })
36
+ end
37
+ end
38
+ end
39
+ end
40
+ class Partner < Model
41
+ has_many :Service, :services, :partner_id
42
+ end
43
+ class Service < Model
44
+ has_many :ServiceEnablement, :service_enablements, :service_id
45
+ has_many :ServiceAccount, :service_accounts, :service_id
46
+ belongs_to :Partner, :partner, :partner_id
47
+ end
48
+ class ServiceAccount < Model
49
+ has_many :ProvisionedService, :provisioned_services, :service_account_id
50
+ has_many :Message, :messages, :service_account_id
51
+ belongs_to :Service, :service, :service_id
52
+ end
53
+ class ProvisionedService < Model
54
+ has_many :Message, :messages, :provisioned_service_id
55
+ belongs_to :ServiceAccount, :service_account, :service_account_id
56
+ end
57
+ class ServiceEnablement < Model; end
58
+ class Invoice < Model; end
59
+ class Message < Model
60
+ belongs_to :ServiceAccount, :service_account, :service_account_id
61
+ belongs_to :ProvisionedService, :provisioned_service, :provisioned_service_id
62
+ end
63
+ class Awsm < Model; end
64
+ end
@@ -0,0 +1,155 @@
1
+ require 'sinatra/base'
2
+ require 'ey_services_fake/models'
3
+
4
+ module EyServicesFake
5
+ class ReacharoundAwsm
6
+ class Application < Sinatra::Base
7
+ enable :raise_errors
8
+ disable :dump_errors
9
+ disable :show_exceptions
10
+
11
+ post '/dashboard_notifications_url' do
12
+ {}.to_json
13
+ end
14
+
15
+ end
16
+
17
+ def app
18
+ Application
19
+ end
20
+
21
+ def reset!
22
+ #no-op
23
+ end
24
+
25
+ def base_url
26
+ "http://cloud.engineyard.com"
27
+ end
28
+
29
+ class Account < EyServicesFake::Model; end
30
+ class AppDeployment < EyServicesFake::Model
31
+ belongs_to :App, :app, :app_id
32
+ belongs_to :Environment, :environment, :environment_id
33
+ end
34
+ class App < EyServicesFake::Model; end
35
+ class Environment < EyServicesFake::Model; end
36
+ class User < EyServicesFake::Model
37
+ has_many :Account, :accounts, :owner_id
38
+ end
39
+
40
+ def service_provider_setup(auth_id, auth_key, service_provider_url, service_provider_rackapp)
41
+ @connection = EY::ApiHMAC::BaseConnection.new(auth_id, auth_key).tap{|c| c.backend = service_provider_rackapp}
42
+ end
43
+ def setup(auth_id, auth_key, tresfiestas_url, tresfiestas_rackapp)
44
+ #ignored... we don't talk to tresfiestas, we talk to service_provider
45
+ end
46
+
47
+ def sso_user
48
+ the_one_email = "the-one-user@example.com"
49
+ User.first(:email => the_one_email) || User.create(:email => the_one_email)
50
+ end
51
+
52
+ def find_sso_account(sso_user)
53
+ account = sso_user.accounts.first
54
+ account && {
55
+ :id => account.id,
56
+ :name => account.name,
57
+ }
58
+ end
59
+ def create_sso_account(sso_user)
60
+ Account.create(:owner_id => sso_user.id, :name => 'some-account')
61
+ find_sso_account(sso_user)
62
+ end
63
+
64
+ def find_app_deployment(sso_account_id)
65
+ app_deployment = AppDeployment.first(:account_id => sso_account_id)
66
+ app_deployment && {
67
+ :id => app_deployment.id,
68
+ :app => {
69
+ :name => app_deployment.app.name,
70
+ },
71
+ :environment => {
72
+ :name => app_deployment.environment.name,
73
+ :framework_env => app_deployment.environment.framework_env,
74
+ }
75
+ }
76
+ end
77
+ def create_app_deployment(sso_account_id, app_name, env_name, framework_env)
78
+ app = App.create(:name => app_name)
79
+ env = Environment.create(:name => env_name, :framework_env => framework_env)
80
+ AppDeployment.create(:account_id => sso_account_id, :app_id => app.id, :environment_id => env.id)
81
+ end
82
+
83
+ #Normal implmentations of AWSM would not be posting to service_accounts_url;
84
+ #they would be posting to private API to say that they wish to create a service account
85
+ #but this is reacharound AWSM, and so it plays the role of tresfiestas internals here
86
+ # def enable_service(connection, sso_account, service_hash)
87
+ def enable_service(service_id, sso_account_id)
88
+ url_gen = EyServicesFake::URL_GEN
89
+ service_account = ServiceAccount.create(:sso_account_id => sso_account_id, :active => false, :service_id => service_id, :dashboard_notifications_url => "#{base_url}/dashboard_notifications_url")
90
+ service = Service.get(service_id)
91
+ creation_attributes = {
92
+ :name => Account.get(sso_account_id).name,
93
+ :url => url_gen.partner_service_account(service, service_account),
94
+ :messages_url => url_gen.messages(service, service_account),
95
+ :invoices_url => url_gen.invoices(service, service_account),
96
+ }
97
+ @connection.post(service.service_accounts_url, creation_attributes) do |result, location|
98
+ service_account.active = true
99
+ service_account.provisioned_services_url = result["service_account"]['provisioned_services_url']
100
+ service_account.configuration_url = result["service_account"]['configuration_url']
101
+ service_account.url = result["service_account"]['url']
102
+ service_account.configuration_required = result["service_account"]['configuration_required']
103
+ if result["message"] && result["message"]["message_type"]
104
+ Message.create(
105
+ :service_account_id => service_account.id,
106
+ :message_type => result["message"]["message_type"],
107
+ :subject => result["message"]["subject"],
108
+ :body => result["message"]["body"])
109
+ end
110
+ service_account.save
111
+ end
112
+ end
113
+
114
+ def disable_service(service_account_id)
115
+ service_account = ServiceAccount.get(service_account_id)
116
+ @connection.delete(service_account.url)
117
+ end
118
+
119
+ def provision_service(sso_account_id, service_account_id, app_deployment_id)
120
+ url_gen = EyServicesFake::URL_GEN
121
+ provisioned_service = ProvisionedService.create(:app_deployment_id => app_deployment_id.to_i, :active => false, :service_account_id => service_account_id.to_i, :dashboard_notifications_url => "#{base_url}/dashboard_notifications_url")
122
+ service_account_object = ServiceAccount.get(service_account_id)
123
+ app_deployment = AppDeployment.get(app_deployment_id)
124
+ app = app_deployment.app
125
+ environment = app_deployment.environment
126
+ provision_attribtues = {
127
+ :url => url_gen.partner_provisioned_service(service_account_object, provisioned_service),
128
+ :messages_url => url_gen.messages(service_account_object.service, service_account_object, provisioned_service),
129
+ :app => {:id => app.id, :name => app.name},
130
+ :environment => {:id => environment.id, :name => environment.name, :framework_env => environment.framework_env},
131
+ }
132
+ @connection.post(service_account_object.provisioned_services_url, provision_attribtues) do |result, location|
133
+ provisioned_service.active = true
134
+ provisioned_service.vars = result['provisioned_service']["vars"]
135
+ provisioned_service.configuration_url = result['provisioned_service']["configuration_url"]
136
+ provisioned_service.configuration_required = result['provisioned_service']["configuration_required"]
137
+ provisioned_service.url = result['provisioned_service']["url"]
138
+ if result["message"] && result["message"]["message_type"]
139
+ Message.create(
140
+ :provisioned_service_id => provisioned_service.id,
141
+ :message_type => result["message"]["message_type"],
142
+ :subject => result["message"]["subject"],
143
+ :body => result["message"]["body"])
144
+ end
145
+ provisioned_service.save
146
+ end
147
+ end
148
+
149
+ def deprovision_service(provisioned_service_id)
150
+ provisioned_service = ProvisionedService.get(provisioned_service_id)
151
+ @connection.delete(provisioned_service.url)
152
+ end
153
+
154
+ end
155
+ end
@@ -0,0 +1,134 @@
1
+ require 'ey_services_fake/url_generator'
2
+ require 'ey_services_fake/models'
3
+ require 'ey_services_fake/tresfiestas_fake_rack_app'
4
+
5
+ module EyServicesFake
6
+ BASE_URL = "http://services.engineyard.com"
7
+ URL_GEN = EyServicesFake::UrlGenerator.new(BASE_URL)
8
+
9
+ class TresfiestasFake
10
+
11
+ def reset!
12
+ Model.nuke_all
13
+ end
14
+
15
+ def base_url
16
+ BASE_URL
17
+ end
18
+
19
+ def app
20
+ TresfiestasFakeRackApp
21
+ end
22
+
23
+ def find_awsm
24
+ awsm_object = Awsm.first
25
+ awsm_object && {
26
+ :id => awsm_object.id,
27
+ :auth_id => awsm_object.auth_id,
28
+ :auth_key => awsm_object.auth_key,
29
+ }
30
+ end
31
+
32
+ def create_awsm(awsm_base_url, awsm_app)
33
+ Awsm.create(:auth_id => "789eef", :auth_key => "009abb")
34
+ app.awsm_connection = EY::ApiHMAC::BaseConnection.new("789eef", "009abb")
35
+ app.awsm_connection.backend = awsm_app
36
+ find_awsm
37
+ end
38
+
39
+ def find_partner(sso_user)
40
+ partner_object = Partner.first
41
+ partner_object && {
42
+ :id => partner_object.id,
43
+ :auth_id => partner_object.auth_id,
44
+ :auth_key => partner_object.auth_key,
45
+ :registration_url => URL_GEN.service_registration(partner_object),
46
+ }
47
+ end
48
+
49
+ def create_partner(sso_user, partner_base_url, partner_app)
50
+ Partner.create(:auth_id => "123edf", :auth_key => "abc456")
51
+ app.partner_connection = EY::ApiHMAC::BaseConnection.new("123edf", "abc456")
52
+ app.partner_connection.backend = partner_app
53
+ find_partner(sso_user)
54
+ end
55
+
56
+ def find_service(partner_id)
57
+ partner_object = Partner.get!(partner_id)
58
+ service_object = partner_object.services.first
59
+ service_object && {
60
+ :id => service_object.id,
61
+ :name => service_object.name,
62
+ :service_accounts_url => service_object.service_accounts_url
63
+ }
64
+ end
65
+
66
+ def service_available_for_account?(service_id, sso_account_id)
67
+ Service.get(service_id).service_enablements.first(:sso_account_id => sso_account_id)
68
+ end
69
+
70
+ def make_service_available_for_account(service_id, sso_account_id)
71
+ ServiceEnablement.create(:service_id => service_id.to_i, :sso_account_id => sso_account_id.to_i, :reason => "test")
72
+ end
73
+
74
+ def find_service_account(service_id, sso_account_id)
75
+ service_object = Service.get(service_id)
76
+ service_account_object = service_object.service_accounts.first(:sso_account_id => sso_account_id)
77
+ service_account_object && {
78
+ :id => service_account_object.id,
79
+ :url => URL_GEN.partner_service_account(service_object, service_account_object),
80
+ :messages_url => URL_GEN.messages(service_object, service_account_object),
81
+ :invoices_url => URL_GEN.invoices(service_object, service_account_object),
82
+ :pushed_service_account => {
83
+ :provisioned_services_url => service_account_object.provisioned_services_url,
84
+ :configuration_url => service_account_object.configuration_url,
85
+ :url => service_account_object.url,
86
+ :configuration_required => service_account_object.configuration_required,
87
+ }
88
+ }
89
+ end
90
+
91
+ def find_provisioned_service(service_account_id, app_deployment_id)
92
+ service_account = ServiceAccount.get(service_account_id)
93
+ provisioned_service = service_account.provisioned_services.first(:app_deployment_id => app_deployment_id)
94
+ provisioned_service && {
95
+ :id => provisioned_service.id,
96
+ :url => URL_GEN.partner_provisioned_service(service_account, provisioned_service),
97
+ :messages_url => URL_GEN.messages(service_account.service, service_account, provisioned_service),
98
+ :pushed_provisioned_service => {
99
+ :vars => provisioned_service.vars,
100
+ :configuration_url => provisioned_service.configuration_url,
101
+ :configuration_required => provisioned_service.configuration_required,
102
+ :url => provisioned_service.url
103
+ }
104
+ }
105
+ end
106
+
107
+ def latest_invoice
108
+ invoice = Invoice.last
109
+ {
110
+ :total_amount_cents => invoice.total_amount_cents,
111
+ :line_item_description => invoice.line_item_description,
112
+ :service_account_id => invoice.service_account_id,
113
+ }
114
+ end
115
+
116
+ def latest_status_message
117
+ if message = Message.last(:message_type => "status")
118
+ to_return = {
119
+ :id => message.id,
120
+ :subject => message.subject,
121
+ :body => message.body
122
+ }
123
+ if message.respond_to?(:service_account) && message.service_account
124
+ to_return[:service_account_id] = message.service_account.id
125
+ end
126
+ if message.respond_to?(:provisioned_service) && message.provisioned_service
127
+ to_return[:provisioned_service_id] = message.provisioned_service.id
128
+ end
129
+ to_return
130
+ end
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,156 @@
1
+ require 'sinatra/base'
2
+
3
+ module EyServicesFake
4
+ class TresfiestasFakeRackApp < Sinatra::Base
5
+ enable :raise_errors
6
+ disable :dump_errors
7
+ disable :show_exceptions
8
+
9
+ class << self
10
+ attr_accessor :partner_connection
11
+ attr_accessor :awsm_connection
12
+ end
13
+
14
+ ################
15
+ # External API #
16
+ ################
17
+
18
+ get '/api/1/partners/:partner_id/services' do |partner_id|
19
+ partner = Partner.get!(partner_id)
20
+ to_return = []
21
+ partner.services.each do |service|
22
+ to_return << {"service" => service.attributes.merge('url' => URL_GEN.service(service)) }
23
+ end
24
+ to_return.to_json
25
+ end
26
+
27
+ #TODO: auth!
28
+ post '/api/1/partners/:partner_id/services' do |partner_id|
29
+ partner = Partner.get!(partner_id)
30
+ service_json = JSON.parse(request.body.read)["service"]
31
+ if service_json["name"].to_s.empty?
32
+ status 400
33
+ {:error_messages => ["Name can't be blank"]}.to_json
34
+ else
35
+ service = Service.create(service_json.merge(:partner_id => partner.id))
36
+ status 201
37
+ headers 'Location' => URL_GEN.service(service)
38
+ {}.to_json
39
+ end
40
+ end
41
+
42
+ get '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
43
+ partner = Partner.get!(partner_id)
44
+ if service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
45
+ {"service" => service.attributes}.to_json
46
+ else
47
+ status 404
48
+ {}.to_json
49
+ end
50
+ end
51
+
52
+ put '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
53
+ partner = Partner.get!(partner_id)
54
+ service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
55
+ update_params = JSON.parse(request.body.read)["service"]
56
+ if update_params.key?("name") && update_params["name"].to_s.empty?
57
+ status 400
58
+ {:error_messages => ["Name can't be blank"]}.to_json
59
+ else
60
+ service.update_attributes(update_params)
61
+ {}.to_json
62
+ end
63
+ end
64
+
65
+ delete '/api/1/partners/:partner_id/services/:service_id' do |partner_id, service_id|
66
+ partner = Partner.get!(partner_id)
67
+ service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
68
+ service.destroy
69
+ {}.to_json
70
+ end
71
+
72
+ put '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id' do |partner_id, service_id, service_account_id|
73
+ partner = Partner.get!(partner_id)
74
+ service = partner.services.detect{ |s| s.id.to_s == service_id.to_s }
75
+ service_account = service.service_accounts.detect{ |sa| sa.id.to_s == service_account_id.to_s }
76
+ service_account_atts = JSON.parse(request.body.read)["service_account"]
77
+ service_account.update_attributes(service_account_atts)
78
+ {}.to_json
79
+ end
80
+
81
+ post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/invoices' do |partner_id, service_id, service_account_id|
82
+ invoice_params = JSON.parse(request.body.read)["invoice"]
83
+ unless invoice_params['total_amount_cents'].is_a?(Fixnum)
84
+ status 400
85
+ return {:error_messages => ["Total Amount Cents must be an integer"]}.to_json
86
+ end
87
+ if invoice_params["line_item_description"].to_s.empty?
88
+ status 400
89
+ return {:error_messages => ["Line item description can't be blank"]}.to_json
90
+ end
91
+ if invoice_params['total_amount_cents'] < 0
92
+ status 400
93
+ return {:error_messages => ["Total amount cents must be greater than or equal to 0"]}.to_json
94
+ end
95
+ Invoice.create(invoice_params.merge(:service_account_id => service_account_id.to_i))
96
+ {}.to_json
97
+ end
98
+
99
+ post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/messages' do |partner_id, service_id, service_account_id|
100
+ message_params = JSON.parse(request.body.read)["message"]
101
+ message_type = message_params['message_type']
102
+ subject = message_params['subject']
103
+ body = message_params['body']
104
+
105
+ if subject.to_s.empty?
106
+ status 400
107
+ return {:error_messages => ["Subject can't be blank."]}.to_json
108
+ end
109
+
110
+ unless ['status', 'notification', 'alert'].include? message_type
111
+ status 400
112
+ return {:error_messages => ['Message type must be one of: status, notification or alert']}.to_json
113
+ end
114
+
115
+ service_account = ServiceAccount.get(service_account_id)
116
+ message = Message.create(message_params.merge(:service_account_id => service_account.id))
117
+ self.class.awsm_connection.post(service_account.dashboard_notifications_url, {
118
+ :notification => {:subject => subject, :body => body},
119
+ :message_type => message_type,
120
+ :configuration_possible => !!service_account.configuration_url,
121
+ :service_name => service_account.service.name,
122
+ :service_id => service_account.service_id})
123
+ {}.to_json
124
+ end
125
+
126
+ post '/api/1/partners/:partner_id/services/:service_id/service_accounts/:service_account_id/provisioned_service/:provisioned_service_id/messages' do |partner_id, service_id, service_account_id, provisioned_service_id|
127
+ message_params = JSON.parse(request.body.read)["message"]
128
+ subject = message_params['subject']
129
+ message_type = message_params['message_type']
130
+ body = message_params['body']
131
+
132
+ if subject.to_s.empty?
133
+ status 400
134
+ return {:error_messages => ["Subject can't be blank."]}.to_json
135
+ end
136
+
137
+ unless ['status', 'notification', 'alert'].include? message_type
138
+ status 400
139
+ return {:error_messages => ['Message type must be one of: status, notification or alert']}.to_json
140
+ end
141
+
142
+ message = Message.create(message_params.merge(:provisioned_service_id => provisioned_service_id.to_i))
143
+ provisioned_service = ProvisionedService.get(provisioned_service_id)
144
+ service_account = provisioned_service.service_account
145
+ message = Message.create(message_params.merge(:provisioned_service_id => provisioned_service.id))
146
+ self.class.awsm_connection.post(provisioned_service.dashboard_notifications_url, {
147
+ :notification => {:subject => subject, :body => body},
148
+ :message_type => message_type,
149
+ :configuration_possible => !!provisioned_service.configuration_url,
150
+ :service_name => service_account.service.name,
151
+ :provisionable_service_id => provisioned_service.id})
152
+ {}.to_json
153
+ end
154
+
155
+ end
156
+ end
@@ -0,0 +1,37 @@
1
+ module EyServicesFake
2
+ class UrlGenerator
3
+
4
+ def initialize(base_url)
5
+ @base_url = base_url
6
+ end
7
+
8
+ def service_registration(partner)
9
+ "#{@base_url}/api/1/partners/#{partner.id}/services"
10
+ end
11
+
12
+ def service(service)
13
+ "#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}"
14
+ end
15
+
16
+ def partner_service_account(service, service_account)
17
+ "#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}"
18
+ end
19
+
20
+ def messages(service, service_account, provisioned_service = nil)
21
+ if provisioned_service
22
+ "#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/provisioned_service/#{provisioned_service.id}/messages"
23
+ else
24
+ "#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/messages"
25
+ end
26
+ end
27
+
28
+ def invoices(service, service_account)
29
+ "#{@base_url}/api/1/partners/#{service.partner_id}/services/#{service.id}/service_accounts/#{service_account.id}/invoices"
30
+ end
31
+
32
+ def partner_provisioned_service(service_account, provisioned_service)
33
+ "#{@base_url}/api/1/service_accounts/#{service_account.id}/provisioned_service/#{provisioned_service.id}"
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module EyServicesFake
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ey_services_fake
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jacob Burkhart & Josh Lane
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-10-06 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: cubbyhole
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 23
43
+ segments:
44
+ - 0
45
+ - 2
46
+ - 0
47
+ version: 0.2.0
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: A fake for use when writting tests against the ey_services_api
51
+ email:
52
+ - jacob@engineyard.com
53
+ executables: []
54
+
55
+ extensions: []
56
+
57
+ extra_rdoc_files: []
58
+
59
+ files:
60
+ - .gitignore
61
+ - ey_services_fake.gemspec
62
+ - lib/ey_services_fake/mock_backend.rb
63
+ - lib/ey_services_fake/mocking_bird_service.rb
64
+ - lib/ey_services_fake/models.rb
65
+ - lib/ey_services_fake/reacharound_awsm.rb
66
+ - lib/ey_services_fake/tresfiestas_fake.rb
67
+ - lib/ey_services_fake/tresfiestas_fake_rack_app.rb
68
+ - lib/ey_services_fake/url_generator.rb
69
+ - lib/ey_services_fake/version.rb
70
+ homepage: ""
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ requirements: []
97
+
98
+ rubyforge_project: ey_services_fake
99
+ rubygems_version: 1.8.10
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: A fake for use when writting tests against the ey_services_api
103
+ test_files: []
104
+