Merge tag 'v2.6.0rc1' into instance_only_statuses

This commit is contained in:
Renato "Lond" Cerqueira
2018-10-23 08:32:55 +02:00
570 changed files with 11506 additions and 5693 deletions

View File

@ -3,8 +3,8 @@ require 'rails_helper'
RSpec.describe AccountsController, type: :controller do
render_views
let(:alice) { Fabricate(:account, username: 'alice') }
let(:eve) { Fabricate(:user) }
let(:alice) { Fabricate(:account, username: 'alice') }
let(:eve) { Fabricate(:user) }
describe 'GET #show' do
let!(:status1) { Status.create!(account: alice, text: 'Hello world') }

View File

@ -25,7 +25,7 @@ RSpec.describe Admin::AccountsController, type: :controller do
expect(h[:remote]).to eq '1'
expect(h[:by_domain]).to eq 'domain'
expect(h[:silenced]).to eq '1'
expect(h[:recent]).to eq '1'
expect(h[:alphabetic]).to eq '1'
expect(h[:suspended]).to eq '1'
expect(h[:username]).to eq 'username'
expect(h[:display_name]).to eq 'display name'
@ -40,7 +40,7 @@ RSpec.describe Admin::AccountsController, type: :controller do
remote: '1',
by_domain: 'domain',
silenced: '1',
recent: '1',
alphabetic: '1',
suspended: '1',
username: 'username',
display_name: 'display name',
@ -75,7 +75,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
end
end
describe 'POST #subscribe' do
subject { post :subscribe, params: { id: account.id } }

View File

@ -40,7 +40,7 @@ RSpec.describe Admin::EmailDomainBlocksController, type: :controller do
describe 'POST #create' do
it 'blocks the domain when succeeded to save' do
post :create, params: { email_domain_block: { domain: 'example.com'} }
post :create, params: { email_domain_block: { domain: 'example.com' } }
expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.created_msg')
expect(response).to redirect_to(admin_email_domain_blocks_path)
@ -50,7 +50,7 @@ RSpec.describe Admin::EmailDomainBlocksController, type: :controller do
describe 'DELETE #destroy' do
it 'unblocks the domain' do
email_domain_block = Fabricate(:email_domain_block)
delete :destroy, params: { id: email_domain_block.id }
delete :destroy, params: { id: email_domain_block.id }
expect(flash[:notice]).to eq I18n.t('admin.email_domain_blocks.destroyed_msg')
expect(response).to redirect_to(admin_email_domain_blocks_path)

View File

@ -24,7 +24,7 @@ describe Admin::InvitesController do
subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } }
it 'succeeds to create a invite' do
expect{ subject }.to change { Invite.count }.by(1)
expect { subject }.to change { Invite.count }.by(1)
expect(subject).to redirect_to admin_invites_path
expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10)
end

View File

@ -15,7 +15,6 @@ describe Admin::ReportNotesController do
let(:report) { Fabricate(:report, action_taken: action_taken, action_taken_by_account_id: account_id) }
context 'when parameter is valid' do
context 'when report is unsolved' do
let(:action_taken) { false }
let(:account_id) { nil }
@ -24,7 +23,7 @@ describe Admin::ReportNotesController do
let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_resolve: nil } }
it 'creates a report note and resolves report' do
expect{ subject }.to change{ ReportNote.count }.by(1)
expect { subject }.to change { ReportNote.count }.by(1)
expect(report.reload).to be_action_taken
expect(subject).to redirect_to admin_reports_path
end
@ -34,7 +33,7 @@ describe Admin::ReportNotesController do
let(:params) { { report_note: { content: 'test content', report_id: report.id } } }
it 'creates a report note and does not resolve report' do
expect{ subject }.to change{ ReportNote.count }.by(1)
expect { subject }.to change { ReportNote.count }.by(1)
expect(report.reload).not_to be_action_taken
expect(subject).to redirect_to admin_report_path(report)
end
@ -49,7 +48,7 @@ describe Admin::ReportNotesController do
let(:params) { { report_note: { content: 'test content', report_id: report.id }, create_and_unresolve: nil } }
it 'creates a report note and unresolves report' do
expect{ subject }.to change{ ReportNote.count }.by(1)
expect { subject }.to change { ReportNote.count }.by(1)
expect(report.reload).not_to be_action_taken
expect(subject).to redirect_to admin_report_path(report)
end
@ -59,7 +58,7 @@ describe Admin::ReportNotesController do
let(:params) { { report_note: { content: 'test content', report_id: report.id } } }
it 'creates a report note and does not unresolve report' do
expect{ subject }.to change{ ReportNote.count }.by(1)
expect { subject }.to change { ReportNote.count }.by(1)
expect(report.reload).to be_action_taken
expect(subject).to redirect_to admin_report_path(report)
end
@ -84,7 +83,7 @@ describe Admin::ReportNotesController do
let!(:report_note) { Fabricate(:report_note) }
it 'deletes note' do
expect{ subject }.to change{ ReportNote.count }.by(-1)
expect { subject }.to change { ReportNote.count }.by(-1)
expect(subject).to redirect_to admin_report_path(report_note.report)
end
end

View File

@ -13,7 +13,7 @@ describe Admin::ReportedStatusesController do
describe 'POST #create' do
subject do
-> { post :create, params: { :report_id => report, action => '', :form_status_batch => { status_ids: status_ids } } }
-> { post :create, params: { :report_id => report, action => '', :form_status_batch => { status_ids: status_ids } } }
end
let(:action) { 'nsfw_on' }

View File

