D spec/controllers/api/v1/timelines/home_controller_spec.rb => spec/controllers/api/v1/timelines/home_controller_spec.rb +0 -44
@@ 1,44 0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Timelines::HomeController do
- render_views
-
- let(:user) { Fabricate(:user, current_sign_in_at: 1.day.ago) }
-
- before do
- allow(controller).to receive(:doorkeeper_token) { token }
- end
-
- context 'with a user context' do
- let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
-
- describe 'GET #show' do
- before do
- follow = Fabricate(:follow, account: user.account)
- PostStatusService.new.call(follow.target_account, text: 'New status for user home timeline.')
- end
-
- it 'returns http success' do
- get :show
-
- expect(response).to have_http_status(200)
- expect(response.headers['Link'].links.size).to eq(2)
- end
- end
- end
-
- context 'without a user context' do
- let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: 'read') }
-
- describe 'GET #show' do
- it 'returns http unprocessable entity' do
- get :show
-
- expect(response).to have_http_status(422)
- expect(response.headers['Link']).to be_nil
- end
- end
- end
-end
A spec/requests/api/v1/timelines/home_spec.rb => spec/requests/api/v1/timelines/home_spec.rb +101 -0
@@ 0,0 1,101 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Home' do
+ let(:user) { Fabricate(:user) }
+ let(:scopes) { 'read:statuses' }
+ let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
+ let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
+
+ describe 'GET /api/v1/timelines/home' do
+ subject do
+ get '/api/v1/timelines/home', headers: headers, params: params
+ end
+
+ let(:params) { {} }
+
+ it_behaves_like 'forbidden for wrong scope', 'write write:statuses'
+
+ context 'when the timeline is available' do
+ let(:home_statuses) { bob.statuses + ana.statuses }
+ let!(:bob) { Fabricate(:account) }
+ let!(:tim) { Fabricate(:account) }
+ let!(:ana) { Fabricate(:account) }
+
+ before do
+ user.account.follow!(bob)
+ user.account.follow!(ana)
+ PostStatusService.new.call(bob, text: 'New toot from bob.')
+ PostStatusService.new.call(tim, text: 'New toot from tim.')
+ PostStatusService.new.call(ana, text: 'New toot from ana.')
+ end
+
+ it 'returns http success' do
+ subject
+
+ expect(response).to have_http_status(200)
+ end
+
+ it 'returns the statuses of followed users' do
+ subject
+
+ expect(body_as_json.pluck(:id)).to match_array(home_statuses.map { |status| status.id.to_s })
+ end
+
+ context 'with limit param' do
+ let(:params) { { limit: 1 } }
+
+ it 'returns only the requested number of statuses' do
+ subject
+
+ expect(body_as_json.size).to eq(params[:limit])
+ end
+
+ it 'sets the correct pagination headers', :aggregate_failures do
+ subject
+
+ headers = response.headers['Link']
+
+ expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_timelines_home_url(limit: 1, min_id: ana.statuses.first.id.to_s))
+ expect(headers.find_link(%w(rel next)).href).to eq(api_v1_timelines_home_url(limit: 1, max_id: ana.statuses.first.id.to_s))
+ end
+ end
+ end
+
+ context 'when the timeline is regenerating' do
+ let(:timeline) { instance_double(HomeFeed, regenerating?: true, get: []) }
+
+ before do
+ allow(HomeFeed).to receive(:new).and_return(timeline)
+ end
+
+ it 'returns http partial content' do
+ subject
+
+ expect(response).to have_http_status(206)
+ end
+ end
+
+ context 'without an authorization header' do
+ let(:headers) { {} }
+
+ it 'returns http unauthorized' do
+ subject
+
+ expect(response).to have_http_status(401)
+ end
+ end
+
+ context 'without a user context' do
+ let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: scopes) }
+
+ it 'returns http unprocessable entity', :aggregate_failures do
+ subject
+
+ expect(response).to have_http_status(422)
+ expect(response.headers['Link']).to be_nil
+ end
+ end
+ end
+end