diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb index 4c17bd79c2..06e4fd8b8f 100644 --- a/app/controllers/api/v1/instances/activity_controller.rb +++ b/app/controllers/api/v1/instances/activity_controller.rb @@ -3,6 +3,8 @@ class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseController before_action :require_enabled_api! + WEEKS_OF_ACTIVITY = 12 + def show cache_even_if_authenticated! render_with_cache json: :activity, expires_in: 1.day @@ -11,23 +13,40 @@ class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseControlle private def activity - statuses_tracker = ActivityTracker.new('activity:statuses:local', :basic) - logins_tracker = ActivityTracker.new('activity:logins', :unique) - registrations_tracker = ActivityTracker.new('activity:accounts:local', :basic) - - (0...12).map do |i| - start_of_week = i.weeks.ago - end_of_week = start_of_week + 6.days - - { - week: start_of_week.to_i.to_s, - statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s, - logins: logins_tracker.sum(start_of_week, end_of_week).to_s, - registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s, - } + activity_weeks.map do |weeks_ago| + activity_json(*week_edge_days(weeks_ago)) end end + def activity_json(start_of_week, end_of_week) + { + week: start_of_week.to_i.to_s, + statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s, + logins: logins_tracker.sum(start_of_week, end_of_week).to_s, + registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s, + } + end + + def activity_weeks + 0...WEEKS_OF_ACTIVITY + end + + def week_edge_days(num) + [num.weeks.ago, num.weeks.ago + 6.days] + end + + def statuses_tracker + ActivityTracker.new('activity:statuses:local', :basic) + end + + def logins_tracker + ActivityTracker.new('activity:logins', :unique) + end + + def registrations_tracker + ActivityTracker.new('activity:accounts:local', :basic) + end + def require_enabled_api! head 404 unless Setting.activity_api_enabled && !limited_federation_mode? end diff --git a/app/controllers/api/v1/instances/domain_blocks_controller.rb b/app/controllers/api/v1/instances/domain_blocks_controller.rb index 8fb90305ad..7ec94312f4 100644 --- a/app/controllers/api/v1/instances/domain_blocks_controller.rb +++ b/app/controllers/api/v1/instances/domain_blocks_controller.rb @@ -19,7 +19,19 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr private def require_enabled_api! - head 404 unless Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?) + head 404 unless api_enabled? + end + + def api_enabled? + show_domain_blocks_for_all? || show_domain_blocks_to_user? + end + + def show_domain_blocks_for_all? + Setting.show_domain_blocks == 'all' + end + + def show_domain_blocks_to_user? + Setting.show_domain_blocks == 'users' && user_signed_in? end def set_domain_blocks diff --git a/spec/controllers/api/v1/instances/activity_controller_spec.rb b/spec/controllers/api/v1/instances/activity_controller_spec.rb deleted file mode 100644 index b446a521f8..0000000000 --- a/spec/controllers/api/v1/instances/activity_controller_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::Instances::ActivityController do - describe 'GET #show' do - it 'returns 200' do - get :show - expect(response).to have_http_status(200) - end - - context 'with !Setting.activity_api_enabled' do - it 'returns 404' do - Setting.activity_api_enabled = false - - get :show - expect(response).to have_http_status(404) - end - end - end -end diff --git a/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb deleted file mode 100644 index 08f505c3d4..0000000000 --- a/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Instances::DomainBlocksController do - render_views - - describe 'GET #index' do - it 'returns http success' do - Setting.show_domain_blocks = 'all' - get :index - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb b/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb deleted file mode 100644 index 58c0d4b8f1..0000000000 --- a/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Instances::ExtendedDescriptionsController do - render_views - - describe 'GET #show' do - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v1/instances/peers_controller_spec.rb b/spec/controllers/api/v1/instances/peers_controller_spec.rb deleted file mode 100644 index 92b1019154..0000000000 --- a/spec/controllers/api/v1/instances/peers_controller_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::Instances::PeersController do - describe 'GET #index' do - it 'returns 200' do - get :index - expect(response).to have_http_status(200) - end - - context 'with !Setting.peers_api_enabled' do - it 'returns 404' do - Setting.peers_api_enabled = false - - get :index - expect(response).to have_http_status(404) - end - end - end -end diff --git a/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb b/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb deleted file mode 100644 index ac0bed9dc6..0000000000 --- a/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Instances::PrivacyPoliciesController do - render_views - - describe 'GET #show' do - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v1/instances/rules_controller_spec.rb b/spec/controllers/api/v1/instances/rules_controller_spec.rb deleted file mode 100644 index 5af50239b0..0000000000 --- a/spec/controllers/api/v1/instances/rules_controller_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Instances::RulesController do - render_views - - describe 'GET #index' do - it 'returns http success' do - get :index - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb b/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb deleted file mode 100644 index f79687df66..0000000000 --- a/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Instances::TranslationLanguagesController do - describe 'GET #show' do - context 'when no translation service is configured' do - it 'returns empty language matrix', :aggregate_failures do - get :show - - expect(response).to have_http_status(200) - expect(body_as_json).to eq({}) - end - end - - context 'when a translation service is configured' do - before do - service = instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] }) - allow(TranslationService).to receive_messages(configured?: true, configured: service) - end - - it 'returns language matrix', :aggregate_failures do - get :show - - expect(response).to have_http_status(200) - expect(body_as_json).to eq({ und: %w(en de), en: ['de'] }) - end - end - end -end diff --git a/spec/controllers/api/v1/instances_controller_spec.rb b/spec/controllers/api/v1/instances_controller_spec.rb deleted file mode 100644 index fcc2c9288c..0000000000 --- a/spec/controllers/api/v1/instances_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::InstancesController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/controllers/api/v2/instances_controller_spec.rb b/spec/controllers/api/v2/instances_controller_spec.rb deleted file mode 100644 index b7206da0a2..0000000000 --- a/spec/controllers/api/v2/instances_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V2::InstancesController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - it 'returns http success' do - get :show - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/instance_spec.rb b/spec/requests/api/v1/instance_spec.rb new file mode 100644 index 0000000000..9cac280c4d --- /dev/null +++ b/spec/requests/api/v1/instance_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Instances' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/instance' do + context 'when not logged in' do + it 'returns http success and json' do + get api_v1_instance_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(title: 'Mastodon') + end + end + + context 'when logged in' do + it 'returns http success and json' do + get api_v1_instance_path, headers: headers + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(title: 'Mastodon') + end + end + end +end diff --git a/spec/requests/api/v1/instances/activity_spec.rb b/spec/requests/api/v1/instances/activity_spec.rb new file mode 100644 index 0000000000..d1f92ef36e --- /dev/null +++ b/spec/requests/api/v1/instances/activity_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Activity' do + describe 'GET /api/v1/instance/activity' do + around do |example| + original = Setting.activity_api_enabled + example.run + Setting.activity_api_enabled = original + end + + context 'with activity api enabled' do + before { Setting.activity_api_enabled = true } + + it 'returns http success' do + get api_v1_instance_activity_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and(be_an(Array)) + .and(have_attributes(size: Api::V1::Instances::ActivityController::WEEKS_OF_ACTIVITY)) + end + end + + context 'with activity api diabled' do + before { Setting.activity_api_enabled = false } + + it 'returns not found' do + get api_v1_instance_activity_path + + expect(response) + .to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/instances/domain_blocks_spec.rb b/spec/requests/api/v1/instances/domain_blocks_spec.rb new file mode 100644 index 0000000000..99b5e2b6aa --- /dev/null +++ b/spec/requests/api/v1/instances/domain_blocks_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Domain Blocks' do + describe 'GET /api/v1/instance/domain_blocks' do + around do |example| + original = Setting.show_domain_blocks + example.run + Setting.show_domain_blocks = original + end + + before do + Fabricate(:domain_block) + end + + context 'with domain blocks set to all' do + before { Setting.show_domain_blocks = 'all' } + + it 'returns http success' do + get api_v1_instance_domain_blocks_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and(be_an(Array)) + .and(have_attributes(size: 1)) + end + end + + context 'with domain blocks set to users' do + before { Setting.show_domain_blocks = 'users' } + + it 'returns http not found' do + get api_v1_instance_domain_blocks_path + + expect(response) + .to have_http_status(404) + end + end + + context 'with domain blocks set to disabled' do + before { Setting.show_domain_blocks = 'disabled' } + + it 'returns http not found' do + get api_v1_instance_domain_blocks_path + + expect(response) + .to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/instances/extended_descriptions_spec.rb b/spec/requests/api/v1/instances/extended_descriptions_spec.rb new file mode 100644 index 0000000000..64982de686 --- /dev/null +++ b/spec/requests/api/v1/instances/extended_descriptions_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Extended Descriptions' do + describe 'GET /api/v1/instance/extended_description' do + it 'returns http success' do + get api_v1_instance_extended_description_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(:content) + end + end +end diff --git a/spec/requests/api/v1/instances/peers_spec.rb b/spec/requests/api/v1/instances/peers_spec.rb new file mode 100644 index 0000000000..d3400ae8fd --- /dev/null +++ b/spec/requests/api/v1/instances/peers_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Peers' do + describe 'GET /api/v1/instance/peers' do + around do |example| + original = Setting.peers_api_enabled + example.run + Setting.peers_api_enabled = original + end + + context 'with peers api enabled' do + before { Setting.peers_api_enabled = true } + + it 'returns http success' do + get api_v1_instance_peers_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_an(Array) + end + end + + context 'with peers api diabled' do + before { Setting.peers_api_enabled = false } + + it 'returns http not found' do + get api_v1_instance_peers_path + + expect(response) + .to have_http_status(404) + end + end + end +end diff --git a/spec/requests/api/v1/instances/privacy_policies_spec.rb b/spec/requests/api/v1/instances/privacy_policies_spec.rb new file mode 100644 index 0000000000..24de98d880 --- /dev/null +++ b/spec/requests/api/v1/instances/privacy_policies_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Privacy Policy' do + describe 'GET /api/v1/instance/privacy_policy' do + it 'returns http success' do + get api_v1_instance_privacy_policy_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(:content) + end + end +end diff --git a/spec/requests/api/v1/instances/rules_spec.rb b/spec/requests/api/v1/instances/rules_spec.rb new file mode 100644 index 0000000000..65b8d78c7d --- /dev/null +++ b/spec/requests/api/v1/instances/rules_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Rules' do + describe 'GET /api/v1/instance/rules' do + it 'returns http success' do + get api_v1_instance_rules_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_an(Array) + end + end +end diff --git a/spec/requests/api/v1/instances/translation_languages_spec.rb b/spec/requests/api/v1/instances/translation_languages_spec.rb new file mode 100644 index 0000000000..0b7dd8314d --- /dev/null +++ b/spec/requests/api/v1/instances/translation_languages_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Translation Languages' do + describe 'GET /api/v1/instances/translation_languages' do + context 'when no translation service is configured' do + it 'returns empty language matrix', :aggregate_failures do + get api_v1_instance_translation_languages_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to eq({}) + end + end + + context 'when a translation service is configured' do + before { configure_translation_service } + + it 'returns language matrix', :aggregate_failures do + get api_v1_instance_translation_languages_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to eq({ und: %w(en de), en: ['de'] }) + end + + private + + def configure_translation_service + allow(TranslationService).to receive_messages(configured?: true, configured: service_double) + end + + def service_double + instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] }) + end + end + end +end diff --git a/spec/requests/api/v2/instance_spec.rb b/spec/requests/api/v2/instance_spec.rb new file mode 100644 index 0000000000..74574afbcf --- /dev/null +++ b/spec/requests/api/v2/instance_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Instances' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v2/instance' do + context 'when logged out' do + it 'returns http success and json' do + get api_v2_instance_path + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(title: 'Mastodon') + end + end + + context 'when logged in' do + it 'returns http success and json' do + get api_v2_instance_path, headers: headers + + expect(response) + .to have_http_status(200) + + expect(body_as_json) + .to be_present + .and include(title: 'Mastodon') + end + end + end +end