@ -24,7 +24,7 @@ describe Admin::StatusesController do
end
it 'returns http success with media' do
get :index, params: { account_id: account.id , media: true }
get :index, params: { account_id: account.id, media: true }
statuses = assigns(:statuses).to_a
expect(statuses.size).to eq 1

View File

@ -15,7 +15,7 @@ RSpec.describe Api::SalmonController, type: :controller do
describe 'POST #update' do
context 'with valid post data' do
before do
post :update, params: { id: account.id }, body: File.read(File.join(Rails.root, 'spec', 'fixtures', 'salmon', 'mention.xml'))
post :update, params: { id: account.id }, body: File.read(Rails.root.join('spec', 'fixtures', 'salmon', 'mention.xml'))
end
it 'contains XML in the request body' do
@ -54,7 +54,7 @@ RSpec.describe Api::SalmonController, type: :controller do
service = double(call: false)
allow(VerifySalmonService).to receive(:new).and_return(service)
post :update, params: { id: account.id }, body: File.read(File.join(Rails.root, 'spec', 'fixtures', 'salmon', 'mention.xml'))
post :update, params: { id: account.id }, body: File.read(Rails.root.join('spec', 'fixtures', 'salmon', 'mention.xml'))
end
it 'returns http client error' do

View File

@ -33,7 +33,7 @@ RSpec.describe Api::SubscriptionsController, type: :controller do
end
describe 'POST #update' do
let(:feed) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'push', 'feed.atom')) }
let(:feed) { File.read(Rails.root.join('spec', 'fixtures', 'push', 'feed.atom')) }
before do
stub_request(:post, "https://quitter.no/main/push/hub").to_return(:status => 200, :body => "", :headers => {})

View File

@ -154,7 +154,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
before do
user.account.follow!(other_account)
post :mute, params: {id: other_account.id }
post :mute, params: { id: other_account.id }
end
it 'returns http success' do
@ -182,7 +182,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
before do
user.account.follow!(other_account)
post :mute, params: {id: other_account.id, notifications: false }
post :mute, params: { id: other_account.id, notifications: false }
end
it 'returns http success' do

View File

