nucleus 0.1.0

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 (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +19 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +44 -0
  6. data/.travis.yml +21 -0
  7. data/CHANGELOG.md +19 -0
  8. data/CONTRIBUTING.md +13 -0
  9. data/Gemfile +16 -0
  10. data/Guardfile +22 -0
  11. data/LICENSE +21 -0
  12. data/README.md +675 -0
  13. data/Rakefile +137 -0
  14. data/bin/nucleus +91 -0
  15. data/bin/nucleus.bat +1 -0
  16. data/config.ru +18 -0
  17. data/config/adapters/cloud_control.yml +32 -0
  18. data/config/adapters/cloud_foundry_v2.yml +61 -0
  19. data/config/adapters/heroku.yml +13 -0
  20. data/config/adapters/openshift_v2.yml +20 -0
  21. data/config/nucleus_config.rb +47 -0
  22. data/lib/nucleus.rb +13 -0
  23. data/lib/nucleus/adapter_resolver.rb +115 -0
  24. data/lib/nucleus/adapters/base_adapter.rb +109 -0
  25. data/lib/nucleus/adapters/buildpack_translator.rb +79 -0
  26. data/lib/nucleus/adapters/v1/cloud_control/application.rb +108 -0
  27. data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +27 -0
  28. data/lib/nucleus/adapters/v1/cloud_control/buildpacks.rb +23 -0
  29. data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +153 -0
  30. data/lib/nucleus/adapters/v1/cloud_control/data.rb +76 -0
  31. data/lib/nucleus/adapters/v1/cloud_control/domains.rb +68 -0
  32. data/lib/nucleus/adapters/v1/cloud_control/lifecycle.rb +27 -0
  33. data/lib/nucleus/adapters/v1/cloud_control/log_poller.rb +71 -0
  34. data/lib/nucleus/adapters/v1/cloud_control/logs.rb +103 -0
  35. data/lib/nucleus/adapters/v1/cloud_control/regions.rb +32 -0
  36. data/lib/nucleus/adapters/v1/cloud_control/scaling.rb +17 -0
  37. data/lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb +31 -0
  38. data/lib/nucleus/adapters/v1/cloud_control/services.rb +162 -0
  39. data/lib/nucleus/adapters/v1/cloud_control/token.rb +17 -0
  40. data/lib/nucleus/adapters/v1/cloud_control/vars.rb +88 -0
  41. data/lib/nucleus/adapters/v1/cloud_foundry_v2/app_states.rb +28 -0
  42. data/lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb +111 -0
  43. data/lib/nucleus/adapters/v1/cloud_foundry_v2/authentication.rb +17 -0
  44. data/lib/nucleus/adapters/v1/cloud_foundry_v2/buildpacks.rb +23 -0
  45. data/lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb +141 -0
  46. data/lib/nucleus/adapters/v1/cloud_foundry_v2/data.rb +97 -0
  47. data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +149 -0
  48. data/lib/nucleus/adapters/v1/cloud_foundry_v2/lifecycle.rb +41 -0
  49. data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +303 -0
  50. data/lib/nucleus/adapters/v1/cloud_foundry_v2/regions.rb +33 -0
  51. data/lib/nucleus/adapters/v1/cloud_foundry_v2/scaling.rb +15 -0
  52. data/lib/nucleus/adapters/v1/cloud_foundry_v2/semantic_errors.rb +27 -0
  53. data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +286 -0
  54. data/lib/nucleus/adapters/v1/cloud_foundry_v2/vars.rb +80 -0
  55. data/lib/nucleus/adapters/v1/heroku/app_states.rb +57 -0
  56. data/lib/nucleus/adapters/v1/heroku/application.rb +93 -0
  57. data/lib/nucleus/adapters/v1/heroku/authentication.rb +27 -0
  58. data/lib/nucleus/adapters/v1/heroku/buildpacks.rb +27 -0
  59. data/lib/nucleus/adapters/v1/heroku/data.rb +78 -0
  60. data/lib/nucleus/adapters/v1/heroku/domains.rb +43 -0
  61. data/lib/nucleus/adapters/v1/heroku/heroku.rb +146 -0
  62. data/lib/nucleus/adapters/v1/heroku/lifecycle.rb +51 -0
  63. data/lib/nucleus/adapters/v1/heroku/logs.rb +108 -0
  64. data/lib/nucleus/adapters/v1/heroku/regions.rb +42 -0
  65. data/lib/nucleus/adapters/v1/heroku/scaling.rb +28 -0
  66. data/lib/nucleus/adapters/v1/heroku/semantic_errors.rb +23 -0
  67. data/lib/nucleus/adapters/v1/heroku/services.rb +168 -0
  68. data/lib/nucleus/adapters/v1/heroku/vars.rb +65 -0
  69. data/lib/nucleus/adapters/v1/openshift_v2/app_states.rb +68 -0
  70. data/lib/nucleus/adapters/v1/openshift_v2/application.rb +108 -0
  71. data/lib/nucleus/adapters/v1/openshift_v2/authentication.rb +21 -0
  72. data/lib/nucleus/adapters/v1/openshift_v2/data.rb +96 -0
  73. data/lib/nucleus/adapters/v1/openshift_v2/domains.rb +37 -0
  74. data/lib/nucleus/adapters/v1/openshift_v2/lifecycle.rb +60 -0
  75. data/lib/nucleus/adapters/v1/openshift_v2/logs.rb +106 -0
  76. data/lib/nucleus/adapters/v1/openshift_v2/openshift_v2.rb +125 -0
  77. data/lib/nucleus/adapters/v1/openshift_v2/regions.rb +58 -0
  78. data/lib/nucleus/adapters/v1/openshift_v2/scaling.rb +39 -0
  79. data/lib/nucleus/adapters/v1/openshift_v2/semantic_errors.rb +40 -0
  80. data/lib/nucleus/adapters/v1/openshift_v2/services.rb +173 -0
  81. data/lib/nucleus/adapters/v1/openshift_v2/vars.rb +49 -0
  82. data/lib/nucleus/adapters/v1/stub_adapter.rb +464 -0
  83. data/lib/nucleus/core/adapter_authentication_inductor.rb +62 -0
  84. data/lib/nucleus/core/adapter_extensions/auth/auth_client.rb +44 -0
  85. data/lib/nucleus/core/adapter_extensions/auth/authentication_retry_wrapper.rb +79 -0
  86. data/lib/nucleus/core/adapter_extensions/auth/expiring_token_auth_client.rb +53 -0
  87. data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +37 -0
  88. data/lib/nucleus/core/adapter_extensions/auth/o_auth2_auth_client.rb +95 -0
  89. data/lib/nucleus/core/adapter_extensions/auth/token_auth_client.rb +36 -0
  90. data/lib/nucleus/core/adapter_extensions/http_client.rb +177 -0
  91. data/lib/nucleus/core/adapter_extensions/http_tail_client.rb +26 -0
  92. data/lib/nucleus/core/adapter_extensions/tail_stopper.rb +25 -0
  93. data/lib/nucleus/core/common/errors/ambiguous_adapter_error.rb +7 -0
  94. data/lib/nucleus/core/common/errors/file_existence_error.rb +7 -0
  95. data/lib/nucleus/core/common/errors/startup_error.rb +12 -0
  96. data/lib/nucleus/core/common/exit_codes.rb +25 -0
  97. data/lib/nucleus/core/common/files/application_repo_sanitizer.rb +52 -0
  98. data/lib/nucleus/core/common/files/archive_extractor.rb +112 -0
  99. data/lib/nucleus/core/common/files/archiver.rb +91 -0
  100. data/lib/nucleus/core/common/link_generator.rb +46 -0
  101. data/lib/nucleus/core/common/logging/logging.rb +52 -0
  102. data/lib/nucleus/core/common/logging/multi_logger.rb +59 -0
  103. data/lib/nucleus/core/common/logging/request_log_formatter.rb +48 -0
  104. data/lib/nucleus/core/common/ssh_handler.rb +108 -0
  105. data/lib/nucleus/core/common/stream_callback.rb +27 -0
  106. data/lib/nucleus/core/common/thread_config_accessor.rb +85 -0
  107. data/lib/nucleus/core/common/url_converter.rb +28 -0
  108. data/lib/nucleus/core/enums/application_states.rb +26 -0
  109. data/lib/nucleus/core/enums/logfile_types.rb +28 -0
  110. data/lib/nucleus/core/error_messages.rb +127 -0
  111. data/lib/nucleus/core/errors/adapter_error.rb +13 -0
  112. data/lib/nucleus/core/errors/adapter_missing_implementation_error.rb +12 -0
  113. data/lib/nucleus/core/errors/adapter_request_error.rb +10 -0
  114. data/lib/nucleus/core/errors/adapter_resource_not_found_error.rb +10 -0
  115. data/lib/nucleus/core/errors/endpoint_authentication_error.rb +10 -0
  116. data/lib/nucleus/core/errors/platform_specific_semantic_error.rb +12 -0
  117. data/lib/nucleus/core/errors/platform_timeout_error.rb +10 -0
  118. data/lib/nucleus/core/errors/platform_unavailable_error.rb +10 -0
  119. data/lib/nucleus/core/errors/semantic_adapter_request_error.rb +19 -0
  120. data/lib/nucleus/core/errors/unknown_adapter_call_error.rb +10 -0
  121. data/lib/nucleus/core/file_handling/archive_converter.rb +29 -0
  122. data/lib/nucleus/core/file_handling/file_manager.rb +64 -0
  123. data/lib/nucleus/core/file_handling/git_deployer.rb +133 -0
  124. data/lib/nucleus/core/file_handling/git_repo_analyzer.rb +23 -0
  125. data/lib/nucleus/core/import/adapter_configuration.rb +53 -0
  126. data/lib/nucleus/core/import/vendor_parser.rb +28 -0
  127. data/lib/nucleus/core/import/version_detector.rb +18 -0
  128. data/lib/nucleus/core/models/abstract_model.rb +29 -0
  129. data/lib/nucleus/core/models/endpoint.rb +30 -0
  130. data/lib/nucleus/core/models/provider.rb +26 -0
  131. data/lib/nucleus/core/models/vendor.rb +22 -0
  132. data/lib/nucleus/ext/kernel.rb +5 -0
  133. data/lib/nucleus/ext/regexp.rb +49 -0
  134. data/lib/nucleus/os.rb +15 -0
  135. data/lib/nucleus/root_dir.rb +13 -0
  136. data/lib/nucleus/scripts/finalize.rb +8 -0
  137. data/lib/nucleus/scripts/initialize.rb +9 -0
  138. data/lib/nucleus/scripts/initialize_config_defaults.rb +26 -0
  139. data/lib/nucleus/scripts/load.rb +17 -0
  140. data/lib/nucleus/scripts/load_dependencies.rb +43 -0
  141. data/lib/nucleus/scripts/setup_config.rb +28 -0
  142. data/lib/nucleus/scripts/shutdown.rb +11 -0
  143. data/lib/nucleus/version.rb +3 -0
  144. data/nucleus.gemspec +88 -0
  145. data/public/robots.txt +2 -0
  146. data/public/swagger-ui/css/reset.css +125 -0
  147. data/public/swagger-ui/css/screen.css +1224 -0
  148. data/public/swagger-ui/images/apple-touch-icon-114x114.png +0 -0
  149. data/public/swagger-ui/images/apple-touch-icon-120x120.png +0 -0
  150. data/public/swagger-ui/images/apple-touch-icon-144x144.png +0 -0
  151. data/public/swagger-ui/images/apple-touch-icon-152x152.png +0 -0
  152. data/public/swagger-ui/images/apple-touch-icon-57x57.png +0 -0
  153. data/public/swagger-ui/images/apple-touch-icon-60x60.png +0 -0
  154. data/public/swagger-ui/images/apple-touch-icon-72x72.png +0 -0
  155. data/public/swagger-ui/images/apple-touch-icon-76x76.png +0 -0
  156. data/public/swagger-ui/images/explorer_icons.png +0 -0
  157. data/public/swagger-ui/images/favicon-128.png +0 -0
  158. data/public/swagger-ui/images/favicon-16x16.png +0 -0
  159. data/public/swagger-ui/images/favicon-196x196.png +0 -0
  160. data/public/swagger-ui/images/favicon-32x32.png +0 -0
  161. data/public/swagger-ui/images/favicon-96x96.png +0 -0
  162. data/public/swagger-ui/images/favicon.ico +0 -0
  163. data/public/swagger-ui/images/logo_small.png +0 -0
  164. data/public/swagger-ui/images/mstile-144x144.png +0 -0
  165. data/public/swagger-ui/images/mstile-150x150.png +0 -0
  166. data/public/swagger-ui/images/mstile-310x150.png +0 -0
  167. data/public/swagger-ui/images/mstile-310x310.png +0 -0
  168. data/public/swagger-ui/images/mstile-70x70.png +0 -0
  169. data/public/swagger-ui/images/pet_store_api.png +0 -0
  170. data/public/swagger-ui/images/throbber.gif +0 -0
  171. data/public/swagger-ui/images/wordnik_api.png +0 -0
  172. data/public/swagger-ui/index.html +107 -0
  173. data/public/swagger-ui/lib/backbone-min.js +38 -0
  174. data/public/swagger-ui/lib/handlebars-1.0.0.js +2278 -0
  175. data/public/swagger-ui/lib/highlight.7.3.pack.js +1 -0
  176. data/public/swagger-ui/lib/jquery-1.8.0.min.js +2 -0
  177. data/public/swagger-ui/lib/jquery.ba-bbq.min.js +18 -0
  178. data/public/swagger-ui/lib/jquery.slideto.min.js +1 -0
  179. data/public/swagger-ui/lib/jquery.wiggle.min.js +8 -0
  180. data/public/swagger-ui/lib/shred.bundle.js +2765 -0
  181. data/public/swagger-ui/lib/shred/content.js +193 -0
  182. data/public/swagger-ui/lib/swagger-oauth.js +211 -0
  183. data/public/swagger-ui/lib/swagger.js +1653 -0
  184. data/public/swagger-ui/lib/underscore-min.js +32 -0
  185. data/public/swagger-ui/o2c.html +15 -0
  186. data/public/swagger-ui/redirect.html +14 -0
  187. data/public/swagger-ui/swagger-ui.js +2324 -0
  188. data/public/swagger-ui/swagger-ui.min.js +1 -0
  189. data/schemas/api.adapter.schema.yml +31 -0
  190. data/schemas/api.requirements.schema.yml +17 -0
  191. data/spec/factories/models.rb +61 -0
  192. data/spec/integration/api/auth_spec.rb +58 -0
  193. data/spec/integration/api/endpoints_spec.rb +167 -0
  194. data/spec/integration/api/errors_spec.rb +47 -0
  195. data/spec/integration/api/providers_spec.rb +157 -0
  196. data/spec/integration/api/swagger_schema_spec.rb +64 -0
  197. data/spec/integration/api/vendors_spec.rb +45 -0
  198. data/spec/integration/integration_spec_helper.rb +27 -0
  199. data/spec/integration/test_data_generator.rb +55 -0
  200. data/spec/nucleus_git_key.pem +51 -0
  201. data/spec/spec_helper.rb +98 -0
  202. data/spec/support/shared_example_request_types.rb +99 -0
  203. data/spec/test_suites.rake +31 -0
  204. data/spec/unit/adapters/archive_converter_spec.rb +25 -0
  205. data/spec/unit/adapters/file_manager_spec.rb +93 -0
  206. data/spec/unit/adapters/git_deployer_spec.rb +262 -0
  207. data/spec/unit/adapters/v1/stub_spec.rb +14 -0
  208. data/spec/unit/common/helpers/auth_helper_spec.rb +73 -0
  209. data/spec/unit/common/oauth2_auth_client_spec.rb +108 -0
  210. data/spec/unit/common/regexp_spec.rb +33 -0
  211. data/spec/unit/common/request_log_formatter_spec.rb +108 -0
  212. data/spec/unit/common/thread_config_accessor_spec.rb +97 -0
  213. data/spec/unit/models/endpoint_spec.rb +83 -0
  214. data/spec/unit/models/provider_spec.rb +102 -0
  215. data/spec/unit/models/vendor_spec.rb +100 -0
  216. data/spec/unit/schemas/adapter_schema_spec.rb +16 -0
  217. data/spec/unit/schemas/adapter_validation_spec.rb +56 -0
  218. data/spec/unit/schemas/requirements_schema_spec.rb +16 -0
  219. data/spec/unit/unit_spec_helper.rb +11 -0
  220. data/tasks/compatibility.rake +113 -0
  221. data/tasks/evaluation.rake +162 -0
  222. data/wiki/adapter_tests.md +99 -0
  223. data/wiki/implement_new_adapter.md +155 -0
  224. metadata +836 -0
@@ -0,0 +1,64 @@
1
+ require 'spec/integration/integration_spec_helper'
2
+
3
+ describe 'Swagger schema' do
4
+ context 'with an invalid version can not access' do
5
+ let!(:header) { { 'HTTP_ACCEPT' => 'application/vnd.nucleus-invalidversion' } }
6
+
7
+ context 'GET apis' do
8
+ before { get '/schema', header }
9
+ include_examples 'a not accepted request'
10
+ end
11
+ context 'GET endpoints schema' do
12
+ before { get '/schema/endpoints', header }
13
+ include_examples 'a not accepted request'
14
+ end
15
+ context 'GET vendors schema' do
16
+ before { get '/schema/vendors', header }
17
+ include_examples 'a not accepted request'
18
+ end
19
+ context 'GET providers schema' do
20
+ before { get '/schema/providers', header }
21
+ include_examples 'a not accepted request'
22
+ end
23
+ end
24
+
25
+ describe 'with a version can access' do
26
+ let!(:header) { { 'HTTP_ACCEPT' => 'application/vnd.nucleus-v1' } }
27
+
28
+ context 'GET apis schema' do
29
+ before { get '/schema', header }
30
+ include_examples 'a valid GET request'
31
+ end
32
+ context 'GET endpoints schema' do
33
+ before { get '/schema/endpoints', header }
34
+ include_examples 'a valid GET request'
35
+ end
36
+ context 'GET vendors schema' do
37
+ before { get '/schema/vendors', header }
38
+ include_examples 'a valid GET request'
39
+ end
40
+ context 'GET providers schema' do
41
+ before { get '/schema/providers', header }
42
+ include_examples 'a valid GET request'
43
+ end
44
+ end
45
+
46
+ describe 'without a version can access' do
47
+ context 'GET apis schema' do
48
+ before { get '/schema' }
49
+ include_examples 'a valid GET request'
50
+ end
51
+ context 'GET endpoints schema' do
52
+ before { get '/schema/endpoints' }
53
+ include_examples 'a valid GET request'
54
+ end
55
+ context 'GET vendors schema' do
56
+ before { get '/schema/vendors' }
57
+ include_examples 'a valid GET request'
58
+ end
59
+ context 'GET providers schema' do
60
+ before { get '/schema/providers' }
61
+ include_examples 'a valid GET request'
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec/integration/integration_spec_helper'
2
+
3
+ describe Nucleus::API::V1::Vendors do
4
+ after { Nucleus::TestDataGenerator.clean }
5
+
6
+ let!(:vendor_a) { create(:vendor) }
7
+ let!(:vendor_b) { create(:vendor) }
8
+ let!(:provider_a) { create(:provider, vendor: vendor_a.id) }
9
+ let!(:provider_b) { create(:provider, vendor: vendor_a.id) }
10
+ let!(:provider_c) { create(:provider, vendor: vendor_b.id) }
11
+ let!(:endpoint_a) { create(:endpoint, provider: provider_a.id) }
12
+ let!(:endpoint_b) { create(:endpoint, provider: provider_b.id) }
13
+
14
+ context 'GET /vendors response' do
15
+ before { get '/vendors' }
16
+ include_examples 'a valid GET request'
17
+ it 'has vendor-list like structure' do
18
+ expect_json_types(size: :int, vendors: :array_of_objects, _links: :object)
19
+ end
20
+
21
+ # TODO: contains all required fields
22
+
23
+ it 'shows the retrieved number of vendors' do
24
+ expect(json_body[:size]).to eq 2
25
+ expect_json_sizes(vendors: 2)
26
+ end
27
+ it 'lists all vendors' do
28
+ expect(json_body[:vendors]).to_not be_nil
29
+ expect(json_body[:vendors][0][:id]).to eq vendor_a.id
30
+ expect(json_body[:vendors][1][:id]).to eq vendor_b.id
31
+ end
32
+ end
33
+
34
+ context 'GET /vendors/:id' do
35
+ before { get "/vendors/#{vendor_a.id}" }
36
+ include_examples 'a valid GET request'
37
+ it 'has the structure of an vendor object' do
38
+ expect_json_types(id: :string, name: :string, created_at: :date, updated_at: :date,
39
+ providers: :array_of_objects, _links: :object)
40
+ end
41
+ it 'contains the requested vendor' do
42
+ expect(json_body[:id]).to eq vendor_a.id
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec/spec_helper'
2
+ require 'nucleus_api/scripts/rack_application'
3
+ require 'spec/integration/test_data_generator'
4
+ require 'spec/support/shared_example_request_types'
5
+ require 'airborne'
6
+
7
+ # define test suite for coverage report
8
+ SimpleCov.command_name 'spec:suite:integration'
9
+
10
+ Airborne.configure do |config|
11
+ config.rack_app = Nucleus::API::Rack.app
12
+ config.headers = { 'HTTP_ACCEPT' => 'application/vnd.nucleus-v1' }
13
+ end
14
+
15
+ RSpec.configure do |config|
16
+ config.before(:suite) do
17
+ Nucleus::TestDataGenerator.clean
18
+ end
19
+
20
+ config.after(:suite) do
21
+ Nucleus::TestDataGenerator.clean
22
+ end
23
+
24
+ config.after(:each) do
25
+ Excon.stubs.clear
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ module Nucleus
2
+ module TestDataGenerator
3
+ def self.clean
4
+ nucleus_config.api.versions.each do |api_version|
5
+ Nucleus::API::DB::AdapterDao.instance(api_version).clear
6
+ Nucleus::API::DB::EndpointDao.instance(api_version).clear
7
+ Nucleus::API::DB::ProviderDao.instance(api_version).clear
8
+ Nucleus::API::DB::VendorDao.instance(api_version).clear
9
+ Nucleus::API::DB::CacheDao.instance(api_version).clear
10
+ end
11
+ end
12
+ end
13
+
14
+ module DaoResolver
15
+ def self.resolve(entity)
16
+ # TODO: find a solution how to test when multiple API versions are supported
17
+ version = 'v1'
18
+ case entity
19
+ when Nucleus::Endpoint
20
+ dao = Nucleus::API::DB::EndpointDao.instance(version)
21
+ when Nucleus::Provider
22
+ dao = Nucleus::API::DB::ProviderDao.instance(version)
23
+ when Nucleus::Vendor
24
+ dao = Nucleus::API::DB::VendorDao.instance(version)
25
+ when Nucleus::AdapterIndexEntry
26
+ dao = Nucleus::API::DB::AdapterDao.instance(version)
27
+ end
28
+ dao
29
+ end
30
+ end
31
+
32
+ class AbstractModel
33
+ def save!
34
+ dao = DaoResolver.resolve self
35
+ dao.set self
36
+ end
37
+
38
+ def new_record?
39
+ dao = DaoResolver.resolve self
40
+ dao.key? id
41
+ end
42
+ end
43
+
44
+ class AdapterIndexEntry
45
+ def save!
46
+ dao = DaoResolver.resolve self
47
+ dao.set self
48
+ end
49
+
50
+ def new_record?
51
+ dao = DaoResolver.resolve self
52
+ dao.key? id
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,98 @@
1
+ $LOAD_PATH << File.join(__dir__, '..')
2
+
3
+ # figure out where we are being loaded from
4
+ if $LOADED_FEATURES.grep(%r{spec\/spec_helper\.rb}).any?
5
+ begin
6
+ fail 'foo'
7
+ rescue => e
8
+ puts <<-MSG
9
+ ===================================================
10
+ It looks like spec_helper.rb has been loaded
11
+ multiple times. Normalize the require to:
12
+
13
+ require "spec/spec_helper"
14
+
15
+ Things like File.join and File.expand_path will
16
+ cause it to be loaded multiple times.
17
+
18
+ Loaded this time from:
19
+
20
+ #{e.backtrace.join("\n ")}
21
+ ===================================================
22
+ MSG
23
+ end
24
+ end
25
+
26
+ require 'vcr'
27
+ require 'factory_girl'
28
+ require 'faker'
29
+ require 'tmpdir'
30
+
31
+ # we need this to detect whether to apply test middleware (tailing hack)
32
+ ENV['RACK_ENV'] = 'test'
33
+
34
+ if ENV['CODECLIMATE_REPO_TOKEN']
35
+ require 'simplecov'
36
+ require 'codeclimate-test-reporter'
37
+ SimpleCov.add_filter 'vendor'
38
+ SimpleCov.formatters = []
39
+ # merge results of the last 1 hour
40
+ SimpleCov.merge_timeout 3600
41
+ SimpleCov.start CodeClimate::TestReporter.configuration.profile
42
+ else
43
+ require 'simplecov'
44
+ # merge results of the last 1 hour
45
+ SimpleCov.merge_timeout 3600
46
+ SimpleCov.start do
47
+ add_filter 'spec/'
48
+ add_filter 'lib/nucleus/scripts/'
49
+ add_filter 'config/'
50
+
51
+ add_group 'Adapters', 'lib/nucleus/adapters'
52
+ add_group 'Core', 'lib/nucleus/core'
53
+ add_group 'Persistence', 'lib/nucleus/persistence'
54
+ add_group 'Lib ext.', 'lib/nucleus/ext'
55
+ add_group 'API versions', 'lib/nucleus_api/api/versions'
56
+ add_group 'API entities', 'lib/nucleus_api/api/entities'
57
+ add_group 'API helpers', 'lib/nucleus_api/api/helpers'
58
+ add_group 'API Middleware', 'lib/nucleus_api/rack_middleware'
59
+ add_group 'API Models', 'lib/nucleus_api/models'
60
+ add_group 'API Lib ext.', 'lib/nucleus_api/ext'
61
+ end
62
+ end
63
+
64
+ # load configuration for integration tests
65
+ require 'nucleus/scripts/setup_config'
66
+ # disable logging
67
+ # TODO: disable logging via proper config option
68
+ nucleus_config.logging.level = Logger::Severity::FATAL
69
+ # force tmp database
70
+ nucleus_config.db.path = File.join(Dir.tmpdir, "#{SecureRandom.uuid}.nucleus.test.store")
71
+ nucleus_config.db.delete_on_shutdown = true
72
+ nucleus_config.db.override = true
73
+
74
+ # require our app
75
+ require 'nucleus_api/scripts/load_api'
76
+
77
+ # load the certificate to use for the tests only
78
+ nucleus_config.ssh.custom_key = File.expand_path(File.join('spec', 'nucleus_git_key.pem'))
79
+
80
+ # initialize db, versions and auth strategy
81
+ require 'nucleus/scripts/initialize_config_defaults'
82
+ # initialize the api config
83
+ require 'nucleus_api/scripts/initialize_api_customizations'
84
+
85
+ require 'spec/factories/models'
86
+
87
+ # require shared examples
88
+ require_all 'spec/support'
89
+
90
+ RSpec.configure do |config|
91
+ config.include FactoryGirl::Syntax::Methods
92
+ config.before(:suite) do
93
+ Excon.defaults[:mock] = true
94
+ end
95
+ config.after(:each) do
96
+ Excon.stubs.clear
97
+ end
98
+ end
@@ -0,0 +1,99 @@
1
+ shared_examples 'contains the request ID' do
2
+ it 'has a request id' do
3
+ expect(headers['X-Request-ID']).to_not be_nil
4
+ end
5
+ end
6
+
7
+ shared_examples 'valid error' do
8
+ include_examples 'contains the request ID'
9
+ include_examples 'valid error schema'
10
+ end
11
+
12
+ shared_examples 'valid error schema' do
13
+ it 'complies with the error schema' do
14
+ expect_json_keys(:status, :dev_message, :message, :error_code, :more_info)
15
+ end
16
+ it 'status matches error schema status' do
17
+ expect(json_body[:status]).to eq(response.status)
18
+ end
19
+ it 'has a not nil developer message' do
20
+ expect(json_body[:dev_message]).to_not be_nil
21
+ end
22
+ it 'has a non empty developer message' do
23
+ expect(json_body[:dev_message].strip.length).to be > 0
24
+ end
25
+ end
26
+
27
+ shared_examples 'an unknown requested resource' do
28
+ include_examples 'contains the request ID'
29
+ it 'has status 404' do
30
+ expect_status 404
31
+ end
32
+ end
33
+
34
+ shared_examples 'an unauthorized request' do
35
+ include_examples 'contains the request ID'
36
+ it 'has status 401' do
37
+ expect_status 401
38
+ end
39
+ end
40
+
41
+ shared_examples 'a bad request' do
42
+ include_examples 'valid error'
43
+ it 'has status 400' do
44
+ expect_status 400
45
+ end
46
+ it 'has a developer message' do
47
+ expect(json_body[:dev_message]).to_not be_nil
48
+ expect(json_body[:dev_message].strip.length).to be > 0
49
+ end
50
+ end
51
+
52
+ shared_examples 'a semantically invalid request' do
53
+ include_examples 'valid error'
54
+ it 'has status 422' do
55
+ expect_status 422
56
+ end
57
+ end
58
+
59
+ shared_examples 'a not accepted request' do
60
+ include_examples 'valid error'
61
+ it 'has status 406' do
62
+ expect_status 406
63
+ end
64
+ end
65
+
66
+ shared_examples 'a valid GET request' do
67
+ include_examples 'contains the request ID'
68
+ it 'has status 200' do
69
+ expect_status 200
70
+ end
71
+ end
72
+
73
+ shared_examples 'a valid POST request' do
74
+ include_examples 'contains the request ID'
75
+ it 'has status 201' do
76
+ expect_status 201
77
+ end
78
+ end
79
+
80
+ shared_examples 'a valid POST action request' do
81
+ include_examples 'contains the request ID'
82
+ it 'has status 200' do
83
+ expect_status 200
84
+ end
85
+ end
86
+
87
+ shared_examples 'a valid PATCH request' do
88
+ include_examples 'contains the request ID'
89
+ it 'has status 200' do
90
+ expect_status 200
91
+ end
92
+ end
93
+
94
+ shared_examples 'a valid DELETE request' do
95
+ include_examples 'contains the request ID'
96
+ it 'has status 204' do
97
+ expect_status 204
98
+ end
99
+ end
@@ -0,0 +1,31 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ SPEC_SUITES = [
4
+ { id: :unit, title: 'unit tests', pattern: 'spec/unit/**/*_spec.rb' },
5
+ { id: :adapters, title: 'adapter tests', pattern: 'spec/adapter/**/*_spec.rb' },
6
+ { id: :integration, title: 'integration tests', pattern: 'spec/integration/**/*_spec.rb' }
7
+ ]
8
+
9
+ namespace :spec do
10
+ namespace :suite do
11
+ SPEC_SUITES.each do |suite|
12
+ desc "Run all specs in #{suite[:title]} spec suite"
13
+ RSpec::Core::RakeTask.new(suite[:id]) do |t|
14
+ t.pattern = suite[:pattern]
15
+ t.verbose = false
16
+ t.fail_on_error = false
17
+ end
18
+ end
19
+ desc 'Run all spec suites'
20
+ task :all do
21
+ require 'English'
22
+ failed = []
23
+ SPEC_SUITES.each do |suite|
24
+ p "Running spec suite #{suite[:id]} ..."
25
+ Rake::Task["spec:suite:#{suite[:id]}"].execute
26
+ failed << suite[:id] unless $CHILD_STATUS.success?
27
+ end
28
+ fail "Spec suite#{failed.length > 1 ? 's' : ''} '#{failed.join(', ')}' failed" unless failed.empty?
29
+ end
30
+ end
31
+ end