doorkeeper 5.1.0 → 5.3.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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +3 -3
  3. data/CHANGELOG.md +881 -0
  4. data/CONTRIBUTING.md +11 -9
  5. data/Dangerfile +2 -2
  6. data/Dockerfile +29 -0
  7. data/Gemfile +4 -3
  8. data/NEWS.md +1 -814
  9. data/README.md +11 -3
  10. data/RELEASING.md +6 -5
  11. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  13. data/app/controllers/doorkeeper/applications_controller.rb +1 -0
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +16 -9
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  16. data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
  17. data/app/views/doorkeeper/applications/_form.html.erb +0 -6
  18. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  19. data/config/locales/en.yml +8 -2
  20. data/doorkeeper.gemspec +9 -1
  21. data/gemfiles/rails_5_0.gemfile +3 -2
  22. data/gemfiles/rails_5_1.gemfile +3 -2
  23. data/gemfiles/rails_5_2.gemfile +3 -2
  24. data/gemfiles/rails_6_0.gemfile +4 -3
  25. data/gemfiles/rails_master.gemfile +3 -2
  26. data/lib/doorkeeper/config/option.rb +13 -7
  27. data/lib/doorkeeper/config.rb +157 -42
  28. data/lib/doorkeeper/errors.rb +13 -18
  29. data/lib/doorkeeper/grape/helpers.rb +6 -2
  30. data/lib/doorkeeper/helpers/controller.rb +28 -7
  31. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  32. data/lib/doorkeeper/models/access_token_mixin.rb +99 -20
  33. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  34. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  37. data/lib/doorkeeper/oauth/authorization/code.rb +12 -14
  38. data/lib/doorkeeper/oauth/authorization/token.rb +10 -7
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +31 -15
  40. data/lib/doorkeeper/oauth/base_request.rb +10 -4
  41. data/lib/doorkeeper/oauth/client.rb +7 -8
  42. data/lib/doorkeeper/oauth/client_credentials/creator.rb +23 -2
  43. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  44. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +10 -2
  45. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  46. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  47. data/lib/doorkeeper/oauth/code_response.rb +4 -4
  48. data/lib/doorkeeper/oauth/error.rb +1 -1
  49. data/lib/doorkeeper/oauth/error_response.rb +6 -6
  50. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  51. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  52. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
  53. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  54. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  55. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  56. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
  57. data/lib/doorkeeper/oauth/pre_authorization.rb +76 -38
  58. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -14
  59. data/lib/doorkeeper/oauth/token.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_introspection.rb +26 -16
  61. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  62. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  63. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  64. data/lib/doorkeeper/orm/active_record/application.rb +5 -83
  65. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  66. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  67. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  68. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  69. data/lib/doorkeeper/orm/active_record.rb +21 -6
  70. data/lib/doorkeeper/rails/helpers.rb +4 -4
  71. data/lib/doorkeeper/rails/routes.rb +5 -7
  72. data/lib/doorkeeper/rake/db.rake +3 -3
  73. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  74. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  75. data/lib/doorkeeper/request/password.rb +2 -2
  76. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  77. data/lib/doorkeeper/request.rb +7 -12
  78. data/lib/doorkeeper/server.rb +3 -7
  79. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  80. data/lib/doorkeeper/version.rb +1 -1
  81. data/lib/doorkeeper.rb +6 -3
  82. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  83. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  84. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  85. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  86. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  87. data/lib/generators/doorkeeper/templates/initializer.rb +149 -33
  88. data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  90. data/spec/controllers/applications_controller_spec.rb +95 -1
  91. data/spec/controllers/authorizations_controller_spec.rb +156 -75
  92. data/spec/controllers/protected_resources_controller_spec.rb +28 -20
  93. data/spec/controllers/token_info_controller_spec.rb +1 -1
  94. data/spec/controllers/tokens_controller_spec.rb +206 -38
  95. data/spec/dummy/config/application.rb +3 -1
  96. data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
  97. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  98. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  99. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  100. data/spec/generators/install_generator_spec.rb +1 -1
  101. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  102. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  103. data/spec/lib/config_spec.rb +104 -7
  104. data/spec/lib/doorkeeper_spec.rb +1 -1
  105. data/spec/lib/models/revocable_spec.rb +3 -3
  106. data/spec/lib/oauth/authorization_code_request_spec.rb +129 -115
  107. data/spec/lib/oauth/base_request_spec.rb +154 -135
  108. data/spec/lib/oauth/base_response_spec.rb +27 -29
  109. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  110. data/spec/lib/oauth/client_credentials/creator_spec.rb +43 -3
  111. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  112. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  113. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  114. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  115. data/spec/lib/oauth/client_spec.rb +26 -26
  116. data/spec/lib/oauth/code_request_spec.rb +34 -35
  117. data/spec/lib/oauth/code_response_spec.rb +21 -25
  118. data/spec/lib/oauth/error_response_spec.rb +42 -44
  119. data/spec/lib/oauth/error_spec.rb +12 -14
  120. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  121. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  122. data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
  123. data/spec/lib/oauth/invalid_request_response_spec.rb +73 -0
  124. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  125. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  126. data/spec/lib/oauth/pre_authorization_spec.rb +161 -153
  127. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -138
  128. data/spec/lib/oauth/scopes_spec.rb +104 -106
  129. data/spec/lib/oauth/token_request_spec.rb +117 -110
  130. data/spec/lib/oauth/token_response_spec.rb +71 -73
  131. data/spec/lib/oauth/token_spec.rb +121 -123
  132. data/spec/lib/server_spec.rb +0 -12
  133. data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
  134. data/spec/models/doorkeeper/access_token_spec.rb +42 -11
  135. data/spec/models/doorkeeper/application_spec.rb +114 -77
  136. data/spec/requests/applications/applications_request_spec.rb +1 -1
  137. data/spec/requests/endpoints/authorization_spec.rb +26 -8
  138. data/spec/requests/endpoints/token_spec.rb +1 -1
  139. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  140. data/spec/requests/flows/authorization_code_spec.rb +123 -45
  141. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  142. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  143. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  144. data/spec/requests/flows/password_spec.rb +67 -10
  145. data/spec/requests/flows/refresh_token_spec.rb +20 -20
  146. data/spec/requests/flows/revoke_token_spec.rb +37 -23
  147. data/spec/spec_helper.rb +1 -4
  148. data/spec/support/doorkeeper_rspec.rb +1 -1
  149. data/spec/support/helpers/request_spec_helper.rb +14 -2
  150. data/spec/support/shared/controllers_shared_context.rb +33 -23
  151. data/spec/validators/redirect_uri_validator_spec.rb +41 -16
  152. metadata +19 -16
  153. data/.coveralls.yml +0 -1
  154. data/.github/ISSUE_TEMPLATE.md +0 -25
  155. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  156. data/.gitignore +0 -20
  157. data/.gitlab-ci.yml +0 -16
  158. data/.hound.yml +0 -3
  159. data/.rspec +0 -1
  160. data/.rubocop.yml +0 -50
  161. data/.travis.yml +0 -35
  162. data/app/validators/redirect_uri_validator.rb +0 -50
  163. data/spec/support/http_method_shim.rb +0 -29