@ -0,0 +1,37 @@
require 'rails_helper'
RSpec.describe Api::V1::ConversationsController, type: :controller do
render_views
let!(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
let(:other) { Fabricate(:user, account: Fabricate(:account, username: 'bob')) }
before do
allow(controller).to receive(:doorkeeper_token) { token }
end
describe 'GET #index' do
let(:scopes) { 'read:statuses' }
before do
PostStatusService.new.call(other.account, 'Hey @alice', nil, visibility: 'direct')
end
it 'returns http success' do
get :index
expect(response).to have_http_status(200)
end
it 'returns pagination headers' do
get :index, params: { limit: 1 }
expect(response.headers['Link'].links.size).to eq(2)
end
it 'returns conversations' do
get :index
json = body_as_json
expect(json.size).to eq 1
end
end
end

View File

@ -64,7 +64,7 @@ RSpec.describe Api::V1::FavouritesController, type: :controller do
get :index, params: { limit: 1 }
expect(response.headers['Link'].find_link(['rel', 'next']).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}"
expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/favourites?limit=1&since_id=#{favourite.id}"
expect(response.headers['Link'].find_link(['rel', 'prev']).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}"
end
it 'does not add pagination headers if not necessary' do

View File

@ -12,16 +12,6 @@ RSpec.describe Api::V1::ReportsController, type: :controller do
allow(controller).to receive(:doorkeeper_token) { token }
end
describe 'GET #index' do
let(:scopes) { 'read:reports' }
it 'returns http success' do
get :index
expect(response).to have_http_status(200)
end
end
describe 'POST #create' do
let(:scopes) { 'write:reports' }
let!(:status) { Fabricate(:status) }

View File

@ -25,7 +25,6 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control
expect(response.headers['Link'].links.size).to eq(2)
end
end
end
context 'without an oauth token' do

View File

@ -31,7 +31,7 @@ describe Api::V1::StreamingController do
describe 'GET #index' do
it 'redirects to streaming host' do
get :index, params: {access_token: 'deadbeef', stream: 'public'}
get :index, params: { access_token: 'deadbeef', stream: 'public' }
expect(response).to have_http_status(301)
request_uri = URI.parse(request.url)
redirect_to_uri = URI.parse(response.location)
@ -42,5 +42,4 @@ describe Api::V1::StreamingController do
end
end
end
end

View File

@ -5,7 +5,7 @@ require 'rails_helper'
describe Api::V1::Timelines::HomeController do
render_views
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice'), current_sign_in_at: 1.day.ago) }
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice'), current_sign_in_at: 1.day.ago) }
before do
allow(controller).to receive(:doorkeeper_token) { token }

View File

@ -5,7 +5,7 @@ require 'rails_helper'
describe Api::V1::Timelines::PublicController do
render_views
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
let(:user) { Fabricate(:user, account: Fabricate(:account, username: 'alice')) }
before do
allow(controller).to receive(:doorkeeper_token) { token }

View File

@ -14,7 +14,7 @@ describe Api::Web::EmbedsController do
context 'when successfully finds status' do
let(:status) { Fabricate(:status) }
let(:url) { "http://#{ Rails.configuration.x.web_domain }/@#{status.account.username}/#{status.id}" }
let(:url) { "http://#{Rails.configuration.x.web_domain}/@#{status.account.username}/#{status.id}" }
it 'returns a right response' do
expect(response).to have_http_status :ok

View File

@ -94,7 +94,7 @@ describe ApplicationController, type: :controller do
describe 'helper_method :current_theme' do
it 'returns "default" when theme wasn\'t changed in admin settings' do
allow(Setting).to receive(:default_settings).and_return({'theme' => 'default'})
allow(Setting).to receive(:default_settings).and_return({ 'theme' => 'default' })
expect(controller.view_context.current_theme).to eq 'default'
end
@ -197,7 +197,7 @@ describe ApplicationController, type: :controller do
describe 'raise_not_found' do
it 'raises error' do
controller.params[:unmatched_route] = 'unmatched'
expect{ controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
expect { controller.raise_not_found }.to raise_error(ActionController::RoutingError, 'No route matches unmatched')
end
end

View File

@ -67,7 +67,7 @@ describe Auth::ConfirmationsController, type: :controller do
end
describe 'PATCH #finish_signup' do
subject { patch :finish_signup, params: { user: { email: email }} }
subject { patch :finish_signup, params: { user: { email: email } } }
let(:user) { Fabricate(:user) }
before do

View File

@ -30,6 +30,13 @@ RSpec.describe Auth::SessionsController, type: :controller do
expect(response).to redirect_to(new_user_session_path)
end
it 'does not delete redirect location with continue=true' do
sign_in(user, scope: :user)
controller.store_location_for(:user, '/authorize')
delete :destroy, params: { continue: 'true' }
expect(controller.stored_location_for(:user)).to eq '/authorize'
end
end
context 'with a suspended user' do
@ -48,7 +55,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
request.env['devise.mapping'] = Devise.mappings[:user]
end
context 'using PAM authentication' do
context 'using PAM authentication', if: ENV['PAM_ENABLED'] == 'true' do
context 'using a valid password' do
before do
post :create, params: { user: { email: "pam_user1", password: '123456' } }

View File

@ -8,6 +8,7 @@ describe ApplicationController, type: :controller do
def index
send_export_file
end
def export_data
@export.account.username
end

View File

@ -28,7 +28,7 @@ describe ApplicationController, type: :controller do
expect(I18n.locale).to eq :fa
end
it 'sets available and compatible langauge if none of available languages are preferred' do
it 'sets available and compatible language if none of available languages are preferred' do
request.headers['Accept-Language'] = 'fa-IR'
get 'success'
expect(I18n.locale).to eq :fa

View File

@ -73,6 +73,30 @@ describe ApplicationController, type: :controller do
end
end
context 'with request older than a day' do
before do
get :success
fake_request = Request.new(:get, request.url)
fake_request.add_headers({ 'Date' => 2.days.ago.utc.httpdate })
fake_request.on_behalf_of(author)
request.headers.merge!(fake_request.headers)
end
describe '#signed_request?' do
it 'returns true' do
expect(controller.signed_request?).to be true
end
end
describe '#signed_request_account' do
it 'returns nil' do
expect(controller.signed_request_account).to be_nil
end
end
end
context 'with body' do
before do
post :success, body: 'Hello world'

View File

@ -6,11 +6,11 @@ describe EmojisController do
let(:emoji) { Fabricate(:custom_emoji) }
describe 'GET #show' do
subject(:responce) { get :show, params: { id: emoji.id, format: :json } }
subject(:response) { get :show, params: { id: emoji.id, format: :json } }
subject(:body) { JSON.parse(response.body, symbolize_names: true) }
it 'returns the right response' do
expect(responce).to have_http_status 200
expect(response).to have_http_status 200
expect(body[:name]).to eq ':coolcat:'
end
end

View File

@ -43,7 +43,7 @@ describe InvitesController do
let(:user) { Fabricate(:user, moderator: false, admin: true) }
it 'succeeds to create a invite' do
expect{ subject }.to change { Invite.count }.by(1)
expect { subject }.to change { Invite.count }.by(1)
expect(subject).to redirect_to invites_path
expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10)
end

View File

@ -5,23 +5,25 @@ require 'rails_helper'
RSpec.describe Oauth::AuthorizationsController, type: :controller do
render_views
let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/') }
let(:app) { Doorkeeper::Application.create!(name: 'test', redirect_uri: 'http://localhost/', scopes: 'read') }
describe 'GET #new' do
subject do
get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/' }
get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/', scope: 'read' }
end
shared_examples 'stores location for user' do
it 'stores location for user' do
subject
expect(controller.stored_location_for(:user)).to eq "/oauth/authorize?client_id=#{app.uid}&redirect_uri=http%3A%2F%2Flocalhost%2F&response_type=code"
expect(controller.stored_location_for(:user)).to eq "/oauth/authorize?client_id=#{app.uid}&redirect_uri=http%3A%2F%2Flocalhost%2F&response_type=code&scope=read"
end
end
context 'when signed in' do
let!(:user) { Fabricate(:user) }
before do
sign_in Fabricate(:user), scope: :user
sign_in user, scope: :user
end
it 'returns http success' do
@ -35,6 +37,28 @@ RSpec.describe Oauth::AuthorizationsController, type: :controller do
end
include_examples 'stores location for user'
context 'when app is already authorized' do
before do
Doorkeeper::AccessToken.find_or_create_for(
app,
user.id,
app.scopes,
Doorkeeper.configuration.access_token_expires_in,
Doorkeeper.configuration.refresh_token_enabled?
)
end
it 'redirects to callback' do
subject
expect(response).to redirect_to(/\A#{app.redirect_uri}/)
end
it 'does not redirect to callback with force_login=true' do
get :new, params: { client_id: app.uid, response_type: 'code', redirect_uri: 'http://localhost/', scope: 'read', force_login: 'true' }
expect(response.body).to match(/Authorize/)
end
end
end
context 'when not signed in' do

View File

@ -14,11 +14,11 @@ describe RemoteUnfollowsController do
before do
sign_in current_user
current_account.follow!(remote_account)
stub_request(:post, 'http://example.com/inbox'){ { status: 200 } }
stub_request(:post, 'http://example.com/inbox') { { status: 200 } }
end
context 'when successfully unfollow remote account' do
let(:acct) {"acct:#{ remote_account.username }@#{ remote_account.domain }"}
let(:acct) { "acct:#{remote_account.username}@#{remote_account.domain}" }
it do
is_expected.to render_template :success
@ -27,7 +27,7 @@ describe RemoteUnfollowsController do
end
context 'when fails to unfollow remote account' do
let(:acct) {"acct:#{ remote_account.username + '_test' }@#{ remote_account.domain }"}
let(:acct) { "acct:#{remote_account.username + '_test'}@#{remote_account.domain}" }
it do
is_expected.to render_template :error

View File

@ -21,7 +21,6 @@ describe Settings::ApplicationsController do
end
end
describe 'GET #show' do
it 'returns http success' do
get :show, params: { id: app.id }
@ -48,13 +47,13 @@ describe Settings::ApplicationsController do
context 'success (passed scopes as a String)' do
def call_create
post :create, params: {
doorkeeper_application: {
name: 'My New App',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
website: 'http://google.com',
scopes: 'read write follow'
}
}
doorkeeper_application: {
name: 'My New App',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
website: 'http://google.com',
scopes: 'read write follow'
}
}
response
end
@ -70,13 +69,13 @@ describe Settings::ApplicationsController do
context 'success (passed scopes as an Array)' do
def call_create
post :create, params: {
doorkeeper_application: {
name: 'My New App',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
website: 'http://google.com',
scopes: [ 'read', 'write', 'follow' ]
}
}
doorkeeper_application: {
name: 'My New App',
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
website: 'http://google.com',
scopes: [ 'read', 'write', 'follow' ]
}
}
response
end
@ -92,13 +91,13 @@ describe Settings::ApplicationsController do
context 'failure' do
before do
post :create, params: {
doorkeeper_application: {
name: '',
redirect_uri: '',
website: '',
scopes: []
}
}
doorkeeper_application: {
name: '',
redirect_uri: '',
website: '',
scopes: []
}
}
end
it 'returns http success' do
@ -121,9 +120,9 @@ describe Settings::ApplicationsController do
def call_update
patch :update, params: {
id: app.id,
doorkeeper_application: opts
}
id: app.id,
doorkeeper_application: opts
}
response
end
@ -140,14 +139,14 @@ describe Settings::ApplicationsController do
context 'failure' do
before do
patch :update, params: {
id: app.id,
doorkeeper_application: {
name: '',
redirect_uri: '',
website: '',
scopes: []
}
}
id: app.id,
doorkeeper_application: {
name: '',
redirect_uri: '',
website: '',
scopes: []
}
}
end
it 'returns http success' do

