search_spec.rb 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Search API' do
  4. context 'with token' do
  5. let(:user) { Fabricate(:user) }
  6. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
  7. let(:scopes) { 'read:search' }
  8. let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
  9. describe 'GET /api/v2/search' do
  10. let!(:bob) { Fabricate(:account, username: 'bob_test') }
  11. let!(:ana) { Fabricate(:account, username: 'ana_test') }
  12. let!(:tom) { Fabricate(:account, username: 'tom_test') }
  13. let(:params) { { q: 'test' } }
  14. it 'returns http success' do
  15. get '/api/v2/search', headers: headers, params: params
  16. expect(response).to have_http_status(200)
  17. expect(response.content_type)
  18. .to start_with('application/json')
  19. end
  20. context 'when searching accounts' do
  21. let(:params) { { q: 'test', type: 'accounts' } }
  22. it 'returns all matching accounts' do
  23. get '/api/v2/search', headers: headers, params: params
  24. expect(response.parsed_body[:accounts].pluck(:id)).to contain_exactly(bob.id.to_s, ana.id.to_s, tom.id.to_s)
  25. end
  26. context 'with truthy `resolve`' do
  27. let(:params) { { q: 'test1', resolve: '1' } }
  28. it 'returns http unauthorized' do
  29. get '/api/v2/search', headers: headers, params: params
  30. expect(response).to have_http_status(200)
  31. expect(response.content_type)
  32. .to start_with('application/json')
  33. end
  34. end
  35. context 'with valid `offset` value' do
  36. let(:params) { { q: 'test1', offset: 1 } }
  37. it 'returns http unauthorized' do
  38. get '/api/v2/search', headers: headers, params: params
  39. expect(response).to have_http_status(200)
  40. expect(response.content_type)
  41. .to start_with('application/json')
  42. end
  43. end
  44. context 'with negative `offset` value' do
  45. let(:params) { { q: 'test1', offset: '-100', type: 'accounts' } }
  46. it 'returns http bad_request' do
  47. get '/api/v2/search', headers: headers, params: params
  48. expect(response).to have_http_status(400)
  49. expect(response.content_type)
  50. .to start_with('application/json')
  51. end
  52. end
  53. context 'with negative `limit` value' do
  54. let(:params) { { q: 'test1', limit: '-100', type: 'accounts' } }
  55. it 'returns http bad_request' do
  56. get '/api/v2/search', headers: headers, params: params
  57. expect(response).to have_http_status(400)
  58. expect(response.content_type)
  59. .to start_with('application/json')
  60. end
  61. end
  62. context 'with following=true' do
  63. let(:params) { { q: 'test', type: 'accounts', following: 'true' } }
  64. before do
  65. user.account.follow!(ana)
  66. end
  67. it 'returns only the followed accounts' do
  68. get '/api/v2/search', headers: headers, params: params
  69. expect(response.parsed_body[:accounts].pluck(:id)).to contain_exactly(ana.id.to_s)
  70. end
  71. end
  72. end
  73. context 'when search raises syntax error' do
  74. before { allow(Search).to receive(:new).and_raise(Mastodon::SyntaxError) }
  75. it 'returns http unprocessable_entity' do
  76. get '/api/v2/search', headers: headers, params: params
  77. expect(response).to have_http_status(422)
  78. expect(response.content_type)
  79. .to start_with('application/json')
  80. end
  81. end
  82. context 'when search raises not found error' do
  83. before { allow(Search).to receive(:new).and_raise(ActiveRecord::RecordNotFound) }
  84. it 'returns http not_found' do
  85. get '/api/v2/search', headers: headers, params: params
  86. expect(response).to have_http_status(404)
  87. expect(response.content_type)
  88. .to start_with('application/json')
  89. end
  90. end
  91. end
  92. end
  93. context 'without token' do
  94. describe 'GET /api/v2/search' do
  95. let(:search_params) { nil }
  96. before do
  97. get '/api/v2/search', params: search_params
  98. end
  99. context 'without a `q` param' do
  100. it 'returns http bad_request' do
  101. expect(response).to have_http_status(400)
  102. expect(response.content_type)
  103. .to start_with('application/json')
  104. end
  105. end
  106. context 'with a `q` shorter than 5 characters' do
  107. let(:search_params) { { q: 'test' } }
  108. it 'returns http success' do
  109. expect(response).to have_http_status(200)
  110. expect(response.content_type)
  111. .to start_with('application/json')
  112. end
  113. end
  114. context 'with a `q` equal to or longer than 5 characters' do
  115. let(:search_params) { { q: 'test1' } }
  116. it 'returns http success' do
  117. expect(response).to have_http_status(200)
  118. expect(response.content_type)
  119. .to start_with('application/json')
  120. end
  121. context 'with truthy `resolve`' do
  122. let(:search_params) { { q: 'test1', resolve: '1' } }
  123. it 'returns http unauthorized' do
  124. expect(response).to have_http_status(401)
  125. expect(response.content_type)
  126. .to start_with('application/json')
  127. expect(response.body).to match('resolve remote resources')
  128. end
  129. end
  130. context 'with `offset`' do
  131. let(:search_params) { { q: 'test1', offset: 1 } }
  132. it 'returns http unauthorized' do
  133. expect(response).to have_http_status(401)
  134. expect(response.content_type)
  135. .to start_with('application/json')
  136. expect(response.body).to match('pagination is not supported')
  137. end
  138. end
  139. end
  140. end
  141. end
  142. end