@@ -2,213 +2,221 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe PreAuthorization do
7
- let(:server) do
8
- server = Doorkeeper.configuration
9
- allow(server).to receive(:default_scopes).and_return(Scopes.new)
10
- allow(server).to receive(:scopes).and_return(Scopes.from_string("public profile"))
11
- server
12
- end
5
+ describe Doorkeeper::OAuth::PreAuthorization do
6
+ let(:server) do
7
+ server = Doorkeeper.configuration
8
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("default"))
9
+ allow(server).to receive(:optional_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public profile"))
10
+ server
11
+ end
13
12
 
14
- let(:application) do
15
- application = double :application
16
- allow(application).to receive(:scopes).and_return(Scopes.from_string(""))
17
- application
18
- end
13
+ let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
14
+ let(:client) { Doorkeeper::OAuth::Client.find(application.uid) }
19
15
 
20
- let(:client) do
21
- double :client, redirect_uri: "http://tst.com/auth", application: application
22
- end
16
+ let :attributes do
17
+ {
18
+ client_id: client.uid,
19
+ response_type: "code",
20
+ redirect_uri: "https://app.com/callback",
21
+ state: "save-this",
22
+ }
23
+ end
23
24
 
24
- let :attributes do
25
- {
26
- response_type: "code",
27
- redirect_uri: "http://tst.com/auth",
28
- state: "save-this",
29
- }
30
- end
25
+ subject do
26
+ described_class.new(server, attributes)
27
+ end
31
28
 
32
- subject do
33
- PreAuthorization.new(server, client, attributes)
34
- end
29
+ it "is authorizable when request is valid" do
30
+ expect(subject).to be_authorizable
31
+ end
35
32
 
36
- it "is authorizable when request is valid" do
33
+ it "accepts code as response type" do
34
+ attributes[:response_type] = "code"
35
+ expect(subject).to be_authorizable
36
+ end
37
+
38
+ it "accepts token as response type" do
39
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
40
+ attributes[:response_type] = "token"
41
+ expect(subject).to be_authorizable
42
+ end
43
+
44
+ context "when using default grant flows" do
45
+ it 'accepts "code" as response type' do
46
+ attributes[:response_type] = "code"
37
47
  expect(subject).to be_authorizable
38
48
  end
39
49
 
40
- it "accepts code as response type" do
41
- subject.response_type = "code"
50
+ it 'accepts "token" as response type' do
51
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
52
+ attributes[:response_type] = "token"
42
53
  expect(subject).to be_authorizable
43
54
  end
55
+ end
44
56
 
45
- it "accepts token as response type" do
57
+ context "when authorization code grant flow is disabled" do
58
+ before do
46
59
  allow(server).to receive(:grant_flows).and_return(["implicit"])
47
- subject.response_type = "token"
48
- expect(subject).to be_authorizable
49
60
  end
50
61
 
51
- context "when using default grant flows" do
52
- it 'accepts "code" as response type' do
53
- subject.response_type = "code"
54
- expect(subject).to be_authorizable
55
- end
62
+ it 'does not accept "code" as response type' do
63
+ attributes[:response_type] = "code"
64
+ expect(subject).not_to be_authorizable
65
+ end
66
+ end
56
67
 
57
- it 'accepts "token" as response type' do
58
- allow(server).to receive(:grant_flows).and_return(["implicit"])
59
- subject.response_type = "token"
60
- expect(subject).to be_authorizable
61
- end
68
+ context "when implicit grant flow is disabled" do
69
+ before do
70
+ allow(server).to receive(:grant_flows).and_return(["authorization_code"])
62
71
  end
63
72
 
64
- context "when authorization code grant flow is disabled" do
65
- before do
66
- allow(server).to receive(:grant_flows).and_return(["implicit"])
67
- end
73
+ it 'does not accept "token" as response type' do
74
+ attributes[:response_type] = "token"
75
+ expect(subject).not_to be_authorizable
76
+ end
77
+ end
68
78
 
69
- it 'does not accept "code" as response type' do
70
- subject.response_type = "code"
71
- expect(subject).not_to be_authorizable
72
- end
79
+ context "client application does not restrict valid scopes" do
80
+ it "accepts valid scopes" do
81
+ attributes[:scope] = "public"
82
+ expect(subject).to be_authorizable
73
83
  end
74
84
 
75
- context "when implicit grant flow is disabled" do
76
- before do
77
- allow(server).to receive(:grant_flows).and_return(["authorization_code"])
78
- end
85
+ it "rejects (globally) non-valid scopes" do
86
+ attributes[:scope] = "invalid"
87
+ expect(subject).not_to be_authorizable
88
+ end
79
89
 
80
- it 'does not accept "token" as response type' do
81
- subject.response_type = "token"
82
- expect(subject).not_to be_authorizable
83
- end
90
+ it "accepts scopes which are permitted for grant_type" do
91
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
92
+ attributes[:scope] = "public"
93
+ expect(subject).to be_authorizable
84
94
  end
85
95
 
86
- context "client application does not restrict valid scopes" do
87
- it "accepts valid scopes" do
88
- subject.scope = "public"
89
- expect(subject).to be_authorizable
90
- end
96
+ it "rejects scopes which are not permitted for grant_type" do
97
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
98
+ attributes[:scope] = "public"
99
+ expect(subject).not_to be_authorizable
100
+ end
101
+ end
91
102
 
92
- it "rejects (globally) non-valid scopes" do
93
- subject.scope = "invalid"
94
- expect(subject).not_to be_authorizable
95
- end
103
+ context "client application restricts valid scopes" do
104
+ let(:application) do
105
+ FactoryBot.create(:application, scopes: Doorkeeper::OAuth::Scopes.from_string("public nonsense"))
106
+ end
96
107
 
97
- it "accepts scopes which are permitted for grant_type" do
98
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
99
- subject.scope = "public"
100
- expect(subject).to be_authorizable
101
- end
108
+ it "accepts valid scopes" do
109
+ attributes[:scope] = "public"
110
+ expect(subject).to be_authorizable
111
+ end
102
112
 
103
- it "rejects scopes which are not permitted for grant_type" do
104
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
105
- subject.scope = "public"
106
- expect(subject).not_to be_authorizable
107
- end
113
+ it "rejects (globally) non-valid scopes" do
114
+ attributes[:scope] = "invalid"
115
+ expect(subject).not_to be_authorizable
108
116
  end
109
117
 
110
- context "client application restricts valid scopes" do
111
- let(:application) do
112
- application = double :application
113
- allow(application).to receive(:scopes).and_return(Scopes.from_string("public nonsense"))
114
- application
115
- end
118
+ it "rejects (application level) non-valid scopes" do
119
+ attributes[:scope] = "profile"
120
+ expect(subject).to_not be_authorizable
121
+ end
116
122
 
117
- it "accepts valid scopes" do
118
- subject.scope = "public"
119
- expect(subject).to be_authorizable
120
- end
123
+ it "accepts scopes which are permitted for grant_type" do
124
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
125
+ attributes[:scope] = "public"
126
+ expect(subject).to be_authorizable
127
+ end
121
128
 
122
- it "rejects (globally) non-valid scopes" do
123
- subject.scope = "invalid"
124
- expect(subject).not_to be_authorizable
125
- end
129
+ it "rejects scopes which are not permitted for grant_type" do
130
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
131
+ attributes[:scope] = "public"
132
+ expect(subject).not_to be_authorizable
133
+ end
134
+ end
126
135
 
127
- it "rejects (application level) non-valid scopes" do
128
- subject.scope = "profile"
129
- expect(subject).to_not be_authorizable
130
- end
136
+ context "when scope is not provided to pre_authorization" do
137
+ before { attributes[:scope] = nil }
131
138
 
132
- it "accepts scopes which are permitted for grant_type" do
133
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
134
- subject.scope = "public"
139
+ context "when default scopes is provided" do
140
+ it "uses default scopes" do
141
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("default_scope"))
135
142
  expect(subject).to be_authorizable