View File

@ -10,7 +10,6 @@ describe Settings::MigrationsController do
end
describe 'GET #show' do
context 'when user is not sign in' do
subject { get :show }
@ -45,7 +44,6 @@ describe Settings::MigrationsController do
end
describe 'PUT #update' do
context 'when user is not sign in' do
subject { put :update }

View File

@ -50,7 +50,7 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do
describe 'when form_two_factor_confirmation parameter is not provided' do
it 'raises ActionController::ParameterMissing' do
expect { post :create, params: { } }.to raise_error(ActionController::ParameterMissing)
expect { post :create, params: {} }.to raise_error(ActionController::ParameterMissing)
end
end

View File

@ -4,7 +4,7 @@ RSpec.describe StreamEntriesController, type: :controller do
render_views
shared_examples 'before_action' do |route|
context 'when account is not suspended anbd stream_entry is available' do
context 'when account is not suspended and stream_entry is available' do
it 'assigns instance variables' do
status = Fabricate(:status)

View File

@ -6,5 +6,5 @@ Fabricator(:account) do
username { sequence(:username) { |i| "#{Faker::Internet.user_name(nil, %w(_))}#{i}" } }
last_webfingered_at { Time.now.utc }
public_key { public_key }
private_key { private_key}
private_key { private_key }
end

View File

@ -0,0 +1,6 @@
Fabricator(:conversation_account) do
account nil
conversation nil
participant_account_ids ""
last_status nil
end

View File

@ -1,4 +1,4 @@
Fabricator(:list) do
account
title "MyString"
title "MyString"
end

View File

@ -1,4 +1,4 @@
Fabricator(:relay) do
inbox_url "https://example.com/inbox"
state :idle
state :idle
end

View File

@ -1,3 +1,2 @@
Fabricator(:site_upload) do
end

View File

@ -2,5 +2,5 @@ Fabricator(:user) do
account
email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
password "123456789"
confirmed_at { Time.now }
confirmed_at { Time.zone.now }
end

View File

@ -3,7 +3,7 @@ require "rails_helper"
feature "Log in" do
given(:email) { "test@examle.com" }
given(:password) { "password" }
given(:confirmed_at) { Time.now }
given(:confirmed_at) { Time.zone.now }
background do
Fabricate(:user, email: email, password: password, confirmed_at: confirmed_at)

View File

