Merge branch 'master' into skylight
This commit is contained in:
commit
47910f57da
|
@ -63,3 +63,7 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||
|
||||
# Streaming API integration
|
||||
# STREAMING_API_BASE_URL=
|
||||
|
||||
# Advanced settings
|
||||
# If you need to use pgBouncer, you need to disable prepared statements:
|
||||
# PREPARED_STATEMENTS=false
|
||||
|
|
|
@ -25,7 +25,7 @@ const ClearColumnButton = React.createClass({
|
|||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<div title={intl.formatMessage(messages.clear)} className='column-icon' tabIndex='0' style={iconStyle} onClick={this.onClick}>
|
||||
<div title={intl.formatMessage(messages.clear)} className='column-icon' tabIndex='0' style={iconStyle} onClick={this.props.onClick}>
|
||||
<i className='fa fa-eraser' />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -14,6 +14,7 @@ const fr = {
|
|||
"status.show_less": "Replier",
|
||||
"status.open": "Déplier ce status",
|
||||
"status.report": "Signaler @{name}",
|
||||
"status.load_more": "Charger plus",
|
||||
"video_player.toggle_sound": "Mettre/Couper le son",
|
||||
"account.mention": "Mentionner",
|
||||
"account.edit_profile": "Modifier le profil",
|
||||
|
@ -41,6 +42,7 @@ const fr = {
|
|||
"column.notifications": "Notifications",
|
||||
"column.blocks": "Utilisateurs bloqués",
|
||||
"column.favourites": "Favoris",
|
||||
"empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres utilisateurs⋅trices pour débuter la conversation.",
|
||||
"tabs_bar.compose": "Composer",
|
||||
"tabs_bar.home": "Accueil",
|
||||
"tabs_bar.mentions": "Mentions",
|
||||
|
|
|
@ -714,7 +714,15 @@ a.status__content__spoiler-link {
|
|||
|
||||
@media screen and (min-width: 360px) {
|
||||
.columns-area {
|
||||
margin: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.column:first-child, .drawer:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.column:last-child, .drawer:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -816,6 +824,7 @@ a.status__content__spoiler-link {
|
|||
}
|
||||
|
||||
.column, .drawer {
|
||||
margin: 10px;
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
flex: 0 0 auto;
|
||||
|
@ -823,11 +832,11 @@ a.status__content__spoiler-link {
|
|||
}
|
||||
|
||||
.column:first-child, .drawer:first-child {
|
||||
margin-left: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.column:last-child, .drawer:last-child {
|
||||
margin-right: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
|
@ -885,6 +894,10 @@ a.status__content__spoiler-link {
|
|||
}
|
||||
|
||||
@media screen and (min-width: 360px) {
|
||||
.columns-area {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.tabs-bar {
|
||||
margin: 10px;
|
||||
margin-bottom: 0;
|
||||
|
@ -895,6 +908,12 @@ a.status__content__spoiler-link {
|
|||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
.columns-area {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.tabs-bar__link {
|
||||
.fa {
|
||||
|
|
|
@ -2,30 +2,25 @@
|
|||
|
||||
class AboutController < ApplicationController
|
||||
before_action :set_body_classes
|
||||
before_action :set_instance_presenter, only: [:show, :more]
|
||||
|
||||
def index
|
||||
@description = Setting.site_description
|
||||
@open_registrations = Setting.open_registrations
|
||||
@closed_registrations_message = Setting.closed_registrations_message
|
||||
def show; end
|
||||
|
||||
@user = User.new
|
||||
@user.build_account
|
||||
end
|
||||
|
||||
def more
|
||||
@description = Setting.site_description
|
||||
@extended_description = Setting.site_extended_description
|
||||
@contact_account = Account.find_local(Setting.site_contact_username)
|
||||
@contact_email = Setting.site_contact_email
|
||||
@user_count = Rails.cache.fetch('user_count') { User.count }
|
||||
@status_count = Rails.cache.fetch('local_status_count') { Status.local.count }
|
||||
@domain_count = Rails.cache.fetch('distinct_domain_count') { Account.distinct.count(:domain) }
|
||||
end
|
||||
def more; end
|
||||
|
||||
def terms; end
|
||||
|
||||
private
|
||||
|
||||
def new_user
|
||||
User.new.tap(&:build_account)
|
||||
end
|
||||
helper_method :new_user
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'about-body'
|
||||
end
|
||||
|
|
|
@ -20,10 +20,8 @@ class Api::V1::AccountsController < ApiController
|
|||
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.target_account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = following_api_v1_account_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = following_api_v1_account_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = following_api_v1_account_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = following_api_v1_account_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -35,10 +33,8 @@ class Api::V1::AccountsController < ApiController
|
|||
accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = followers_api_v1_account_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = followers_api_v1_account_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = followers_api_v1_account_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = followers_api_v1_account_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -52,11 +48,9 @@ class Api::V1::AccountsController < ApiController
|
|||
@statuses = cache_collection(@statuses, Status)
|
||||
|
||||
set_maps(@statuses)
|
||||
# set_counters_maps(@statuses)
|
||||
# set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
|
||||
|
||||
next_path = statuses_api_v1_account_url(max_id: @statuses.last.id) unless @statuses.empty?
|
||||
prev_path = statuses_api_v1_account_url(since_id: @statuses.first.id) unless @statuses.empty?
|
||||
next_path = statuses_api_v1_account_url(statuses_pagination_params(max_id: @statuses.last.id)) unless @statuses.empty?
|
||||
prev_path = statuses_api_v1_account_url(statuses_pagination_params(since_id: @statuses.first.id)) unless @statuses.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
@ -117,8 +111,6 @@ class Api::V1::AccountsController < ApiController
|
|||
def search
|
||||
@accounts = AccountSearchService.new.call(params[:q], limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:resolve] == 'true', current_account)
|
||||
|
||||
# set_account_counters_maps(@accounts) unless @accounts.nil?
|
||||
|
||||
render action: :index
|
||||
end
|
||||
|
||||
|
@ -135,4 +127,12 @@ class Api::V1::AccountsController < ApiController
|
|||
@muting = Account.muting_map([@account.id], current_user.account_id)
|
||||
@requested = Account.requested_map([@account.id], current_user.account_id)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def statuses_pagination_params(core_params)
|
||||
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,11 +11,15 @@ class Api::V1::BlocksController < ApiController
|
|||
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.target_account_id] }.compact
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = api_v1_blocks_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = api_v1_blocks_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = api_v1_blocks_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = api_v1_blocks_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,11 +11,16 @@ class Api::V1::FavouritesController < ApiController
|
|||
@statuses = cache_collection(Status.where(id: results.map(&:status_id)), Status)
|
||||
|
||||
set_maps(@statuses)
|
||||
# set_counters_maps(@statuses)
|
||||
|
||||
next_path = api_v1_favourites_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_STATUSES_LIMIT)
|
||||
prev_path = api_v1_favourites_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = api_v1_favourites_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_STATUSES_LIMIT)
|
||||
prev_path = api_v1_favourites_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,10 +9,8 @@ class Api::V1::FollowRequestsController < ApiController
|
|||
accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = api_v1_follow_requests_url(max_id: results.last.id) if results.size == DEFAULT_ACCOUNTS_LIMIT
|
||||
prev_path = api_v1_follow_requests_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = api_v1_follow_requests_url(pagination_params(max_id: results.last.id)) if results.size == DEFAULT_ACCOUNTS_LIMIT
|
||||
prev_path = api_v1_follow_requests_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
@ -26,4 +24,10 @@ class Api::V1::FollowRequestsController < ApiController
|
|||
RejectFollowService.new.call(Account.find(params[:id]), current_account)
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,11 +11,15 @@ class Api::V1::MutesController < ApiController
|
|||
accounts = Account.where(id: results.map(&:target_account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.target_account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = api_v1_mutes_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = api_v1_mutes_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = api_v1_mutes_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = api_v1_mutes_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,11 +14,9 @@ class Api::V1::NotificationsController < ApiController
|
|||
statuses = @notifications.select { |n| !n.target_status.nil? }.map(&:target_status)
|
||||
|
||||
set_maps(statuses)
|
||||
# set_counters_maps(statuses)
|
||||
# set_account_counters_maps(@notifications.map(&:from_account))
|
||||
|
||||
next_path = api_v1_notifications_url(max_id: @notifications.last.id) unless @notifications.empty?
|
||||
prev_path = api_v1_notifications_url(since_id: @notifications.first.id) unless @notifications.empty?
|
||||
next_path = api_v1_notifications_url(pagination_params(max_id: @notifications.last.id)) unless @notifications.empty?
|
||||
prev_path = api_v1_notifications_url(pagination_params(since_id: @notifications.first.id)) unless @notifications.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
@ -31,4 +29,10 @@ class Api::V1::NotificationsController < ApiController
|
|||
Notification.where(account: current_account).delete_all
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,7 +23,6 @@ class Api::V1::StatusesController < ApiController
|
|||
statuses = [@status] + @context[:ancestors] + @context[:descendants]
|
||||
|
||||
set_maps(statuses)
|
||||
# set_counters_maps(statuses)
|
||||
end
|
||||
|
||||
def card
|
||||
|
@ -36,10 +35,8 @@ class Api::V1::StatusesController < ApiController
|
|||
accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |r| accounts[r.account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = reblogged_by_api_v1_status_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = reblogged_by_api_v1_status_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = reblogged_by_api_v1_status_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = reblogged_by_api_v1_status_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -51,10 +48,8 @@ class Api::V1::StatusesController < ApiController
|
|||
accounts = Account.where(id: results.map(&:account_id)).map { |a| [a.id, a] }.to_h
|
||||
@accounts = results.map { |f| accounts[f.account_id] }
|
||||
|
||||
# set_account_counters_maps(@accounts)
|
||||
|
||||
next_path = favourited_by_api_v1_status_url(max_id: results.last.id) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = favourited_by_api_v1_status_url(since_id: results.first.id) unless results.empty?
|
||||
next_path = favourited_by_api_v1_status_url(pagination_params(max_id: results.last.id)) if results.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
prev_path = favourited_by_api_v1_status_url(pagination_params(since_id: results.first.id)) unless results.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -115,4 +110,8 @@ class Api::V1::StatusesController < ApiController
|
|||
def status_params
|
||||
params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: [])
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::TimelinesController < ApiController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!, only: [:home, :mentions]
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:home]
|
||||
before_action :require_user!, only: [:home]
|
||||
|
||||
respond_to :json
|
||||
|
||||
|
@ -11,11 +11,9 @@ class Api::V1::TimelinesController < ApiController
|
|||
@statuses = cache_collection(@statuses)
|
||||
|
||||
set_maps(@statuses)
|
||||
# set_counters_maps(@statuses)
|
||||
# set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
|
||||
|
||||
next_path = api_v1_home_timeline_url(max_id: @statuses.last.id) unless @statuses.empty?
|
||||
prev_path = api_v1_home_timeline_url(since_id: @statuses.first.id) unless @statuses.empty?
|
||||
next_path = api_v1_home_timeline_url(pagination_params(max_id: @statuses.last.id)) unless @statuses.empty?
|
||||
prev_path = api_v1_home_timeline_url(pagination_params(since_id: @statuses.first.id)) unless @statuses.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -27,11 +25,9 @@ class Api::V1::TimelinesController < ApiController
|
|||
@statuses = cache_collection(@statuses)
|
||||
|
||||
set_maps(@statuses)
|
||||
# set_counters_maps(@statuses)
|
||||
# set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
|
||||
|
||||
next_path = api_v1_public_timeline_url(max_id: @statuses.last.id) unless @statuses.empty?
|
||||
prev_path = api_v1_public_timeline_url(since_id: @statuses.first.id) unless @statuses.empty?
|
||||
next_path = api_v1_public_timeline_url(pagination_params(max_id: @statuses.last.id)) unless @statuses.empty?
|
||||
prev_path = api_v1_public_timeline_url(pagination_params(since_id: @statuses.first.id)) unless @statuses.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -44,11 +40,9 @@ class Api::V1::TimelinesController < ApiController
|
|||
@statuses = cache_collection(@statuses)
|
||||
|
||||
set_maps(@statuses)
|
||||
# set_counters_maps(@statuses)
|
||||
# set_account_counters_maps(@statuses.flat_map { |s| [s.account, s.reblog? ? s.reblog.account : nil] }.compact.uniq)
|
||||
|
||||
next_path = api_v1_hashtag_timeline_url(params[:id], max_id: @statuses.last.id) unless @statuses.empty?
|
||||
prev_path = api_v1_hashtag_timeline_url(params[:id], since_id: @statuses.first.id) unless @statuses.empty?
|
||||
next_path = api_v1_hashtag_timeline_url(params[:id], pagination_params(max_id: @statuses.last.id)) unless @statuses.empty?
|
||||
prev_path = api_v1_hashtag_timeline_url(params[:id], pagination_params(since_id: @statuses.first.id)) unless @statuses.empty?
|
||||
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
|
||||
|
@ -60,4 +54,8 @@ class Api::V1::TimelinesController < ApiController
|
|||
def cache_collection(raw)
|
||||
super(raw, Status)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:local, :limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -203,7 +203,7 @@ class Account < ApplicationRecord
|
|||
end
|
||||
|
||||
def triadic_closures(account, limit = 5)
|
||||
sql = <<SQL
|
||||
sql = <<-SQL.squish
|
||||
WITH first_degree AS (
|
||||
SELECT target_account_id
|
||||
FROM follows
|
||||
|
@ -216,7 +216,7 @@ class Account < ApplicationRecord
|
|||
GROUP BY target_account_id, accounts.id
|
||||
ORDER BY count(account_id) DESC
|
||||
LIMIT ?
|
||||
SQL
|
||||
SQL
|
||||
|
||||
Account.find_by_sql([sql, account.id, account.id, limit])
|
||||
end
|
||||
|
@ -226,7 +226,7 @@ SQL
|
|||
textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
|
||||
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
|
||||
|
||||
sql = <<SQL
|
||||
sql = <<-SQL.squish
|
||||
SELECT
|
||||
accounts.*,
|
||||
ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
|
||||
|
@ -234,7 +234,7 @@ SQL
|
|||
WHERE #{query} @@ #{textsearch}
|
||||
ORDER BY rank DESC
|
||||
LIMIT ?
|
||||
SQL
|
||||
SQL
|
||||
|
||||
Account.find_by_sql([sql, limit])
|
||||
end
|
||||
|
@ -244,7 +244,7 @@ SQL
|
|||
textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
|
||||
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
|
||||
|
||||
sql = <<SQL
|
||||
sql = <<-SQL.squish
|
||||
SELECT
|
||||
accounts.*,
|
||||
(count(f.id) + 1) * ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
|
||||
|
@ -254,7 +254,7 @@ SQL
|
|||
GROUP BY accounts.id
|
||||
ORDER BY rank DESC
|
||||
LIMIT ?
|
||||
SQL
|
||||
SQL
|
||||
|
||||
Account.find_by_sql([sql, account.id, account.id, limit])
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ class Tag < ApplicationRecord
|
|||
textsearch = 'to_tsvector(\'simple\', tags.name)'
|
||||
query = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
|
||||
|
||||
sql = <<SQL
|
||||
sql = <<-SQL.squish
|
||||
SELECT
|
||||
tags.*,
|
||||
ts_rank_cd(#{textsearch}, #{query}) AS rank
|
||||
|
@ -25,7 +25,7 @@ class Tag < ApplicationRecord
|
|||
WHERE #{query} @@ #{textsearch}
|
||||
ORDER BY rank DESC
|
||||
LIMIT ?
|
||||
SQL
|
||||
SQL
|
||||
|
||||
Tag.find_by_sql([sql, limit])
|
||||
end
|
||||
|
|
28
app/presenters/instance_presenter.rb
Normal file
28
app/presenters/instance_presenter.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class InstancePresenter
|
||||
delegate(
|
||||
:closed_registrations_message,
|
||||
:contact_email,
|
||||
:open_registrations,
|
||||
:site_description,
|
||||
:site_extended_description,
|
||||
to: Setting
|
||||
)
|
||||
|
||||
def contact_account
|
||||
Account.find_local(Setting.site_contact_username)
|
||||
end
|
||||
|
||||
def user_count
|
||||
Rails.cache.fetch('user_count') { User.count }
|
||||
end
|
||||
|
||||
def status_count
|
||||
Rails.cache.fetch('local_status_count') { Status.local.count }
|
||||
end
|
||||
|
||||
def domain_count
|
||||
Rails.cache.fetch('distinct_domain_count') { Account.distinct.count(:domain) }
|
||||
end
|
||||
end
|
30
app/views/about/_registration.html.haml
Normal file
30
app/views/about/_registration.html.haml
Normal file
|
@ -0,0 +1,30 @@
|
|||
= simple_form_for(new_user, url: user_registration_path) do |f|
|
||||
= f.simple_fields_for :account do |account_fields|
|
||||
= account_fields.input :username,
|
||||
autofocus: true,
|
||||
placeholder: t('simple_form.labels.defaults.username'),
|
||||
required: true,
|
||||
input_html: { 'aria-label' => t('simple_form.labels.defaults.username') }
|
||||
|
||||
= f.input :email,
|
||||
placeholder: t('simple_form.labels.defaults.email'),
|
||||
required: true,
|
||||
input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
|
||||
= f.input :password,
|
||||
autocomplete: "off",
|
||||
placeholder: t('simple_form.labels.defaults.password'),
|
||||
required: true,
|
||||
input_html: { 'aria-label' => t('simple_form.labels.defaults.password') }
|
||||
= f.input :password_confirmation,
|
||||
autocomplete: "off",
|
||||
placeholder: t('simple_form.labels.defaults.confirm_password'),
|
||||
required: true,
|
||||
input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password') }
|
||||
|
||||
.actions
|
||||
= f.button :button, t('about.get_started'), type: :submit
|
||||
|
||||
.info
|
||||
= link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
|
||||
·
|
||||
= link_to t('about.about_this'), about_more_path
|
|
@ -7,42 +7,42 @@
|
|||
.panel
|
||||
%h2= Rails.configuration.x.local_domain
|
||||
|
||||
- unless @description.blank?
|
||||
%p= @description.html_safe
|
||||
- unless @instance_presenter.site_description.blank?
|
||||
%p= @instance_presenter.site_description.html_safe
|
||||
|
||||
.information-board
|
||||
.section
|
||||
%span= t 'about.user_count_before'
|
||||
%strong= number_with_delimiter @user_count
|
||||
%strong= number_with_delimiter @instance_presenter.user_count
|
||||
%span= t 'about.user_count_after'
|
||||
.section
|
||||
%span= t 'about.status_count_before'
|
||||
%strong= number_with_delimiter @status_count
|
||||
%strong= number_with_delimiter @instance_presenter.status_count
|
||||
%span= t 'about.status_count_after'
|
||||
.section
|
||||
%span= t 'about.domain_count_before'
|
||||
%strong= number_with_delimiter @domain_count
|
||||
%strong= number_with_delimiter @instance_presenter.domain_count
|
||||
%span= t 'about.domain_count_after'
|
||||
|
||||
- unless @extended_description.blank?
|
||||
.panel= @extended_description.html_safe
|
||||
- unless @instance_presenter.site_extended_description.blank?
|
||||
.panel= @instance_presenter.site_extended_description.html_safe
|
||||
|
||||
.sidebar
|
||||
.panel
|
||||
.panel-header= t 'about.contact'
|
||||
.panel-body
|
||||
- if @contact_account
|
||||
- if @instance_presenter.contact_account
|
||||
.owner
|
||||
.avatar= image_tag @contact_account.avatar.url
|
||||
.avatar= image_tag @instance_presenter.contact_account.avatar.url
|
||||
.name
|
||||
= link_to TagManager.instance.url_for(@contact_account) do
|
||||
%span.display_name.emojify= display_name(@contact_account)
|
||||
%span.username= "@#{@contact_account.acct}"
|
||||
= link_to TagManager.instance.url_for(@instance_presenter.contact_account) do
|
||||
%span.display_name.emojify= display_name(@instance_presenter.contact_account)
|
||||
%span.username= "@#{@instance_presenter.contact_account.acct}"
|
||||
|
||||
- unless @contact_email.blank?
|
||||
- unless @instance_presenter.contact_email.blank?
|
||||
.contact-email
|
||||
= t 'about.business_email'
|
||||
%strong= @contact_email
|
||||
%strong= @instance_presenter.contact_email
|
||||
.panel
|
||||
.panel-header= t 'about.links'
|
||||
.panel-list
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
%meta{ property: 'og:site_name', content: site_title }/
|
||||
%meta{ property: 'og:type', content: 'website' }/
|
||||
%meta{ property: 'og:title', content: Rails.configuration.x.local_domain }/
|
||||
%meta{ property: 'og:description', content: @description.blank? ? "Mastodon is a free, open-source social network server. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly" : strip_tags(@description) }/
|
||||
%meta{ property: 'og:description', content: strip_tags(@instance_presenter.site_description.blank? ? t('about.about_mastodon') : @instance_presenter.site_description) }/
|
||||
%meta{ property: 'og:image', content: asset_url('mastodon_small.jpg') }/
|
||||
%meta{ property: 'og:image:width', content: '400' }/
|
||||
%meta{ property: 'og:image:height', content: '400' }/
|
||||
|
@ -24,28 +24,14 @@
|
|||
.screenshot-with-signup
|
||||
.mascot= image_tag 'fluffy-elephant-friend.png'
|
||||
|
||||
- if @open_registrations
|
||||
= simple_form_for(@user, url: user_registration_path) do |f|
|
||||
= f.simple_fields_for :account do |ff|
|
||||
= ff.input :username, autofocus: true, placeholder: t('simple_form.labels.defaults.username'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username') }
|
||||
|
||||
= f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
|
||||
= f.input :password, autocomplete: "off", placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password') }
|
||||
= f.input :password_confirmation, autocomplete: "off", placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password') }
|
||||
|
||||
.actions
|
||||
= f.button :button, t('about.get_started'), type: :submit
|
||||
|
||||
.info
|
||||
= link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
|
||||
·
|
||||
= link_to t('about.about_this'), about_more_path
|
||||
- if @instance_presenter.open_registrations
|
||||
= render 'registration'
|
||||
- else
|
||||
.closed-registrations-message
|
||||
- if @closed_registrations_message.blank?
|
||||
- if @instance_presenter.closed_registrations_message.blank?
|
||||
%p= t('about.closed_registrations')
|
||||
- else
|
||||
= @closed_registrations_message.html_safe
|
||||
= @instance_presenter.closed_registrations_message.html_safe
|
||||
.info
|
||||
= link_to t('auth.login'), new_user_session_path, class: 'webapp-btn'
|
||||
·
|
||||
|
@ -85,9 +71,9 @@
|
|||
= fa_icon('li check-square')
|
||||
= t 'about.features.api'
|
||||
|
||||
- unless @description.blank?
|
||||
- unless @instance_presenter.site_description.blank?
|
||||
%h3= t('about.description_headline', domain: Rails.configuration.x.local_domain)
|
||||
%p= @description.html_safe
|
||||
%p= @instance_presenter.site_description.html_safe
|
||||
|
||||
.actions
|
||||
.info
|
|
@ -1,5 +1,5 @@
|
|||
<p>Bienvenue <%= @resource.email %> !</p>
|
||||
|
||||
<p>Vous pouvez confirmer l'email de votre compte Mastodon en cliquant sur le lien ci-dessous :</p>
|
||||
<p>Vous pouvez confirmer le courriel de votre compte Mastodon en cliquant sur le lien ci-dessous :</p>
|
||||
|
||||
<p><%= link_to 'Confirmer mon compte', confirmation_url(@resource, confirmation_token: @token) %></p>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Bienvenue <%= @resource.email %> !
|
||||
|
||||
Vous pouvez confirmer l'email de votre compte Mastodon en cliquant sur le lien ci-dessous :
|
||||
Vous pouvez confirmer le courriel de votre compte Mastodon en cliquant sur le lien ci-dessous :
|
||||
|
||||
<%= confirmation_url(@resource, confirmation_token: @token) %>
|
||||
|
|
|
@ -22,4 +22,4 @@ production:
|
|||
password: <%= ENV['DB_PASS'] || '' %>
|
||||
host: <%= ENV['DB_HOST'] || 'localhost' %>
|
||||
port: <%= ENV['DB_PORT'] || 5432 %>
|
||||
prepared_statements: false
|
||||
prepared_statements: <%= ENV['PREPARED_STATEMENTS'] || 'true' %>
|
||||
|
|
|
@ -38,9 +38,9 @@ Rails.application.configure do
|
|||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
config.force_ssl = false
|
||||
|
||||
# Use the lowest log level to ensure availability of diagnostic information
|
||||
# By default, use the lowest log level to ensure availability of diagnostic information
|
||||
# when problems arise.
|
||||
config.log_level = :debug
|
||||
config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'debug').to_sym
|
||||
|
||||
# Prepend all log lines with the following tags.
|
||||
config.log_tags = [:request_id]
|
||||
|
|
|
@ -58,4 +58,4 @@ fr:
|
|||
not_locked: n'était pas verrouillé(e)
|
||||
not_saved:
|
||||
one: '1 erreur a empêché ce(tte) %{resource} d''être sauvegardé(e) :'
|
||||
other: '%{count} erreurs ont empêché ce(tte) %{resource} d''être sauvegardé(e): '
|
||||
other: '%{count} erreurs ont empêché ce(tte) %{resource} d''être sauvegardé(e) : '
|
||||
|
|
|
@ -23,11 +23,11 @@ fr:
|
|||
edit: Modifier
|
||||
submit: Envoyer
|
||||
confirmations:
|
||||
destroy: Êtes-vous certain?
|
||||
destroy: Êtes-vous certain ?
|
||||
edit:
|
||||
title: Modifier l'application
|
||||
form:
|
||||
error: Oups! Vérifier votre formulaire pour des erreurs possibles
|
||||
error: Oups ! Vérifier votre formulaire pour des erreurs possibles
|
||||
help:
|
||||
native_redirect_uri: Utiliser %{native_redirect_uri} pour les tests locaux
|
||||
redirect_uri: Utiliser une ligne par URL
|
||||
|
@ -54,7 +54,7 @@ fr:
|
|||
title: Une erreur est survenue
|
||||
new:
|
||||
able_to: Cette application pourra
|
||||
prompt: Autoriser %{client_name} à utiliser votre compte?
|
||||
prompt: Autoriser %{client_name} à utiliser votre compte ?
|
||||
title: Autorisation requise
|
||||
show:
|
||||
title: Code d'autorisation
|
||||
|
@ -109,5 +109,5 @@ fr:
|
|||
title: Autorisation OAuth requise
|
||||
scopes:
|
||||
follow: s’abonner, se désabonner, bloquer, et débloquer des comptes
|
||||
read: lire les données de votre compte
|
||||
read: lire les données de votre compte
|
||||
write: poster en tant que vous
|
||||
|
|
|
@ -4,7 +4,7 @@ fr:
|
|||
about_mastodon: Mastodon est un serveur <em>libre</em> de réseautage social. Alternative <em>décentralisée</em> aux plateformes commerciales, la monopolisation de vos communications par une entreprise unique est évitée. Tout un chacun peut faire tourner Mastodon et participer au <em>réseau social</em> de manière transparente.
|
||||
about_this: À propos de cette instance
|
||||
apps: Applications
|
||||
business_email: E-mail professionnel
|
||||
business_email: Courriel professionnel
|
||||
closed_registrations: Les inscriptions sont actuellement fermées sur cette instance.
|
||||
contact: Contact
|
||||
description_headline: Qu'est-ce que %{domain} ?
|
||||
|
@ -40,9 +40,9 @@ fr:
|
|||
remote_follow: Suivre à distance
|
||||
unfollow: Ne plus suivre
|
||||
application_mailer:
|
||||
settings: 'Changer les préférences e-mail: ${link}'
|
||||
settings: 'Changer les préférences courriel : ${link}'
|
||||
signature: Notifications de Mastodon depuis %{instance}
|
||||
view: 'Voir:'
|
||||
view: 'Voir :'
|
||||
applications:
|
||||
invalid_url: L'URL fournie est invalide
|
||||
auth:
|
||||
|
@ -58,21 +58,27 @@ fr:
|
|||
authorize_follow:
|
||||
error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant
|
||||
follow: Suivre
|
||||
prompt_html: 'Vous (<strong>%{self}</strong>) avez demandé à suivre:'
|
||||
prompt_html: 'Vous (<strong>%{self}</strong>) avez demandé à suivre :'
|
||||
title: Suivre %{acct}
|
||||
datetime:
|
||||
distance_in_words:
|
||||
about_x_hours: "%{count}h"
|
||||
about_x_months: "%{count}mo"
|
||||
about_x_years: "%{count}y"
|
||||
almost_x_years: "%{count}y"
|
||||
about_x_months: "%{count}mois"
|
||||
about_x_years:
|
||||
one: un an
|
||||
other: "%{count} ans"
|
||||
almost_x_years:
|
||||
one: un an
|
||||
other: "%{count} ans"
|
||||
half_a_minute: A l'instant
|
||||
less_than_x_minutes: "%{count}m"
|
||||
less_than_x_minutes: "%{count}min"
|
||||
less_than_x_seconds: A l'instant
|
||||
over_x_years: "%{count}y"
|
||||
x_days: "%{count}d"
|
||||
x_minutes: "%{count}m"
|
||||
x_months: "%{count}mo"
|
||||
over_x_years:
|
||||
one: un an
|
||||
other: "%{count} ans"
|
||||
x_days: "%{count}j"
|
||||
x_minutes: "%{count}min"
|
||||
x_months: "%{count}mois"
|
||||
x_seconds: "%{count}s"
|
||||
exports:
|
||||
blocks: Vous bloquez
|
||||
|
@ -96,7 +102,7 @@ fr:
|
|||
landing_strip_html: <strong>%{name}</strong> utilise <strong>%{domain}</strong>. Vous pouvez le/la suivre et interagir si vous possédez un compte quelque part dans le "fediverse". Si ce n'est pas le cas, vous pouvez <a href="%{sign_up_path}">en créer un ici</a>.
|
||||
notification_mailer:
|
||||
digest:
|
||||
body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite (%{}):'
|
||||
body: 'Voici ce que vous avez raté sur ${instance} depuis votre dernière visite (%{}) :'
|
||||
mention: '%{name} vous a mentionné⋅e'
|
||||
new_followers_summary:
|
||||
one: Vous avez un⋅e nouvel⋅le abonné⋅e ! Youpi !
|
||||
|
@ -156,10 +162,10 @@ fr:
|
|||
disable: Désactiver
|
||||
enable: Activer
|
||||
instructions_html: "<strong>Scannez ce QR code grâce à Google Authenticator, Authy ou une application similaire sur votre téléphone</strong>. Désormais, cette application générera des jetons que vous devrez saisir à chaque connexion."
|
||||
plaintext_secret_html: 'Code secret en clair: <samp>%{secret}</samp>'
|
||||
plaintext_secret_html: 'Code secret en clair : <samp>%{secret}</samp>'
|
||||
warning: Si vous ne pouvez pas configurer une application d'authentification maintenant, vous devriez cliquer sur "Désactiver" pour ne pas bloquer l'accès à votre compte.
|
||||
users:
|
||||
invalid_email: L'adresse e-mail est invalide
|
||||
invalid_email: L'adresse courriel est invalide
|
||||
invalid_otp_token: Le code d'authentification à deux facteurs est invalide
|
||||
will_paginate:
|
||||
page_gap: "…"
|
||||
|
|
|
@ -188,11 +188,14 @@ Rails.application.routes.draw do
|
|||
|
||||
get '/web/(*any)', to: 'home#index', as: :web
|
||||
|
||||
get '/about', to: 'about#index'
|
||||
get '/about', to: 'about#show'
|
||||
get '/about/more', to: 'about#more'
|
||||
get '/terms', to: 'about#terms'
|
||||
|
||||
root 'home#index'
|
||||
|
||||
match '*unmatched_route', via: :all, to: 'application#raise_not_found'
|
||||
match '*unmatched_route',
|
||||
via: :all,
|
||||
to: 'application#raise_not_found',
|
||||
format: false
|
||||
end
|
||||
|
|
|
@ -35,3 +35,11 @@ You are able to set the following settings:
|
|||
- Site extended description
|
||||
|
||||
You may wish to use the extended description (shown at https://yourmastodon.instance/about/more ) to display content guidelines or a user agreement (see https://mastodon.social/about/more for an example).
|
||||
|
||||
## Confirming Users Manually
|
||||
|
||||
The following rake task:
|
||||
|
||||
RAILS_ENV=production bundle exec rails mastodon:confirm_email USER_EMAIL=alice@alice.com
|
||||
|
||||
Will confirm a user manually, in case they don't have access to their confirmation email for whatever reason.
|
||||
|
|
|
@ -10,6 +10,15 @@ namespace :mastodon do
|
|||
puts "Congrats! #{user.account.username} is now an admin. \\o/\nNavigate to #{admin_settings_url} to get started"
|
||||
end
|
||||
|
||||
desc 'Manually confirms a user with associated user email address stored in USER_EMAIL environment variable.'
|
||||
task confirm_email: :environment do
|
||||
email = ENV.fetch('USER_EMAIL')
|
||||
user = User.where(email: email)
|
||||
user.update(confirmed_at: Time.now.utc)
|
||||
|
||||
puts "User #{email} confirmed."
|
||||
end
|
||||
|
||||
namespace :media do
|
||||
desc 'Removes media attachments that have not been assigned to any status for longer than a day'
|
||||
task clear: :environment do
|
||||
|
|
|
@ -3,9 +3,16 @@ require 'rails_helper'
|
|||
RSpec.describe AboutController, type: :controller do
|
||||
render_views
|
||||
|
||||
describe 'GET #index' do
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
get :show
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #more' do
|
||||
it 'returns http success' do
|
||||
get :more
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -170,6 +170,61 @@ RSpec.describe Account, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.search_for' do
|
||||
before do
|
||||
@match = Fabricate(
|
||||
:account,
|
||||
display_name: "Display Name",
|
||||
username: "username",
|
||||
domain: "example.com"
|
||||
)
|
||||
_missing = Fabricate(
|
||||
:account,
|
||||
display_name: "Missing",
|
||||
username: "missing",
|
||||
domain: "missing.com"
|
||||
)
|
||||
end
|
||||
|
||||
it 'finds accounts with matching display_name' do
|
||||
results = Account.search_for("display")
|
||||
expect(results).to eq [@match]
|
||||
end
|
||||
|
||||
it 'finds accounts with matching username' do
|
||||
results = Account.search_for("username")
|
||||
expect(results).to eq [@match]
|
||||
end
|
||||
|
||||
it 'finds accounts with matching domain' do
|
||||
results = Account.search_for("example")
|
||||
expect(results).to eq [@match]
|
||||
end
|
||||
|
||||
it 'ranks multiple matches higher' do
|
||||
account = Fabricate(
|
||||
:account,
|
||||
username: "username",
|
||||
display_name: "username"
|
||||
)
|
||||
results = Account.search_for("username")
|
||||
expect(results).to eq [account, @match]
|
||||
end
|
||||
end
|
||||
|
||||
describe '.advanced_search_for' do
|
||||
it 'ranks followed accounts higher' do
|
||||
account = Fabricate(:account)
|
||||
match = Fabricate(:account, username: "Matching")
|
||||
followed_match = Fabricate(:account, username: "Matcher")
|
||||
Fabricate(:follow, account: account, target_account: followed_match)
|
||||
|
||||
results = Account.advanced_search_for("match", account)
|
||||
expect(results).to eq [followed_match, match]
|
||||
expect(results.first.rank).to be > results.last.rank
|
||||
end
|
||||
end
|
||||
|
||||
describe '.find_local' do
|
||||
before do
|
||||
Fabricate(:account, username: 'Alice')
|
||||
|
|
|
@ -12,4 +12,15 @@ RSpec.describe Tag, type: :model do
|
|||
expect(subject.match('https://en.wikipedia.org/wiki/Ghostbusters_(song)#Lawsuit')).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '.search_for' do
|
||||
it 'finds tag records with matching names' do
|
||||
tag = Fabricate(:tag, name: "match")
|
||||
_miss_tag = Fabricate(:tag, name: "miss")
|
||||
|
||||
results = Tag.search_for("match")
|
||||
|
||||
expect(results).to eq [tag]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
74
spec/presenters/instance_presenter_spec.rb
Normal file
74
spec/presenters/instance_presenter_spec.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe InstancePresenter do
|
||||
let(:instance_presenter) { InstancePresenter.new }
|
||||
|
||||
it "delegates site_description to Setting" do
|
||||
Setting.site_description = "Site desc"
|
||||
|
||||
expect(instance_presenter.site_description).to eq "Site desc"
|
||||
end
|
||||
|
||||
it "delegates site_extended_description to Setting" do
|
||||
Setting.site_extended_description = "Extended desc"
|
||||
|
||||
expect(instance_presenter.site_extended_description).to eq "Extended desc"
|
||||
end
|
||||
|
||||
it "delegates open_registrations to Setting" do
|
||||
Setting.open_registrations = false
|
||||
|
||||
expect(instance_presenter.open_registrations).to eq false
|
||||
end
|
||||
|
||||
it "delegates closed_registrations_message to Setting" do
|
||||
Setting.closed_registrations_message = "Closed message"
|
||||
|
||||
expect(instance_presenter.closed_registrations_message).to eq "Closed message"
|
||||
end
|
||||
|
||||
it "delegates contact_email to Setting" do
|
||||
Setting.contact_email = "admin@example.com"
|
||||
|
||||
expect(instance_presenter.contact_email).to eq "admin@example.com"
|
||||
end
|
||||
|
||||
describe "contact_account" do
|
||||
it "returns the account for the site contact username" do
|
||||
Setting.site_contact_username = "aaa"
|
||||
account = Fabricate(:account, username: "aaa")
|
||||
|
||||
expect(instance_presenter.contact_account).to eq(account)
|
||||
end
|
||||
end
|
||||
|
||||
describe "user_count" do
|
||||
it "returns the number of site users" do
|
||||
cache = double
|
||||
allow(Rails).to receive(:cache).and_return(cache)
|
||||
allow(cache).to receive(:fetch).with("user_count").and_return(123)
|
||||
|
||||
expect(instance_presenter.user_count).to eq(123)
|
||||
end
|
||||
end
|
||||
|
||||
describe "status_count" do
|
||||
it "returns the number of local statuses" do
|
||||
cache = double
|
||||
allow(Rails).to receive(:cache).and_return(cache)
|
||||
allow(cache).to receive(:fetch).with("local_status_count").and_return(234)
|
||||
|
||||
expect(instance_presenter.status_count).to eq(234)
|
||||
end
|
||||
end
|
||||
|
||||
describe "domain_count" do
|
||||
it "returns the number of known domains" do
|
||||
cache = double
|
||||
allow(Rails).to receive(:cache).and_return(cache)
|
||||
allow(cache).to receive(:fetch).with("distinct_domain_count").and_return(345)
|
||||
|
||||
expect(instance_presenter.domain_count).to eq(345)
|
||||
end
|
||||
end
|
||||
end
|
21
spec/requests/catch_all_route_request_spec.rb
Normal file
21
spec/requests/catch_all_route_request_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require "rails_helper"
|
||||
|
||||
describe "The catch all route" do
|
||||
describe "with a simple value" do
|
||||
it "returns a 404 page as html" do
|
||||
get "/test"
|
||||
|
||||
expect(response.status).to eq 404
|
||||
expect(response.content_type).to eq "text/html"
|
||||
end
|
||||
end
|
||||
|
||||
describe "with an implied format" do
|
||||
it "returns a 404 page as html" do
|
||||
get "/test.test"
|
||||
|
||||
expect(response.status).to eq 404
|
||||
expect(response.content_type).to eq "text/html"
|
||||
end
|
||||
end
|
||||
end
|
Reference in a new issue