143
+ expect(subject.scope).to eq("default_scope")
144
+ expect(subject.scopes).to eq(Doorkeeper::OAuth::Scopes.from_string("default_scope"))
136
145
  end
146
+ end
137
147
 
138
- it "rejects scopes which are not permitted for grant_type" do
139
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
140
- subject.scope = "public"
148
+ context "when default scopes is none" do
149
+ it "not be authorizable when none default scope" do
150
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.new)
141
151
  expect(subject).not_to be_authorizable
142
152
  end
143
153
  end
154
+ end
144
155
 
145
- it "uses default scopes when none is required" do
146
- allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
147
- subject.scope = nil
148
- expect(subject.scope).to eq("default")
149
- expect(subject.scopes).to eq(Scopes.from_string("default"))
150
- end
156
+ it "matches the redirect uri against client's one" do
157
+ attributes[:redirect_uri] = "http://nothesame.com"
158
+ expect(subject).not_to be_authorizable
159
+ end
151
160
 
152
- context "with native redirect uri" do
153
- let(:native_redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
161
+ it "stores the state" do
162
+ expect(subject.state).to eq("save-this")
163
+ end
154
164
 
155
- it "accepts redirect_uri when it matches with the client" do
156
- subject.redirect_uri = native_redirect_uri
157
- allow(subject.client).to receive(:redirect_uri) { native_redirect_uri }
158
- expect(subject).to be_authorizable
159
- end
165
+ it "rejects if response type is not allowed" do
166
+ attributes[:response_type] = "whops"
167
+ expect(subject).not_to be_authorizable
168
+ end
160
169
 
161
- it "invalidates redirect_uri when it does'n match with the client" do
162
- subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
163
- expect(subject).not_to be_authorizable
164
- end
165
- end
170
+ it "requires an existing client" do
171
+ attributes[:client_id] = nil
172
+ expect(subject).not_to be_authorizable
173
+ end
166
174
 
167
- it "matches the redirect uri against client's one" do
168
- subject.redirect_uri = "http://nothesame.com"
169
- expect(subject).not_to be_authorizable
170
- end
175
+ it "requires a redirect uri" do
176
+ attributes[:redirect_uri] = nil
177
+ expect(subject).not_to be_authorizable
178
+ end
171
179
 
172
- it "stores the state" do
173
- expect(subject.state).to eq("save-this")
174
- end
180
+ describe "as_json" do
181
+ before { subject.authorizable? }
175
182
 
176
- it "rejects if response type is not allowed" do
177
- subject.response_type = "whops"
178
- expect(subject).not_to be_authorizable
179
- end
183
+ it { is_expected.to respond_to :as_json }
180
184
 
181
- it "requires an existing client" do
182
- subject.client = nil
183
- expect(subject).not_to be_authorizable
185
+ shared_examples "returns the pre authorization" do
186
+ it "returns the pre authorization" do
187
+ expect(json[:client_id]).to eq client.uid
188
+ expect(json[:redirect_uri]).to eq subject.redirect_uri
189
+ expect(json[:state]).to eq subject.state
190
+ expect(json[:response_type]).to eq subject.response_type
191
+ expect(json[:scope]).to eq subject.scope
192
+ expect(json[:client_name]).to eq client.name
193
+ expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
194
+ end
184
195
  end
185
196
 
186
- it "requires a redirect uri" do
187
- subject.redirect_uri = nil
188
- expect(subject).not_to be_authorizable
197
+ context "when attributes param is not passed" do
198
+ let(:json) { subject.as_json }
199
+
200
+ include_examples "returns the pre authorization"
189
201
  end
190
202
 
191
- describe "as_json" do
192
- let(:client_id) { "client_uid_123" }
193
- let(:client_name) { "Acme Co." }
203
+ context "when attributes param is passed" do
204
+ context "when attributes is a hash" do
205
+ let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
206
+ let(:json) { subject.as_json(custom_attributes) }
194
207
 
195
- before do
196
- allow(client).to receive(:uid).and_return client_id
197
- allow(client).to receive(:name).and_return client_name
198
- end
208
+ include_examples "returns the pre authorization"
199
209
 
200
- let(:json) { subject.as_json({}) }
210
+ it "merges the attributes in params" do
211
+ expect(json[:custom_id]).to eq custom_attributes[:custom_id]
212
+ expect(json[:custom_name]).to eq custom_attributes[:custom_name]
213
+ end
214
+ end
201
215
 
202
- it { is_expected.to respond_to :as_json }
216
+ context "when attributes is not a hash" do
217
+ let(:json) { subject.as_json(nil) }
203
218
 
204
- it "returns correct values" do
205
- expect(json[:client_id]).to eq client_id
206
- expect(json[:redirect_uri]).to eq subject.redirect_uri
207
- expect(json[:state]).to eq subject.state
208
- expect(json[:response_type]).to eq subject.response_type
209
- expect(json[:scope]).to eq subject.scope
210
- expect(json[:client_name]).to eq client_name
211
- expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
219
+ include_examples "returns the pre authorization"
212
220
  end
213
221
  end
214
222
  end