@ -9,6 +9,14 @@ describe ApplicationHelper do
expect(result).to eq "active"
end
it 'returns active when on a current page' do
allow(helper).to receive(:current_page?).with('/foo').and_return(false)
allow(helper).to receive(:current_page?).with('/test').and_return(true)
result = helper.active_nav_class('/foo', '/test')
expect(result).to eq "active"
end
it 'returns empty string when not on current page' do
allow(helper).to receive(:current_page?).and_return(false)

View File

@ -105,6 +105,31 @@ RSpec.describe ActivityPub::Activity::Create do
end
end
context 'limited' do
let(:recipient) { Fabricate(:account) }
let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
to: ActivityPub::TagManager.instance.uri_for(recipient),
}
end
it 'creates status' do
status = sender.statuses.first
expect(status).to_not be_nil
expect(status.visibility).to eq 'limited'
end
it 'creates silent mention' do
status = sender.statuses.first
expect(status.mentions.first).to be_silent
end
end
context 'direct' do
let(:recipient) { Fabricate(:account) }
@ -114,6 +139,10 @@ RSpec.describe ActivityPub::Activity::Create do
type: 'Note',
content: 'Lorem ipsum',
to: ActivityPub::TagManager.instance.uri_for(recipient),
tag: {
type: 'Mention',
href: ActivityPub::TagManager.instance.uri_for(recipient),
},
}
end

View File

@ -393,7 +393,7 @@ RSpec.describe FeedManager do
end
it 'sends push updates' do
status = Fabricate(:status)
status = Fabricate(:status)
FeedManager.instance.push_to_home(receiver, status)

View File

@ -170,12 +170,11 @@ RSpec.describe Formatter do
end
end
describe '#format_spoiler' do
subject { Formatter.instance.format_spoiler(status) }
context 'given a post containing plain text' do
let(:status) { Fabricate(:status, text: 'text', spoiler_text: 'Secret!', uri: nil) }
let(:status) { Fabricate(:status, text: 'text', spoiler_text: 'Secret!', uri: nil) }
it 'Returns the spoiler text' do
is_expected.to eq 'Secret!'
@ -184,7 +183,7 @@ RSpec.describe Formatter do
context 'given a post with an emoji shortcode at the start' do
let!(:emoji) { Fabricate(:custom_emoji) }
let(:status) { Fabricate(:status, text: 'text', spoiler_text: ':coolcat: Secret!', uri: nil) }
let(:status) { Fabricate(:status, text: 'text', spoiler_text: ':coolcat: Secret!', uri: nil) }
let(:text) { ':coolcat: Beep boop' }
it 'converts the shortcode to an image tag' do
@ -207,7 +206,7 @@ RSpec.describe Formatter do
end
context 'given a post containing plain text' do
let(:status) { Fabricate(:status, text: 'text', uri: nil) }
let(:status) { Fabricate(:status, text: 'text', uri: nil) }
it 'paragraphizes the text' do
is_expected.to eq '<p>text</p>'
@ -215,7 +214,7 @@ RSpec.describe Formatter do
end
context 'given a post containing line feeds' do
let(:status) { Fabricate(:status, text: "line\nfeed", uri: nil) }
let(:status) { Fabricate(:status, text: "line\nfeed", uri: nil) }
it 'removes line feeds' do
is_expected.not_to include "\n"
@ -367,7 +366,7 @@ RSpec.describe Formatter do
subject { Formatter.instance.plaintext(status) }
context 'given a post with local status' do
let(:status) { Fabricate(:status, text: '<p>a text by a nerd who uses an HTML tag in text</p>', uri: nil) }
let(:status) { Fabricate(:status, text: '<p>a text by a nerd who uses an HTML tag in text</p>', uri: nil) }
it 'returns the raw text' do
is_expected.to eq '<p>a text by a nerd who uses an HTML tag in text</p>'
@ -375,7 +374,7 @@ RSpec.describe Formatter do
end
context 'given a post with remote status' do
let(:status) { Fabricate(:status, account: remote_account, text: '<script>alert("Hello")</script>') }
let(:status) { Fabricate(:status, account: remote_account, text: '<script>alert("Hello")</script>') }
it 'returns tag-stripped text' do
is_expected.to eq ''

View File

