ey_services_fake 0.0.1

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