lists_spec.rb 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. # frozen_string_literal: true
  2. require 'rails_helper'
  3. RSpec.describe 'Lists' do
  4. let(:user) { Fabricate(:user) }
  5. let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
  6. let(:scopes) { 'read:lists write:lists' }
  7. let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
  8. describe 'GET /api/v1/lists' do
  9. subject do
  10. get '/api/v1/lists', headers: headers
  11. end
  12. let!(:lists) do
  13. [
  14. Fabricate(:list, account: user.account, title: 'first list', replies_policy: :followed),
  15. Fabricate(:list, account: user.account, title: 'second list', replies_policy: :list),
  16. Fabricate(:list, account: user.account, title: 'third list', replies_policy: :none),
  17. Fabricate(:list, account: user.account, title: 'fourth list', exclusive: true),
  18. ]
  19. end
  20. let(:expected_response) do
  21. lists.map do |list|
  22. {
  23. id: list.id.to_s,
  24. title: list.title,
  25. replies_policy: list.replies_policy,
  26. exclusive: list.exclusive,
  27. }
  28. end
  29. end
  30. before do
  31. Fabricate(:list)
  32. end
  33. it_behaves_like 'forbidden for wrong scope', 'write write:lists'
  34. it 'returns the expected lists', :aggregate_failures do
  35. subject
  36. expect(response).to have_http_status(200)
  37. expect(response.content_type)
  38. .to start_with('application/json')
  39. expect(response.parsed_body).to match_array(expected_response)
  40. end
  41. end
  42. describe 'GET /api/v1/lists/:id' do
  43. subject do
  44. get "/api/v1/lists/#{list.id}", headers: headers
  45. end
  46. let(:list) { Fabricate(:list, account: user.account) }
  47. it_behaves_like 'forbidden for wrong scope', 'write write:lists'
  48. it 'returns the requested list correctly', :aggregate_failures do
  49. subject
  50. expect(response).to have_http_status(200)
  51. expect(response.content_type)
  52. .to start_with('application/json')
  53. expect(response.parsed_body).to match({
  54. id: list.id.to_s,
  55. title: list.title,
  56. replies_policy: list.replies_policy,
  57. exclusive: list.exclusive,
  58. })
  59. end
  60. context 'when the list belongs to a different user' do
  61. let(:list) { Fabricate(:list) }
  62. it 'returns http not found' do
  63. subject
  64. expect(response).to have_http_status(404)
  65. expect(response.content_type)
  66. .to start_with('application/json')
  67. end
  68. end
  69. context 'when the list does not exist' do
  70. it 'returns http not found' do
  71. get '/api/v1/lists/-1', headers: headers
  72. expect(response).to have_http_status(404)
  73. expect(response.content_type)
  74. .to start_with('application/json')
  75. end
  76. end
  77. end
  78. describe 'POST /api/v1/lists' do
  79. subject do
  80. post '/api/v1/lists', headers: headers, params: params
  81. end
  82. let(:params) { { title: 'my list', replies_policy: 'none', exclusive: 'true' } }
  83. it_behaves_like 'forbidden for wrong scope', 'read read:lists'
  84. it 'returns the new list', :aggregate_failures do
  85. subject
  86. expect(response).to have_http_status(200)
  87. expect(response.content_type)
  88. .to start_with('application/json')
  89. expect(response.parsed_body).to match(a_hash_including(title: 'my list', replies_policy: 'none', exclusive: true))
  90. expect(List.where(account: user.account).count).to eq(1)
  91. end
  92. context 'when a title is not given' do
  93. let(:params) { { title: '' } }
  94. it 'returns http unprocessable entity' do
  95. subject
  96. expect(response).to have_http_status(422)
  97. expect(response.content_type)
  98. .to start_with('application/json')
  99. end
  100. end
  101. context 'when the given replies_policy is invalid' do
  102. let(:params) { { title: 'a list', replies_policy: 'whatever' } }
  103. it 'returns http unprocessable entity' do
  104. subject
  105. expect(response).to have_http_status(422)
  106. expect(response.content_type)
  107. .to start_with('application/json')
  108. end
  109. end
  110. end
  111. describe 'PUT /api/v1/lists/:id' do
  112. subject do
  113. put "/api/v1/lists/#{list.id}", headers: headers, params: params
  114. end
  115. let(:list) { Fabricate(:list, account: user.account, title: 'my list') }
  116. let(:params) { { title: 'list', replies_policy: 'followed', exclusive: 'true' } }
  117. it_behaves_like 'forbidden for wrong scope', 'read read:lists'
  118. it 'returns the updated list and updates values', :aggregate_failures do
  119. expect { subject }
  120. .to change_list_title
  121. .and change_list_replies_policy
  122. .and change_list_exclusive
  123. expect(response).to have_http_status(200)
  124. expect(response.content_type)
  125. .to start_with('application/json')
  126. list.reload
  127. expect(response.parsed_body).to match({
  128. id: list.id.to_s,
  129. title: list.title,
  130. replies_policy: list.replies_policy,
  131. exclusive: list.exclusive,
  132. })
  133. end
  134. def change_list_title
  135. change { list.reload.title }.from('my list').to('list')
  136. end
  137. def change_list_replies_policy
  138. change { list.reload.replies_policy }.from('list').to('followed')
  139. end
  140. def change_list_exclusive
  141. change { list.reload.exclusive }.from(false).to(true)
  142. end
  143. context 'when the list does not exist' do
  144. it 'returns http not found' do
  145. put '/api/v1/lists/-1', headers: headers, params: params
  146. expect(response).to have_http_status(404)
  147. expect(response.content_type)
  148. .to start_with('application/json')
  149. end
  150. end
  151. context 'when the list belongs to another user' do
  152. let(:list) { Fabricate(:list) }
  153. it 'returns http not found' do
  154. subject
  155. expect(response).to have_http_status(404)
  156. expect(response.content_type)
  157. .to start_with('application/json')
  158. end
  159. end
  160. end
  161. describe 'DELETE /api/v1/lists/:id' do
  162. subject do
  163. delete "/api/v1/lists/#{list.id}", headers: headers
  164. end
  165. let(:list) { Fabricate(:list, account: user.account) }
  166. it_behaves_like 'forbidden for wrong scope', 'read read:lists'
  167. it 'deletes the list', :aggregate_failures do
  168. subject
  169. expect(response).to have_http_status(200)
  170. expect(response.content_type)
  171. .to start_with('application/json')
  172. expect(List.where(id: list.id)).to_not exist
  173. end
  174. context 'when the list does not exist' do
  175. it 'returns http not found' do
  176. delete '/api/v1/lists/-1', headers: headers
  177. expect(response).to have_http_status(404)
  178. end
  179. end
  180. context 'when the list belongs to another user' do
  181. let(:list) { Fabricate(:list) }
  182. it 'returns http not found' do
  183. subject
  184. expect(response).to have_http_status(404)
  185. expect(response.content_type)
  186. .to start_with('application/json')
  187. end
  188. end
  189. end
  190. end