kinde_sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +119 -0
  4. data/LICENSE +21 -0
  5. data/README.md +342 -0
  6. data/Rakefile +10 -0
  7. data/kinde_api/.gitignore +39 -0
  8. data/kinde_api/.rspec +2 -0
  9. data/kinde_api/README.md +103 -0
  10. data/kinde_api/docs/AddOrganizationUsers200Response.md +22 -0
  11. data/kinde_api/docs/AddOrganizationUsersRequest.md +18 -0
  12. data/kinde_api/docs/ApiResult.md +18 -0
  13. data/kinde_api/docs/ConnectedAppsAccessToken.md +20 -0
  14. data/kinde_api/docs/ConnectedAppsApi.md +219 -0
  15. data/kinde_api/docs/ConnectedAppsAuthUrl.md +20 -0
  16. data/kinde_api/docs/CreateOrganization201Response.md +20 -0
  17. data/kinde_api/docs/CreateOrganizationRequest.md +20 -0
  18. data/kinde_api/docs/CreateUser200Response.md +22 -0
  19. data/kinde_api/docs/CreateUserRequest.md +20 -0
  20. data/kinde_api/docs/CreateUserRequestIdentitiesInner.md +20 -0
  21. data/kinde_api/docs/CreateUserRequestIdentitiesInnerDetails.md +18 -0
  22. data/kinde_api/docs/CreateUserRequestProfile.md +20 -0
  23. data/kinde_api/docs/EnvironmentsApi.md +216 -0
  24. data/kinde_api/docs/Error.md +20 -0
  25. data/kinde_api/docs/ErrorResponse.md +18 -0
  26. data/kinde_api/docs/FeatureFlagsApi.md +239 -0
  27. data/kinde_api/docs/GetOrganizationUsers200Response.md +24 -0
  28. data/kinde_api/docs/GetOrganizations200Response.md +24 -0
  29. data/kinde_api/docs/GetUsers200Response.md +24 -0
  30. data/kinde_api/docs/OAuthApi.md +141 -0
  31. data/kinde_api/docs/Organization.md +22 -0
  32. data/kinde_api/docs/OrganizationUser.md +26 -0
  33. data/kinde_api/docs/OrganizationsApi.md +671 -0
  34. data/kinde_api/docs/RemoveOrganizationUsers200Response.md +20 -0
  35. data/kinde_api/docs/RemoveOrganizationUsersRequest.md +18 -0
  36. data/kinde_api/docs/SuccessResponse.md +20 -0
  37. data/kinde_api/docs/UpdateUserRequest.md +22 -0
  38. data/kinde_api/docs/User.md +28 -0
  39. data/kinde_api/docs/UserIdentity.md +20 -0
  40. data/kinde_api/docs/UserIdentityResult.md +20 -0
  41. data/kinde_api/docs/UserProfile.md +26 -0
  42. data/kinde_api/docs/UserProfileV2.md +30 -0
  43. data/kinde_api/docs/UsersApi.md +603 -0
  44. data/kinde_api/lib/kinde_api/api/connected_apps_api.rb +221 -0
  45. data/kinde_api/lib/kinde_api/api/environments_api.rb +212 -0
  46. data/kinde_api/lib/kinde_api/api/feature_flags_api.rb +309 -0
  47. data/kinde_api/lib/kinde_api/api/o_auth_api.rb +136 -0
  48. data/kinde_api/lib/kinde_api/api/organizations_api.rb +634 -0
  49. data/kinde_api/lib/kinde_api/api/users_api.rb +560 -0
  50. data/kinde_api/lib/kinde_api/api_client.rb +397 -0
  51. data/kinde_api/lib/kinde_api/api_error.rb +58 -0
  52. data/kinde_api/lib/kinde_api/configuration.rb +295 -0
  53. data/kinde_api/lib/kinde_api/models/add_organization_users200_response.rb +239 -0
  54. data/kinde_api/lib/kinde_api/models/add_organization_users_request.rb +220 -0
  55. data/kinde_api/lib/kinde_api/models/api_result.rb +218 -0
  56. data/kinde_api/lib/kinde_api/models/connected_apps_access_token.rb +228 -0
  57. data/kinde_api/lib/kinde_api/models/connected_apps_auth_url.rb +228 -0
  58. data/kinde_api/lib/kinde_api/models/create_organization201_response.rb +228 -0
  59. data/kinde_api/lib/kinde_api/models/create_organization_request.rb +252 -0
  60. data/kinde_api/lib/kinde_api/models/create_user200_response.rb +239 -0
  61. data/kinde_api/lib/kinde_api/models/create_user_request.rb +229 -0
  62. data/kinde_api/lib/kinde_api/models/create_user_request_identities_inner.rb +228 -0
  63. data/kinde_api/lib/kinde_api/models/create_user_request_identities_inner_details.rb +219 -0
  64. data/kinde_api/lib/kinde_api/models/create_user_request_profile.rb +229 -0
  65. data/kinde_api/lib/kinde_api/models/error.rb +228 -0
  66. data/kinde_api/lib/kinde_api/models/error_response.rb +219 -0
  67. data/kinde_api/lib/kinde_api/models/get_organization_users200_response.rb +249 -0
  68. data/kinde_api/lib/kinde_api/models/get_organizations200_response.rb +249 -0
  69. data/kinde_api/lib/kinde_api/models/get_users200_response.rb +249 -0
  70. data/kinde_api/lib/kinde_api/models/organization.rb +235 -0
  71. data/kinde_api/lib/kinde_api/models/organization_user.rb +253 -0
  72. data/kinde_api/lib/kinde_api/models/remove_organization_users200_response.rb +228 -0
  73. data/kinde_api/lib/kinde_api/models/remove_organization_users_request.rb +220 -0
  74. data/kinde_api/lib/kinde_api/models/success_response.rb +226 -0
  75. data/kinde_api/lib/kinde_api/models/update_user_request.rb +238 -0
  76. data/kinde_api/lib/kinde_api/models/user.rb +269 -0
  77. data/kinde_api/lib/kinde_api/models/user_identity.rb +227 -0
  78. data/kinde_api/lib/kinde_api/models/user_identity_result.rb +229 -0
  79. data/kinde_api/lib/kinde_api/models/user_profile.rb +259 -0
  80. data/kinde_api/lib/kinde_api/models/user_profile_v2.rb +279 -0
  81. data/kinde_api/lib/kinde_api/version.rb +15 -0
  82. data/kinde_api/lib/kinde_api.rb +73 -0
  83. data/kinde_api/spec/api/connected_apps_api_spec.rb +72 -0
  84. data/kinde_api/spec/api/environments_api_spec.rb +71 -0
  85. data/kinde_api/spec/api/feature_flags_api_spec.rb +82 -0
  86. data/kinde_api/spec/api/o_auth_api_spec.rb +57 -0
  87. data/kinde_api/spec/api/organizations_api_spec.rb +154 -0
  88. data/kinde_api/spec/api/users_api_spec.rb +141 -0
  89. data/kinde_api/spec/api_client_spec.rb +229 -0
  90. data/kinde_api/spec/configuration_spec.rb +42 -0
  91. data/kinde_api/spec/models/add_organization_users200_response_spec.rb +46 -0
  92. data/kinde_api/spec/models/add_organization_users_request_spec.rb +34 -0
  93. data/kinde_api/spec/models/api_result_spec.rb +34 -0
  94. data/kinde_api/spec/models/connected_apps_access_token_spec.rb +40 -0
  95. data/kinde_api/spec/models/connected_apps_auth_url_spec.rb +40 -0
  96. data/kinde_api/spec/models/create_organization201_response_spec.rb +40 -0
  97. data/kinde_api/spec/models/create_organization_request_spec.rb +44 -0
  98. data/kinde_api/spec/models/create_user200_response_spec.rb +46 -0
  99. data/kinde_api/spec/models/create_user_request_identities_inner_details_spec.rb +34 -0
  100. data/kinde_api/spec/models/create_user_request_identities_inner_spec.rb +40 -0
  101. data/kinde_api/spec/models/create_user_request_profile_spec.rb +40 -0
  102. data/kinde_api/spec/models/create_user_request_spec.rb +40 -0
  103. data/kinde_api/spec/models/error_response_spec.rb +34 -0
  104. data/kinde_api/spec/models/error_spec.rb +40 -0
  105. data/kinde_api/spec/models/get_organization_users200_response_spec.rb +52 -0
  106. data/kinde_api/spec/models/get_organizations200_response_spec.rb +52 -0
  107. data/kinde_api/spec/models/get_users200_response_spec.rb +52 -0
  108. data/kinde_api/spec/models/organization_spec.rb +46 -0
  109. data/kinde_api/spec/models/organization_user_spec.rb +58 -0
  110. data/kinde_api/spec/models/remove_organization_users200_response_spec.rb +40 -0
  111. data/kinde_api/spec/models/remove_organization_users_request_spec.rb +34 -0
  112. data/kinde_api/spec/models/success_response_spec.rb +40 -0
  113. data/kinde_api/spec/models/update_user_request_spec.rb +46 -0
  114. data/kinde_api/spec/models/user_identity_result_spec.rb +40 -0
  115. data/kinde_api/spec/models/user_identity_spec.rb +40 -0
  116. data/kinde_api/spec/models/user_profile_spec.rb +58 -0
  117. data/kinde_api/spec/models/user_profile_v2_spec.rb +70 -0
  118. data/kinde_api/spec/models/user_spec.rb +64 -0
  119. data/kinde_api/spec/spec_helper.rb +111 -0
  120. data/kinde_sdk.gemspec +33 -0
  121. data/lib/kinde_sdk/client.rb +49 -0
  122. data/lib/kinde_sdk/configuration.rb +50 -0
  123. data/lib/kinde_sdk/version.rb +3 -0
  124. data/lib/kinde_sdk.rb +109 -0
  125. data/openapitools.json +7 -0
  126. data/spec/kinde_sdk_spec.rb +105 -0
  127. data/spec/spec_helper.rb +82 -0
  128. metadata +291 -0