@ -42,6 +42,7 @@ describe LanguageDetector do
describe 'detect' do
let(:account_without_user_locale) { Fabricate(:user, locale: nil).account }
let(:account_remote) { Fabricate(:account, domain: 'joinmastodon.org') }
it 'detects english language for basic strings' do
strings = [
@ -90,7 +91,7 @@ describe LanguageDetector do
end
it 'uses nil when account is present but has no locale' do
result = described_class.instance.detect('', account_without_user_locale)
result = described_class.instance.detect('', account_without_user_locale)
expect(result).to eq nil
end
@ -104,6 +105,15 @@ describe LanguageDetector do
end
end
describe 'remote user' do
it 'nil for foreign user when language is not present' do
string = '안녕하세요'
result = described_class.instance.detect(string, account_remote)
expect(result).to eq nil
end
end
describe 'with a non-`en` default locale' do
around(:each) do |example|
before = I18n.default_locale

View File

@ -728,9 +728,9 @@ RSpec.describe OStatus::AtomSerializer do
it 'appends id element with unique tag' do
block = Fabricate(:block)
time_before = Time.now
time_before = Time.zone.now
block_salmon = OStatus::AtomSerializer.new.block_salmon(block)
time_after = Time.now
time_after = Time.zone.now
expect(block_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, block.id, 'Block'))
@ -815,9 +815,9 @@ RSpec.describe OStatus::AtomSerializer do
it 'appends id element with unique tag' do
block = Fabricate(:block)
time_before = Time.now
time_before = Time.zone.now
unblock_salmon = OStatus::AtomSerializer.new.unblock_salmon(block)
time_after = Time.now
time_after = Time.zone.now
expect(unblock_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, block.id, 'Block'))
@ -880,7 +880,7 @@ RSpec.describe OStatus::AtomSerializer do
ProcessInteractionService.new.call(envelope, block.target_account)
expect{ block.reload }.to raise_error ActiveRecord::RecordNotFound
expect { block.reload }.to raise_error ActiveRecord::RecordNotFound
end
end
@ -994,9 +994,9 @@ RSpec.describe OStatus::AtomSerializer do
it 'appends id element with unique tag' do
favourite = Fabricate(:favourite)
time_before = Time.now
time_before = Time.zone.now
unfavourite_salmon = OStatus::AtomSerializer.new.unfavourite_salmon(favourite)
time_after = Time.now
time_after = Time.zone.now
expect(unfavourite_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, favourite.id, 'Favourite'))
@ -1179,9 +1179,9 @@ RSpec.describe OStatus::AtomSerializer do
follow = Fabricate(:follow)
follow.destroy!
time_before = Time.now
time_before = Time.zone.now
unfollow_salmon = OStatus::AtomSerializer.new.unfollow_salmon(follow)
time_after = Time.now
time_after = Time.zone.now
expect(unfollow_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow.id, 'Follow'))
@ -1327,9 +1327,9 @@ RSpec.describe OStatus::AtomSerializer do
it 'appends id element with unique tag' do
follow_request = Fabricate(:follow_request)
time_before = Time.now
time_before = Time.zone.now
authorize_follow_request_salmon = OStatus::AtomSerializer.new.authorize_follow_request_salmon(follow_request)
time_after = Time.now
time_after = Time.zone.now
expect(authorize_follow_request_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow_request.id, 'FollowRequest'))
@ -1396,9 +1396,9 @@ RSpec.describe OStatus::AtomSerializer do
it 'appends id element with unique tag' do
follow_request = Fabricate(:follow_request)
time_before = Time.now
time_before = Time.zone.now
reject_follow_request_salmon = OStatus::AtomSerializer.new.reject_follow_request_salmon(follow_request)
time_after = Time.now
time_after = Time.zone.now
expect(reject_follow_request_salmon.id.text).to(
eq(OStatus::TagManager.instance.unique_tag(time_before.utc, follow_request.id, 'FollowRequest'))

View File

@ -84,7 +84,7 @@ describe Request do
allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM)
.and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
.and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:db8::face"], :PF_INET6, :SOCK_STREAM))
expect{ subject.perform }.to raise_error Mastodon::ValidationError
expect { subject.perform }.to raise_error Mastodon::ValidationError
end
end
end

View File

@ -0,0 +1,72 @@
require 'rails_helper'
RSpec.describe AccountConversation, type: :model do
let!(:alice) { Fabricate(:account, username: 'alice') }
let!(:bob) { Fabricate(:account, username: 'bob') }
let!(:mark) { Fabricate(:account, username: 'mark') }
describe '.add_status' do
it 'creates new record when no others exist' do
status = Fabricate(:status, account: alice, visibility: :direct)
status.mentions.create(account: bob)
conversation = AccountConversation.add_status(alice, status)
expect(conversation.participant_accounts).to include(bob)
expect(conversation.last_status).to eq status
expect(conversation.status_ids).to eq [status.id]
end
it 'appends to old record when there is a match' do
last_status = Fabricate(:status, account: alice, visibility: :direct)
conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status)
status.mentions.create(account: alice)
new_conversation = AccountConversation.add_status(alice, status)
expect(new_conversation.id).to eq conversation.id
expect(new_conversation.participant_accounts).to include(bob)
expect(new_conversation.last_status).to eq status
expect(new_conversation.status_ids).to eq [last_status.id, status.id]
end
it 'creates new record when new participants are added' do
last_status = Fabricate(:status, account: alice, visibility: :direct)
conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
status = Fabricate(:status, account: bob, visibility: :direct, thread: last_status)
status.mentions.create(account: alice)
status.mentions.create(account: mark)
new_conversation = AccountConversation.add_status(alice, status)
expect(new_conversation.id).to_not eq conversation.id
expect(new_conversation.participant_accounts).to include(bob, mark)
expect(new_conversation.last_status).to eq status
expect(new_conversation.status_ids).to eq [status.id]
end
end
describe '.remove_status' do
it 'updates last status to a previous value' do
last_status = Fabricate(:status, account: alice, visibility: :direct)
status = Fabricate(:status, account: alice, visibility: :direct)
conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [status.id, last_status.id])
last_status.mentions.create(account: bob)
last_status.destroy!
conversation.reload
expect(conversation.last_status).to eq status
expect(conversation.status_ids).to eq [status.id]
end
it 'removes the record if no other statuses are referenced' do
last_status = Fabricate(:status, account: alice, visibility: :direct)
conversation = AccountConversation.create!(account: alice, conversation: last_status.conversation, participant_account_ids: [bob.id], status_ids: [last_status.id])
last_status.mentions.create(account: bob)
last_status.destroy!
expect(AccountConversation.where(id: conversation.id).count).to eq 0
end
end
end

View File

