apps_spec.rb 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Apps' do
  4. describe 'POST /api/v1/apps' do
  5. subject do
  6. post '/api/v1/apps', params: params
  7. end
  8. let(:client_name) { 'Test app' }
  9. let(:scopes) { 'read write' }
  10. let(:redirect_uri) { 'urn:ietf:wg:oauth:2.0:oob' }
  11. let(:redirect_uris) { [redirect_uri] }
  12. let(:website) { nil }
  13. let(:params) do
  14. {
  15. client_name: client_name,
  16. redirect_uris: redirect_uris,
  17. scopes: scopes,
  18. website: website,
  19. }
  20. end
  21. context 'with valid params' do
  22. it 'creates an OAuth app', :aggregate_failures do
  23. subject
  24. expect(response).to have_http_status(200)
  25. app = Doorkeeper::Application.find_by(name: client_name)
  26. expect(app).to be_present
  27. expect(app.scopes.to_s).to eq scopes
  28. expect(app.redirect_uris).to eq redirect_uris
  29. expect(body_as_json).to match(
  30. a_hash_including(
  31. id: app.id.to_s,
  32. client_id: app.uid,
  33. client_secret: app.secret,
  34. name: client_name,
  35. website: website,
  36. scopes: ['read', 'write'],
  37. redirect_uris: redirect_uris,
  38. # Deprecated properties as of 4.3:
  39. redirect_uri: redirect_uri,
  40. vapid_key: Rails.configuration.x.vapid_public_key
  41. )
  42. )
  43. end
  44. end
  45. context 'without scopes being supplied' do
  46. let(:scopes) { nil }
  47. it 'creates an OAuth App with the default scope' do
  48. subject
  49. expect(response).to have_http_status(200)
  50. expect(Doorkeeper::Application.find_by(name: client_name)).to be_present
  51. body = body_as_json
  52. expect(body[:scopes]).to eq Doorkeeper.config.default_scopes.to_a
  53. end
  54. end
  55. # FIXME: This is a bug: https://github.com/mastodon/mastodon/issues/30152
  56. context 'with scopes as an array' do
  57. let(:scopes) { %w(read write follow) }
  58. it 'creates an OAuth App with the default scope' do
  59. subject
  60. expect(response).to have_http_status(200)
  61. app = Doorkeeper::Application.find_by(name: client_name)
  62. expect(app).to be_present
  63. expect(app.scopes.to_s).to eq 'read'
  64. body = body_as_json
  65. expect(body[:scopes]).to eq ['read']
  66. end
  67. end
  68. context 'with an unsupported scope' do
  69. let(:scopes) { 'hoge' }
  70. it 'returns http unprocessable entity' do
  71. subject
  72. expect(response).to have_http_status(422)
  73. end
  74. end
  75. context 'with many duplicate scopes' do
  76. let(:scopes) { (%w(read) * 40).join(' ') }
  77. it 'only saves the scope once', :aggregate_failures do
  78. subject
  79. expect(response).to have_http_status(200)
  80. expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read'
  81. end
  82. end
  83. context 'with a too-long name' do
  84. let(:client_name) { 'hoge' * 20 }
  85. it 'returns http unprocessable entity' do
  86. subject
  87. expect(response).to have_http_status(422)
  88. end
  89. end
  90. context 'with a too-long website' do
  91. let(:website) { "https://foo.bar/#{'hoge' * 2_000}" }
  92. it 'returns http unprocessable entity' do
  93. subject
  94. expect(response).to have_http_status(422)
  95. end
  96. end
  97. context 'with a too-long redirect_uri' do
  98. let(:redirect_uris) { "https://app.example/#{'hoge' * 2_000}" }
  99. it 'returns http unprocessable entity' do
  100. subject
  101. expect(response).to have_http_status(422)
  102. end
  103. end
  104. # NOTE: This spec currently tests the same as the "with a too-long redirect_uri test case"
  105. context 'with too many redirect_uris' do
  106. let(:redirect_uris) { (0...500).map { |i| "https://app.example/#{i}/callback" } }
  107. it 'returns http unprocessable entity' do
  108. subject
  109. expect(response).to have_http_status(422)
  110. end
  111. end
  112. context 'with multiple redirect_uris as a string' do
  113. let(:redirect_uris) { "https://redirect1.example/\napp://redirect2.example/" }
  114. it 'creates an OAuth application with multiple redirect URIs' do
  115. subject
  116. expect(response).to have_http_status(200)
  117. app = Doorkeeper::Application.find_by(name: client_name)
  118. expect(app).to be_present
  119. expect(app.redirect_uri).to eq redirect_uris
  120. expect(app.redirect_uris).to eq redirect_uris.split
  121. body = body_as_json
  122. expect(body[:redirect_uri]).to eq redirect_uris
  123. expect(body[:redirect_uris]).to eq redirect_uris.split
  124. end
  125. end
  126. context 'with multiple redirect_uris as an array' do
  127. let(:redirect_uris) { ['https://redirect1.example/', 'app://redirect2.example/'] }
  128. it 'creates an OAuth application with multiple redirect URIs' do
  129. subject
  130. expect(response).to have_http_status(200)
  131. app = Doorkeeper::Application.find_by(name: client_name)
  132. expect(app).to be_present
  133. expect(app.redirect_uri).to eq redirect_uris.join "\n"
  134. expect(app.redirect_uris).to eq redirect_uris
  135. body = body_as_json
  136. expect(body[:redirect_uri]).to eq redirect_uris.join "\n"
  137. expect(body[:redirect_uris]).to eq redirect_uris
  138. end
  139. end
  140. context 'with an empty redirect_uris array' do
  141. let(:redirect_uris) { [] }
  142. it 'returns http unprocessable entity' do
  143. subject
  144. expect(response).to have_http_status(422)
  145. end
  146. end
  147. context 'with just a newline as the redirect_uris string' do
  148. let(:redirect_uris) { "\n" }
  149. it 'returns http unprocessable entity' do
  150. subject
  151. expect(response).to have_http_status(422)
  152. end
  153. end
  154. context 'with an empty redirect_uris string' do
  155. let(:redirect_uris) { '' }
  156. it 'returns http unprocessable entity' do
  157. subject
  158. expect(response).to have_http_status(422)
  159. end
  160. end
  161. context 'without a required param' do
  162. let(:client_name) { '' }
  163. it 'returns http unprocessable entity' do
  164. subject
  165. expect(response).to have_http_status(422)
  166. end
  167. end
  168. context 'with a website' do
  169. let(:website) { 'https://app.example/' }
  170. it 'creates an OAuth application with the website specified' do
  171. subject
  172. expect(response).to have_http_status(200)
  173. app = Doorkeeper::Application.find_by(name: client_name)
  174. expect(app).to be_present
  175. expect(app.website).to eq website
  176. end
  177. end
  178. end
  179. end