axel 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.
Files changed (128) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/.octopolo.yml +2 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +23 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +271 -0
  11. data/Rakefile +13 -0
  12. data/app/models/axel/api_proxy.rb +86 -0
  13. data/app/models/axel/associations/base.rb +64 -0
  14. data/app/models/axel/associations/belongs_to.rb +43 -0
  15. data/app/models/axel/associations/has_many.rb +29 -0
  16. data/app/models/axel/associations/has_one.rb +30 -0
  17. data/app/models/axel/payload.rb +4 -0
  18. data/app/models/axel/payload/base.rb +107 -0
  19. data/app/models/axel/payload/errors.rb +62 -0
  20. data/app/models/axel/payload/metadata.rb +57 -0
  21. data/app/models/axel/querier.rb +166 -0
  22. data/app/models/axel/router.rb +119 -0
  23. data/app/models/axel/service_resource.rb +4 -0
  24. data/app/models/axel/service_resource/associations.rb +80 -0
  25. data/app/models/axel/service_resource/attributes.rb +23 -0
  26. data/app/models/axel/service_resource/automatic_resource.rb +23 -0
  27. data/app/models/axel/service_resource/base.rb +47 -0
  28. data/app/models/axel/service_resource/builder.rb +40 -0
  29. data/app/models/axel/service_resource/inspects.rb +17 -0
  30. data/app/models/axel/service_resource/payload_parser.rb +46 -0
  31. data/app/models/axel/service_resource/queries.rb +25 -0
  32. data/app/models/axel/service_resource/requesters.rb +49 -0
  33. data/app/models/axel/service_resource/routes.rb +19 -0
  34. data/app/models/axel/service_resource/typhoid_extensions.rb +134 -0
  35. data/app/views/axel/base/empty.json.erb +0 -0
  36. data/app/views/axel/base/empty.xml.builder +0 -0
  37. data/app/views/layouts/axel.json.jbuilder +7 -0
  38. data/app/views/layouts/axel.xml.builder +12 -0
  39. data/axel.gemspec +42 -0
  40. data/lib/axel.rb +56 -0
  41. data/lib/axel/application_extensions.rb +13 -0
  42. data/lib/axel/application_helper.rb +27 -0
  43. data/lib/axel/base_controller.rb +6 -0
  44. data/lib/axel/cascadable_attribute.rb +33 -0
  45. data/lib/axel/configurations/resource.rb +29 -0
  46. data/lib/axel/configurations/service.rb +28 -0
  47. data/lib/axel/configurator.rb +54 -0
  48. data/lib/axel/configurators/services.rb +29 -0
  49. data/lib/axel/controller_base.rb +27 -0
  50. data/lib/axel/controller_helpers.rb +209 -0
  51. data/lib/axel/controller_parameters.rb +32 -0
  52. data/lib/axel/engine.rb +14 -0
  53. data/lib/axel/inspector.rb +91 -0
  54. data/lib/axel/payload/remote_error.rb +14 -0
  55. data/lib/axel/request_options.rb +26 -0
  56. data/lib/axel/uri.rb +47 -0
  57. data/lib/axel/version.rb +3 -0
  58. data/lib/generators/axel/install_generator.rb +16 -0
  59. data/lib/generators/templates/README.md +22 -0
  60. data/lib/generators/templates/axel.rb +81 -0
  61. data/script/rails +5 -0
  62. data/spec/controllers/pages_controller_spec.rb +217 -0
  63. data/spec/dummy/README.rdoc +261 -0
  64. data/spec/dummy/Rakefile +7 -0
  65. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  66. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  67. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  68. data/spec/dummy/app/controllers/pages_controller.rb +6 -0
  69. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  70. data/spec/dummy/app/mailers/.gitkeep +0 -0
  71. data/spec/dummy/app/models/.gitkeep +0 -0
  72. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/config/application.rb +62 -0
  75. data/spec/dummy/config/boot.rb +10 -0
  76. data/spec/dummy/config/database.yml +25 -0
  77. data/spec/dummy/config/environment.rb +5 -0
  78. data/spec/dummy/config/environments/development.rb +37 -0
  79. data/spec/dummy/config/environments/production.rb +67 -0
  80. data/spec/dummy/config/environments/test.rb +37 -0
  81. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  82. data/spec/dummy/config/initializers/inflections.rb +15 -0
  83. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  84. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  85. data/spec/dummy/config/initializers/session_store.rb +8 -0
  86. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  87. data/spec/dummy/config/locales/en.yml +5 -0
  88. data/spec/dummy/config/routes.rb +3 -0
  89. data/spec/dummy/db/development.sqlite3 +0 -0
  90. data/spec/dummy/db/test.sqlite3 +0 -0
  91. data/spec/dummy/lib/assets/.gitkeep +0 -0
  92. data/spec/dummy/log/.gitignore +1 -0
  93. data/spec/dummy/log/.gitkeep +0 -0
  94. data/spec/dummy/public/404.html +26 -0
  95. data/spec/dummy/public/422.html +26 -0
  96. data/spec/dummy/public/500.html +25 -0
  97. data/spec/dummy/public/favicon.ico +0 -0
  98. data/spec/dummy/script/rails +6 -0
  99. data/spec/envelope_integration_check.rb +96 -0
  100. data/spec/helpers/axel/application_helper_spec.rb +31 -0
  101. data/spec/lib/axel/associations/base_spec.rb +28 -0
  102. data/spec/lib/axel/associations/belongs_to_spec.rb +62 -0
  103. data/spec/lib/axel/associations/has_many_spec.rb +23 -0
  104. data/spec/lib/axel/associations/has_one_spec.rb +23 -0
  105. data/spec/lib/axel/configurations/resource_spec.rb +15 -0
  106. data/spec/lib/axel/configurations/service_spec.rb +31 -0
  107. data/spec/lib/axel/configurator_spec.rb +26 -0
  108. data/spec/lib/axel/configurators/services_spec.rb +37 -0
  109. data/spec/lib/axel/controller_base_spec.rb +16 -0
  110. data/spec/lib/axel/controller_parameters_spec.rb +31 -0
  111. data/spec/lib/axel/inspector_spec.rb +45 -0
  112. data/spec/lib/axel/request_options_spec.rb +50 -0
  113. data/spec/lib/axel/uri_spec.rb +42 -0
  114. data/spec/lib/axel_spec.rb +64 -0
  115. data/spec/models/axel/api_proxy_spec.rb +66 -0
  116. data/spec/models/axel/payload/errors_spec.rb +165 -0
  117. data/spec/models/axel/payload/metadata_spec.rb +141 -0
  118. data/spec/models/axel/querier_spec.rb +158 -0
  119. data/spec/models/axel/router_spec.rb +115 -0
  120. data/spec/models/axel/service_resource/base_spec.rb +244 -0
  121. data/spec/models/axel/service_resource/builder_spec.rb +64 -0
  122. data/spec/models/axel/service_resource/payload_parser_spec.rb +60 -0
  123. data/spec/spec_helper.rb +39 -0
  124. data/spec/support/address.rb +5 -0
  125. data/spec/support/persona.rb +15 -0
  126. data/spec/support/user.rb +6 -0
  127. data/spec/views/axel/base/empty_spec.rb +34 -0
  128. metadata +508 -0
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/422.html -->
21
+ <div class="dialog">
22
+ <h1>The change you wanted was rejected.</h1>
23
+ <p>Maybe you tried to change something you didn't have access to.</p>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <style type="text/css">
6
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
7
+ div.dialog {
8
+ width: 25em;
9
+ padding: 0 4em;
10
+ margin: 4em auto 0 auto;
11
+ border: 1px solid #ccc;
12
+ border-right-color: #999;
13
+ border-bottom-color: #999;
14
+ }
15
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <!-- This file lives in public/500.html -->
21
+ <div class="dialog">
22
+ <h1>We're sorry, but something went wrong.</h1>
23
+ </div>
24
+ </body>
25
+ </html>
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+ class Sport < Axel::ServiceResource::Base
3
+ field :friendly_name
4
+ field :status
5
+ end
6
+ module Axel
7
+ module ServiceResource
8
+ describe Sport do
9
+ subject { Sport.new payload }
10
+
11
+ let(:payload) { {} }
12
+
13
+ its(:metadata) { should be_a Payload::Metadata }
14
+ its(:remote_errors) { should be_a Payload::Errors }
15
+ its(:result) { should == {} }
16
+
17
+ describe "with some nested" do
18
+ let(:payload) { { metadata: meta, errors: errors, result: result } }
19
+ let(:meta) { nil }
20
+ let(:errors) { nil }
21
+ let(:result) { nil }
22
+
23
+ its(:metadata) { should be_a Payload::Metadata }
24
+ its(:remote_errors) { should be_a Payload::Errors }
25
+ its(:result) { should == {} }
26
+
27
+ describe "errorless" do
28
+ let(:meta) { { current_user: { user_name: "jon" } } }
29
+ let(:result) { { friendly_name: "Jon" } }
30
+
31
+ its(:metadata) { should be_a Payload::Metadata }
32
+ its(:remote_errors) { should be_a Payload::Errors }
33
+ its(:result) { should == { "friendly_name" => "Jon" } }
34
+
35
+ it "has data from meta" do
36
+ subject.metadata[:current_user].should == { "user_name" => "jon" }
37
+ end
38
+ end
39
+
40
+ describe "with errors" do
41
+ let(:meta) { { current_user: { user_name: "jon" } } }
42
+ let(:result) { { friendly_name: "Jon" } }
43
+ let(:errors) { { status: 401 } }
44
+
45
+ its(:metadata) { should be_a Payload::Metadata }
46
+ its(:remote_errors) { should be_a Payload::Errors }
47
+ its(:result) { should == { "friendly_name" => "Jon" } }
48
+
49
+ it "has data from meta" do
50
+ subject.metadata[:current_user].should == { "user_name" => "jon" }
51
+ end
52
+
53
+ it "has data from errors" do
54
+ subject.remote_errors.status_code.should == 401
55
+ end
56
+
57
+ it "has attributes" do
58
+ subject.friendly_name.should == "Jon"
59
+ end
60
+ end
61
+
62
+ describe "with save" do
63
+ let(:result) { { friendly_name: "Jon" } }
64
+ before do
65
+ Typhoeus::Request.stub post: double(body: { status: "Active" }.to_json, success?: true, code: 200)
66
+ subject.stub save_request: double(request_uri: "", options: {})
67
+ end
68
+
69
+ it "doesn't lose its friendly name" do
70
+ subject.friendly_name.should == "Jon"
71
+ subject.save
72
+ subject.remote_errors.status_code.should == 200
73
+ subject.friendly_name.should == "Jon"
74
+ subject.status.should == "Active"
75
+ end
76
+ end
77
+
78
+ describe "with envelope save" do
79
+ let(:result) { { friendly_name: "Jon" } }
80
+ before do
81
+ Typhoeus::Request.stub post: double(body: { metadata: {}, result: { status: "Active" } }.to_json, success?: true, code: 200)
82
+ subject.stub save_request: double(request_uri: "", options: {})
83
+ end
84
+
85
+ it "doesn't lose its friendly name" do
86
+ subject.friendly_name.should == "Jon"
87
+ subject.save
88
+ subject.remote_errors.status_code.should == 200
89
+ subject.friendly_name.should == "Jon"
90
+ subject.status.should == "Active"
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ describe ApplicationHelper do
4
+ before do
5
+ helper.stub drop_meta?: false
6
+ end
7
+ describe "page title" do
8
+ it "is empty with no title locales implemented" do
9
+ helper.page_title.should == ""
10
+ end
11
+
12
+ context "with locale hash" do
13
+ let(:action_param) { "show" }
14
+ let(:controller_param) { "pages" }
15
+ let(:params) { { action: action_param, controller: controller_param } }
16
+ let(:t) { { user: { pages: { show: "User Page Show" } }, pages: { show: "Page Show" } } }
17
+
18
+ before do
19
+ helper.stub t: t, params: params
20
+ end
21
+
22
+ it { helper.page_title.should == " - Page Show" }
23
+
24
+ context "nested controller name" do
25
+ let(:controller_param) { "user/pages" }
26
+ it { helper.page_title.should == " - User Page Show" }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+ module Axel::Associations
3
+ describe Base do
4
+ let(:model) { User }
5
+ let(:relation_name) { "personas" }
6
+ let(:options) { {} }
7
+ let(:instance) { User.new }
8
+ subject { described_class.new model, relation_name, options }
9
+
10
+ it "handles a read" do
11
+ subject.handles_method?(:personas).should be_truthy
12
+ end
13
+
14
+ it "doesn't handle a write" do
15
+ subject.handles_method?(:personas=).should be_falsey
16
+ end
17
+
18
+ it "runs a getter" do
19
+ subject.should_receive(:getter).and_return nil
20
+ subject.run_method(instance, :personas)
21
+ end
22
+
23
+ it "runs a getter" do
24
+ expect { subject.run_method(instance, :personas=) }.to raise_error NoMethodError,
25
+ "Could not find an association method for `personas='"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ module Axel::Associations
3
+ describe BelongsTo do
4
+ let(:instance) { Persona.new id: 1, user_id: 2 }
5
+ let(:options) { {} }
6
+ let(:association_object) { Persona.send(:belongs_to_associations)[:user] }
7
+ before do
8
+ association_object.send :options=, options
9
+ end
10
+
11
+ describe "included in result" do
12
+ let(:options) { { included: true } }
13
+ subject { instance }
14
+
15
+ it "does not get a user" do
16
+ expect(subject.user).to be_nil
17
+ end
18
+
19
+ describe "with data present in result" do
20
+ let(:instance) { Persona.new id: 1, user: { id: 1, name: "Jon" } }
21
+
22
+ it "does not get a user" do
23
+ expect(subject.user).to be_a User
24
+ end
25
+ end
26
+ end
27
+
28
+ describe "via API" do
29
+ subject { association_object }
30
+ its(:build_klass) { should be User }
31
+ it "tries to get user" do
32
+ User.should_receive(:find).with(2, {})
33
+ instance.user
34
+ end
35
+
36
+ describe "use another ID method" do
37
+ let(:options) { { id_attribute: :id } }
38
+
39
+ it "tries to get a user with options" do
40
+ User.should_receive(:find).with(1, {})
41
+
42
+ instance.user
43
+ end
44
+ end
45
+
46
+ describe "nested find" do
47
+ let(:options) { { find_nested: true } }
48
+
49
+ its(:find_nested?) { should be_truthy }
50
+
51
+ it "tries to get a user with options" do
52
+ User.should_receive(:querier).and_return(User)
53
+ User.should_receive(:without_default_path).and_return(User)
54
+ User.should_receive(:at_path).with("/personas/1/users/2").and_return(User)
55
+ User.should_receive(:request_options).with({}).and_return([])
56
+
57
+ instance.user
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ module Axel::Associations
3
+ describe HasMany do
4
+ let(:instance) { User.new id: 1 }
5
+ let(:options) { {} }
6
+ subject { User.send(:has_many_associations)[:personas] }
7
+
8
+ before do
9
+ subject.send :options=, options
10
+ end
11
+
12
+ its(:build_klass) { should be Persona }
13
+
14
+ it "tries to get a user with options" do
15
+ Persona.should_receive(:querier).and_return(Persona)
16
+ Persona.should_receive(:without_default_path).and_return(Persona)
17
+ Persona.should_receive(:at_path).with("/users/1/personas").and_return(Persona)
18
+ Persona.should_receive(:request_options).with({}).and_return([])
19
+
20
+ instance.personas
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ module Axel::Associations
3
+ describe HasOne do
4
+ let(:instance) { User.new id: 1 }
5
+ let(:options) { {} }
6
+ subject { instance.class.send(:has_one_associations)[:address] }
7
+
8
+ before do
9
+ subject.send :options=, options
10
+ end
11
+
12
+ its(:build_klass) { should be Address }
13
+
14
+ it "tries to get a user with options" do
15
+ Address.should_receive(:querier).and_return(Address)
16
+ Address.should_receive(:without_default_path).and_return(Address)
17
+ Address.should_receive(:at_path).with("/users/1/address").and_return(Address)
18
+ Address.should_receive(:request_options).with({}).and_return([])
19
+
20
+ instance.address
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ module Configurations
4
+ describe Resource do
5
+ subject { Resource.new name, service }
6
+ let(:service) { Service.new(:user_service, "http://localhost") }
7
+ let(:name) { :users }
8
+
9
+ its(:name) { should == "user" }
10
+ its(:base_url) { should == "http://localhost" }
11
+ its(:path) { should == "users" }
12
+ its(:full_url) { should == "http://localhost/users" }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ module Configurations
4
+ describe Service do
5
+ subject { Service.new name, url }
6
+ let(:name) { :user_service }
7
+ let(:url) { "http://user-service.dev" }
8
+
9
+ describe "without resource" do
10
+ its(:resources) { should == {} }
11
+ end
12
+
13
+ describe "with resources set" do
14
+ before do
15
+ subject.add_resource :user
16
+ subject.add_resource :persona
17
+ end
18
+
19
+ its(:resources) { should have_key :user }
20
+ it "user is a resource" do
21
+ subject.resources[:user].should be_a Resource
22
+ end
23
+
24
+ its(:resources) { should have_key :persona }
25
+ it "persona is a resource" do
26
+ subject.resources[:persona].should be_a Resource
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ describe Configurator do
4
+ its(:services) { should be_a Configurators::Services }
5
+
6
+ it "adds a proxy url" do
7
+ subject.set_proxy_url "http://some-proxy-url"
8
+ subject.proxy.should be_an ApiProxy
9
+ end
10
+
11
+ it "adds a new service" do
12
+ subject.add_service "new_service", "http://new-service"
13
+ subject.service_configs[:new_service].url.should == "http://new-service"
14
+ end
15
+
16
+ its(:uses_rails_api?) { should be_falsey }
17
+
18
+ context "rails api set" do
19
+ it "uses_rails_api?" do
20
+ subject.uses_rails_api = true
21
+ subject.uses_rails_api?.should be_truthy
22
+ subject.uses_rails_api = false
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ module Axel
3
+ module Configurators
4
+ describe Services do
5
+ context "service adding" do
6
+ before { subject.add_service :user_service, "http://user-service.dev" }
7
+
8
+ it "sets up a service object" do
9
+ subject.services[:user_service].should be_a Configurations::Service
10
+ end
11
+ end
12
+
13
+ context "resource adding" do
14
+ context "without service pre-created" do
15
+ before { subject.add_resource :boss_service, :boss, service: { url: "http://boss-service.dev" } }
16
+
17
+ it "sets up a resource" do
18
+ subject.services[:boss_service].should be_a Configurations::Service
19
+ subject.resources[:boss].should be_a Configurations::Resource
20
+ end
21
+ end
22
+
23
+ context "with service pre-created" do
24
+ before do
25
+ subject.add_service :user_service, "http://user-service.dev"
26
+ subject.add_resource :user_service, :user
27
+ end
28
+
29
+ it "sets up a resource" do
30
+ subject.services[:user_service].should be_a Configurations::Service
31
+ subject.resources[:user].should be_a Configurations::Resource
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end