@ -2,10 +2,10 @@ require 'rails_helper'
describe AccountFilter do
describe 'with empty params' do
it 'defaults to alphabetic account list' do
it 'defaults to recent account list' do
filter = described_class.new({})
expect(filter.results).to eq Account.alphabetic
expect(filter.results).to eq Account.recent
end
end
@ -60,7 +60,7 @@ describe AccountFilter do
end
describe 'that call account methods' do
%i(local remote silenced recent suspended).each do |option|
%i(local remote silenced alphabetic suspended).each do |option|
it "delegates the #{option} option" do
allow(Account).to receive(option).and_return(Account.none)
filter = described_class.new({ option => true })

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe AccountModerationNote, type: :model do
end

View File

@ -275,7 +275,7 @@ RSpec.describe Account, type: :model do
subject { Fabricate(:account) }
context 'when the status is a reblog of another status'do
context 'when the status is a reblog of another status' do
let(:original_reblog) do
author = Fabricate(:account, username: 'original_reblogger')
Fabricate(:status, reblog: original_status, account: author)
@ -559,7 +559,7 @@ RSpec.describe Account, type: :model do
end
context 'when is local' do
it 'is invalid if the username is not unique in case-insensitive comparsion among local accounts' do
it 'is invalid if the username is not unique in case-insensitive comparison among local accounts' do
account_1 = Fabricate(:account, username: 'the_doctor')
account_2 = Fabricate.build(:account, username: 'the_Doctor')
account_2.valid?

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe Admin::ActionLog, type: :model do
end

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe Backup, type: :model do
end

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe ConversationMute, type: :model do
end

View File

@ -4,7 +4,7 @@ RSpec.describe CustomEmoji, type: :model do
describe '#search' do
let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: shortcode) }
subject { described_class.search(search_term) }
subject { described_class.search(search_term) }
context 'shortcode is exact' do
let(:shortcode) { 'blobpats' }

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe CustomFilter, type: :model do
end

View File

@ -23,6 +23,20 @@ RSpec.describe Follow, type: :model do
follow.valid?
expect(follow).to model_have_error_on_field(:target_account)
end
it 'is invalid if account already follows too many people' do
alice.update(following_count: FollowLimitValidator::LIMIT)
expect(subject).to_not be_valid
expect(subject).to model_have_error_on_field(:base)
end
it 'is valid if account is only on the brink of following too many people' do
alice.update(following_count: FollowLimitValidator::LIMIT - 1)
expect(subject).to be_valid
expect(subject).to_not model_have_error_on_field(:base)
end
end
describe 'recent' do

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe ListAccount, type: :model do
end

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe List, type: :model do
end

View File

@ -131,7 +131,7 @@ RSpec.describe MediaAttachment, type: :model do
expect(media.file.meta["original"]["aspect"]).to eq 1.5
expect(media.file.meta["small"]["width"]).to eq 490
expect(media.file.meta["small"]["height"]).to eq 327
expect(media.file.meta["small"]["aspect"]).to eq 490.0/327
expect(media.file.meta["small"]["aspect"]).to eq 490.0 / 327
end
end

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe Mute, type: :model do
end

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe PreviewCard, type: :model do
end

View File

@ -34,7 +34,7 @@ RSpec.describe RemoteFollow do
subject { remote_follow.valid? }
context 'attrs with acct' do
let(:attrs) { { acct: 'gargron@quitter.no' }}
let(:attrs) { { acct: 'gargron@quitter.no' } }
it do
is_expected.to be true
@ -42,7 +42,7 @@ RSpec.describe RemoteFollow do
end
context 'attrs without acct' do
let(:attrs) { { } }
let(:attrs) { {} }
it do
is_expected.to be false

View File

@ -154,7 +154,7 @@ RSpec.describe Status, type: :model do
describe '#target' do
it 'returns nil if the status is self-contained' do
expect(subject.target).to be_nil
expect(subject.target).to be_nil
end
it 'returns nil if the status is a reply' do

View File

@ -18,7 +18,7 @@ RSpec.describe Subscription, type: :model do
end
describe 'lease_seconds' do
it 'returns the time remaing until expiration' do
it 'returns the time remaining until expiration' do
datetime = 1.day.from_now
subscription = Subscription.new(expires_at: datetime)
travel_to(datetime - 12.hours) do

View File

@ -67,7 +67,7 @@ RSpec.describe User, type: :model do
describe 'confirmed' do
it 'returns an array of users who are confirmed' do
user_1 = Fabricate(:user, confirmed_at: nil)
user_2 = Fabricate(:user, confirmed_at: Time.now)
user_2 = Fabricate(:user, confirmed_at: Time.zone.now)
expect(User.confirmed).to match_array([user_2])
end
end
@ -254,7 +254,7 @@ RSpec.describe User, type: :model do
it_behaves_like 'Settings-extended' do
def create!
User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234' )
User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234')
end
def fabricate

View File

@ -1,5 +1,4 @@
require 'rails_helper'
RSpec.describe Web::Setting, type: :model do
end

View File

@ -29,6 +29,7 @@ Devise::Test::ControllerHelpers.module_eval do
value: resource.activate_session(warden.request),
expires: 1.year.from_now,
httponly: true,
same_site: :lax,
}
end
end
@ -71,11 +72,11 @@ RSpec::Sidekiq.configure do |config|
end
def request_fixture(name)
File.read(File.join(Rails.root, 'spec', 'fixtures', 'requests', name))
File.read(Rails.root.join('spec', 'fixtures', 'requests', name))
end
def attachment_fixture(name)
File.open(File.join(Rails.root, 'spec', 'fixtures', 'files', name))
File.open(Rails.root.join('spec', 'fixtures', 'files', name))
end
def stub_jsonld_contexts!

View File