@@ -0,0 +1,49 @@
1
+ require "kinde_api"
2
+
3
+ module KindeSdk
4
+ class Client
5
+ attr_accessor :kinde_api_client
6
+ attr_accessor :bearer_token
7
+
8
+ def initialize(sdk_api_client, bearer_token)
9
+ @kinde_api_client = sdk_api_client
10
+ @bearer_token = bearer_token
11
+ @decoded_token = JWT.decode(bearer_token, nil, false)
12
+ end
13
+
14
+ def get_claim(*args)
15
+ @decoded_token[0].dig(*args)
16
+ end
17
+
18
+ def get_permissions
19
+ get_claim("permissions")
20
+ end
21
+
22
+ def get_permission(permission)
23
+ {
24
+ org_code: get_claim("org_code"),
25
+ is_granted: permission_granted?(permission)
26
+ }
27
+ end
28
+
29
+ def permission_granted?(permission)
30
+ get_claim("permissions").include?(permission)
31
+ end
32
+
33
+ def logout
34
+ KindeSdk.logout(bearer_token, kinde_api_client)
35
+ end
36
+
37
+ ::KindeApi.constants.filter { |klass| klass.to_s.end_with?("Api") }.each do |klass|
38
+ api_klass = Kernel.const_get("KindeApi::#{klass}")
39
+
40
+ define_method(klass.to_s.downcase.split("api")[0]) { init_instance_api(api_klass) }
41
+ end
42
+
43
+ private
44
+
45
+ def init_instance_api(api_klass)
46
+ api_klass.new(kinde_api_client)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,50 @@
1
+ module KindeSdk
2
+ class Configuration
3
+ attr_accessor :domain
4
+ attr_accessor :client_id
5
+ attr_accessor :client_secret
6
+ attr_accessor :callback_url
7
+ attr_accessor :logout_url
8
+ attr_accessor :scope
9
+
10
+ attr_accessor :authorize_url
11
+ attr_accessor :token_url
12
+
13
+ attr_accessor :logger
14
+ attr_accessor :debugging
15
+ attr_accessor :oauth_client
16
+ attr_accessor :pkce_enabled
17
+ attr_accessor :business_name
18
+
19
+ def initialize
20
+ @authorize_url = '/oauth2/auth'
21
+ @token_url = '/oauth2/token'
22
+ @debugging = false
23
+ @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
24
+ @scope = 'openid offline email profile'
25
+ @pkce_enabled = true
26
+ @business_name = nil
27
+
28
+ yield(self) if block_given?
29
+ end
30
+
31
+ def self.default
32
+ @@default ||= Configuration.new
33
+ end
34
+
35
+ def configure
36
+ yield(self) if block_given?
37
+ end
38
+
39
+ def oauth_client
40
+ ::OAuth2::Client.new(
41
+ client_id,
42
+ client_secret,
43
+ site: domain,
44
+ authorize_url: authorize_url,
45
+ token_url: token_url,
46
+ logger: logger
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module KindeSdk
2
+ VERSION = "1.0.0"
3
+ end
data/lib/kinde_sdk.rb ADDED
@@ -0,0 +1,109 @@
1
+ require "kinde_sdk/version"
2
+ require "kinde_sdk/configuration"
3
+ require "kinde_sdk/client"
4
+
5
+ require 'securerandom'
6
+ require 'oauth2'
7
+ require 'pkce_challenge'
8
+ require 'faraday/follow_redirects'
9
+
10
+ module KindeSdk
11
+ class << self
12
+ attr_accessor :config
13
+
14
+ def configure
15
+ if block_given?
16
+ yield(Configuration.default)
17
+ else
18
+ Configuration.default
19
+ end
20
+
21
+ @config = Configuration.default
22
+ end
23
+
24
+ # receive url for authorization in Kinde itself
25
+ #
26
+ # @return [Hash]
27
+ def auth_url(**kwargs)
28
+ params = {
29
+ redirect_uri: @config.callback_url,
30
+ state: SecureRandom.hex,
31
+ scope: @config.scope
32
+ }.merge(**kwargs)
33
+ return { url: @config.oauth_client.auth_code.authorize_url(params) } unless @config.pkce_enabled
34
+
35
+ pkce_challenge = PkceChallenge.challenge(char_length: 128)
36
+ params.merge!(code_challenge_method: 'S256', code_challenge: pkce_challenge.code_challenge)
37
+ {
38
+ url: @config.oauth_client.auth_code.authorize_url(params),
39
+ code_verifier: pkce_challenge.code_verifier
40
+ }
41
+ end
42
+
43
+ # when callback processor receives code, it needs to be used for fetching bearer token
44
+ #
45
+ # @return [Hash]
46
+ def fetch_tokens(params_or_code, code_verifier = nil)
47
+ code = params_or_code.kind_of?(Hash) ? params.fetch("code") : params_or_code
48
+ params = { redirect_uri: @config.callback_url }
49
+ params[:code_verifier] = code_verifier if code_verifier
50
+ @config.oauth_client.auth_code.get_token(code.to_s, params).to_hash
51
+ end
52
+
53
+ # @return [KindeSdk::Client]
54
+ def client(bearer_token)
55
+ sdk_api_client = api_client(bearer_token)
56
+ KindeSdk::Client.new(sdk_api_client, bearer_token)
57
+ end
58
+
59
+ def logout(bearer_token, sdk_api_client = nil)
60
+ (sdk_api_client || api_client(bearer_token))
61
+ .call_api(
62
+ :get, '/logout',
63
+ query_params: { 'redirect' => @config.logout_url },
64
+ header_params: { 'Authorization' => "Bearer #{bearer_token}" }
65
+ )
66
+ end
67
+
68
+ def client_credentials_access(
69
+ client_id: @config.client_id,
70
+ client_secret: @config.client_secret,
71
+ audience: "#{@config.domain}/api"
72
+ )
73
+ Faraday.new(url: @config.domain) do |faraday|
74
+ faraday.response :json
75
+ faraday.use Faraday::FollowRedirects::Middleware
76
+ end
77
+ .post(@config.token_url) do |req|
78
+ req.headers[:content_type] = 'application/x-www-form-urlencoded'
79
+ req.body =
80
+ "grant_type=client_credentials&client_id=#{client_id}&client_secret=#{client_secret}&audience=#{audience}"
81
+ end.body
82
+ end
83
+
84
+ def token_expired?(hash)
85
+ OAuth2::AccessToken.from_hash(@config.oauth_client, hash).expired?
86
+ end
87
+
88
+ # @return [Hash]
89
+ def refresh_token(hash)
90
+ OAuth2::AccessToken.from_hash(@config.oauth_client, hash).refresh.to_hash
91
+ end
92
+
93
+ # init sdk api client by bearer token
94
+ #
95
+ # @return [KindeApi::ApiClient]
96
+ def api_client(bearer_token)
97
+ config = KindeApi::Configuration.default
98
+ config.configure do |c|
99
+ c.access_token = bearer_token
100
+ c.server_variables = { businessName: @config.business_name || @config.domain.split("//")[1].split(".")[0] }
101
+ c.host = @config.domain
102
+ c.debugging = @config.debugging
103
+ c.logger = @config.logger
104
+ end
105
+
106
+ KindeApi::ApiClient.new(config)
107
+ end
108
+ end
109
+ end
data/openapitools.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
3
+ "spaces": 2,
4
+ "generator-cli": {
5
+ "version": "6.4.0"
6
+ }
7
+ }
@@ -0,0 +1,105 @@
1
+ require 'spec_helper'
2
+
3
+ describe KindeSdk do
4
+ let(:domain) { "http://example.com" }
5
+ let(:client_id) { "client_id" }
6
+ let(:client_secret) { "client_secret" }
7
+ let(:callback_url) { "http://localhost:3000/callback" }
8
+
9
+ before do
10
+ KindeSdk.configure do |c|
11
+ c.domain = domain
12
+ c.client_id = client_id
13
+ c.client_secret = client_secret
14
+ c.callback_url = callback_url
15
+ end
16
+ end
17
+
18
+ describe "#auth_url" do
19
+ it "returns prepared authorize url", :aggregate_failures do
20
+ auth_obj = described_class.auth_url
21
+ expect(auth_obj[:code_verifier]).not_to be_nil
22
+ expect(auth_obj[:url]).to start_with("#{domain}/oauth2/auth?client_id=#{client_id}&")
23
+ end
24
+ end
25
+
26
+ describe "#api_client" do
27
+ it "returns initialized api_client instance of KindeApi" do
28
+ expect(described_class.api_client("bearer-token")).to be_instance_of(KindeApi::ApiClient)
29
+ end
30
+ end
31
+
32
+ describe "#client_credentials_access" do
33
+ let(:audience) { "#{domain}/api" }
34
+ let(:request_body) do
35
+ "grant_type=client_credentials&client_id=#{client_id}&client_secret=#{client_secret}&audience=#{audience}"
36
+ end
37
+ let(:response_body) do
38
+ { "access_token" => "eyJhbGciO", "expires_in" => 86399, "scope" => "", "token_type" => "bearer" }.to_json
39
+ end
40
+ before { stub_request(:post, "#{domain}/oauth2/token").with(body: request_body).to_return(body: response_body) }
41
+
42
+ it "calls oauth2/token url with configured credentials" do
43
+ expect(described_class.client_credentials_access).to eq(response_body)
44
+ end
45
+
46
+ context "with params override" do
47
+ let(:client_id) { 'other_id' }
48
+ let(:client_secret) { 'other_secret' }
49
+ let(:audience) { 'some-audience' }
50
+
51
+ it "calls oauth2/token url with passed credentials" do
52
+ expect(described_class.client_credentials_access(
53
+ client_id: client_id, client_secret: client_secret, audience: audience
54
+ )).to eq(response_body)
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "client" do
60
+ let(:hash_to_encode) do
61
+ { "aud" => [],
62
+ "azp" => "19ebb687cd2f405c9f2daf645a8db895",
63
+ "exp" => 1679600554,
64
+ "feature_flags" => nil,
65
+ "iat" => 1679514154,
66
+ "iss" => "https://qwv2.kinde.com",
67
+ "jti" => "22c48b2c-da46-4661-a7ff-425c23eceab5",
68
+ "org_code" => "org_cb4544175bc",
69
+ "permissions" => ["read:todos", "create:todos"],
70
+ "scp" => ["openid", "offline"],
71
+ "sub" => "kp:b17adf719f7d4b87b611d1a88a09fd15" }
72
+ end
73
+ let(:token) { JWT.encode(hash_to_encode, nil, "none") }
74
+ let(:client) { described_class.client(token) }
75
+
76
+ it "returns requested claim from bearer", :aggregate_failures do
77
+ expect(client.get_claim("scp")).to eq(hash_to_encode["scp"])
78
+ expect(client.get_claim("aaa")).to be_nil
79
+ end
80
+
81
+ it "returns permissions from bearer", :aggregate_failures do
82
+ expect(client.get_permissions).to eq(hash_to_encode["permissions"])
83
+ expect(client.get_permission(hash_to_encode["permissions"][0]))
84
+ .to eq({ org_code: hash_to_encode["org_code"], is_granted: true })
85
+ expect(client.permission_granted?(hash_to_encode["permissions"][0])).to be(true)
86
+ expect(client.get_permission("asd"))
87
+ .to eq({ org_code: hash_to_encode["org_code"], is_granted: false })
88
+ expect(client.permission_granted?("asd")).to be(false)
89
+ end
90
+
91
+ describe "api instances" do
92
+ it 'initializes client by passing the bearer' do
93
+ expect(client).to be_instance_of(KindeSdk::Client)
94
+ end
95
+
96
+ it "initializes oauth instance api" do
97
+ expect(client.oauth).to be_instance_of(KindeApi::OAuthApi)
98
+ end
99
+
100
+ it "initializes users instance api" do
101
+ expect(client.users).to be_instance_of(KindeApi::UsersApi)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,82 @@
1
+ require "kinde_sdk"
2
+ require "webmock/rspec"
3
+
4
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
+ RSpec.configure do |config|
6
+ # rspec-expectations config goes here. You can use an alternate
7
+ # assertion/expectation library such as wrong or the stdlib/minitest
8
+ # assertions if you prefer.
9
+ config.expect_with :rspec do |expectations|
10
+ # This option will default to `true` in RSpec 4. It makes the `description`
11
+ # and `failure_message` of custom matchers include text for helper methods
12
+ # defined using `chain`, e.g.:
13
+ # be_bigger_than(2).and_smaller_than(4).description
14
+ # # => "be bigger than 2 and smaller than 4"
15
+ # ...rather than:
16
+ # # => "be bigger than 2"
17
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
18
+ end
19
+
20
+ # rspec-mocks config goes here. You can use an alternate test double
21
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
22
+ config.mock_with :rspec do |mocks|
23
+ # Prevents you from mocking or stubbing a method that does not exist on
24
+ # a real object. This is generally recommended, and will default to
25
+ # `true` in RSpec 4.
26
+ mocks.verify_partial_doubles = true
27
+ end
28
+
29
+ # The settings below are suggested to provide a good initial experience
30
+ # with RSpec, but feel free to customize to your heart's content.
31
+ =begin
32
+ # These two settings work together to allow you to limit a spec run
33
+ # to individual examples or groups you care about by tagging them with
34
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
35
+ # get run.
36
+ config.filter_run :focus
37
+ config.run_all_when_everything_filtered = true
38
+
39
+ # Allows RSpec to persist some state between runs in order to support
40
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
41
+ # you configure your source control system to ignore this file.
42
+ config.example_status_persistence_file_path = "spec/examples.txt"
43
+
44
+ # Limits the available syntax to the non-monkey patched syntax that is
45
+ # recommended. For more details, see:
46
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
47
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
48
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
49
+ config.disable_monkey_patching!
50
+
51
+ # This setting enables warnings. It's recommended, but in some cases may
52
+ # be too noisy due to issues in dependencies.
53
+ config.warnings = true
54
+
55
+ # Many RSpec users commonly either run the entire suite or an individual
56
+ # file, and it's useful to allow more verbose output when running an
57
+ # individual spec file.
58
+ if config.files_to_run.one?
59
+ # Use the documentation formatter for detailed output,
60
+ # unless a formatter has already been configured
61
+ # (e.g. via a command-line flag).
62
+ config.default_formatter = 'doc'
63
+ end
64
+
65
+ # Print the 10 slowest examples and example groups at the
66
+ # end of the spec run, to help surface which specs are running
67
+ # particularly slow.
68
+ config.profile_examples = 10
69
+
70
+ # Run specs in random order to surface order dependencies. If you find an
71
+ # order dependency and want to debug it, you can fix the order by providing
72
+ # the seed, which is printed after each run.
73
+ # --seed 1234
74
+ config.order = :random
75
+
76
+ # Seed global randomization in this process using the `--seed` CLI option.
77
+ # Setting this allows you to use `--seed` to deterministically reproduce
78
+ # test failures related to randomization by passing the same `--seed` value
79
+ # as the one that triggered the failure.
80
+ Kernel.srand config.seed
81
+ =end
82
+ end