@ -34,7 +34,7 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
end
it 'processes payload with actor if valid signature exists' do
payload['signature'] = {'type' => 'RsaSignature2017'}
payload['signature'] = { 'type' => 'RsaSignature2017' }
expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(actor)
expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), actor, instance_of(Hash))
@ -43,7 +43,7 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
end
it 'does not process payload if invalid signature exists' do
payload['signature'] = {'type' => 'RsaSignature2017'}
payload['signature'] = { 'type' => 'RsaSignature2017' }
expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(nil)
expect(ActivityPub::Activity).not_to receive(:factory)

View File

@ -19,7 +19,7 @@ RSpec.describe BatchedRemoveStatusService, type: :service do
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
Fabricate(:subscription, account: alice, callback_url: 'http://example.com/push', confirmed: true, expires_at: 30.days.from_now)
jeff.user.update(current_sign_in_at: Time.now)
jeff.user.update(current_sign_in_at: Time.zone.now)
jeff.follow!(alice)
hank.follow!(alice)

View File

@ -57,7 +57,7 @@ RSpec.describe FetchAtomService, type: :service do
context 'content type is application/atom+xml' do
let(:content_type) { 'application/atom+xml' }
it { is_expected.to eq [url, {:prefetched_body=>""}, :ostatus] }
it { is_expected.to eq [url, { :prefetched_body => "" }, :ostatus] }
end
context 'content_type is json' do

View File

@ -19,7 +19,7 @@ RSpec.describe FetchRemoteAccountService, type: :service do
end
let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
let(:xml) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'xml', 'mastodon.atom')) }
let(:xml) { File.read(Rails.root.join('spec', 'fixtures', 'xml', 'mastodon.atom')) }
shared_examples 'return Account' do
it { is_expected.to be_an Account }

View File

@ -4,7 +4,7 @@ RSpec.describe ProcessFeedService, type: :service do
subject { ProcessFeedService.new }
describe 'processing a feed' do
let(:body) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'xml', 'mastodon.atom')) }
let(:body) { File.read(Rails.root.join('spec', 'fixtures', 'xml', 'mastodon.atom')) }
let(:account) { Fabricate(:account, username: 'localhost', domain: 'kickass.zone') }
before do
@ -166,7 +166,7 @@ XML
expect(created_statuses.first.reblog.text).to eq 'Overwatch rocks'
end
it 'ignores reblogs if it failed to retreive reblogged statuses' do
it 'ignores reblogs if it failed to retrieve reblogged statuses' do
stub_request(:get, 'https://overwatch.com/users/tracer/updates/1').to_return(status: 404)
actor = Fabricate(:account, username: 'tracer', domain: 'overwatch.com')

View File

@ -1,7 +1,7 @@
require 'rails_helper'
RSpec.describe UpdateRemoteProfileService, type: :service do
let(:xml) { File.read(File.join(Rails.root, 'spec', 'fixtures', 'push', 'feed.atom')) }
let(:xml) { File.read(Rails.root.join('spec', 'fixtures', 'push', 'feed.atom')) }
subject { UpdateRemoteProfileService.new }

View File

@ -0,0 +1,109 @@
require 'rails_helper'
RSpec.describe VerifyLinkService, type: :service do
subject { described_class.new }
context 'given a local account' do
let(:account) { Fabricate(:account, username: 'alice') }
let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') }
before do
stub_request(:head, 'https://redirect.me/abc').to_return(status: 301, headers: { 'Location' => ActivityPub::TagManager.instance.url_for(account) })
stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
subject.call(field)
end
context 'when a link contains an <a> back' do
let(:html) do
<<-HTML
<!doctype html>
<body>
<a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me">Follow me on Mastodon</a>
</body>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
context 'when a link contains an <a rel="noopener"> back' do
let(:html) do
<<-HTML
<!doctype html>
<body>
<a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="noopener me" target="_blank">Follow me on Mastodon</a>
</body>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
context 'when a link contains a <link> back' do
let(:html) do
<<-HTML
<!doctype html>
<head>
<link type="text/html" href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me" />
</head>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
context 'when a link goes through a redirect back' do
let(:html) do
<<-HTML
<!doctype html>
<head>
<link type="text/html" href="https://redirect.me/abc" rel="me" />
</head>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
context 'when a link does not contain a link back' do
let(:html) { '' }
it 'marks the field as verified' do
expect(field.verified?).to be false
end
end
end
context 'given a remote account' do
let(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', url: 'https://profile.example.com/alice') }
let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => '<a href="http://example.com" rel="me"><span class="invisible">http://</span><span class="">example.com</span><span class="invisible"></span></a>') }
before do
stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
subject.call(field)
end
context 'when a link contains an <a> back' do
let(:html) do
<<-HTML
<!doctype html>
<body>
<a href="https://profile.example.com/alice" rel="me">Follow me on Mastodon</a>
</body>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
end
end

View File

@ -18,6 +18,7 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
open_registrations: false,
thumbnail: nil,
hero: nil,
mascot: nil,
user_count: 0,
status_count: 0,
contact_account: nil,

View File

@ -49,8 +49,8 @@ describe 'stream_entries/show.html.haml', without_verify_partial_doubles: true d
assign(:stream_entry, reply.stream_entry)
assign(:account, alice)
assign(:type, reply.stream_entry.activity_type.downcase)
assign(:ancestors, reply.stream_entry.activity.ancestors(1, bob) )
assign(:descendant_threads, [{ statuses: reply.stream_entry.activity.descendants(1)}])
assign(:ancestors, reply.stream_entry.activity.ancestors(1, bob))
assign(:descendant_threads, [{ statuses: reply.stream_entry.activity.descendants(1) }])
render