Merge remote-tracking branch 'parent/main' into kb_migration
This commit is contained in:
commit
fbb1a69a65
19 changed files with 317 additions and 70 deletions
108
Gemfile.lock
108
Gemfile.lock
|
@ -39,47 +39,47 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (7.0.7.2)
|
actioncable (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (7.0.7.2)
|
actionmailbox (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
activejob (= 7.0.7.2)
|
activejob (= 7.0.8)
|
||||||
activerecord (= 7.0.7.2)
|
activerecord (= 7.0.8)
|
||||||
activestorage (= 7.0.7.2)
|
activestorage (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
actionmailer (7.0.7.2)
|
actionmailer (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
actionview (= 7.0.7.2)
|
actionview (= 7.0.8)
|
||||||
activejob (= 7.0.7.2)
|
activejob (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (7.0.7.2)
|
actionpack (7.0.8)
|
||||||
actionview (= 7.0.7.2)
|
actionview (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
rack (~> 2.0, >= 2.2.4)
|
rack (~> 2.0, >= 2.2.4)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (7.0.7.2)
|
actiontext (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
activerecord (= 7.0.7.2)
|
activerecord (= 7.0.8)
|
||||||
activestorage (= 7.0.7.2)
|
activestorage (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.0.7.2)
|
actionview (7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
@ -89,22 +89,22 @@ GEM
|
||||||
activemodel (>= 4.1, < 7.1)
|
activemodel (>= 4.1, < 7.1)
|
||||||
case_transform (>= 0.2)
|
case_transform (>= 0.2)
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||||
activejob (7.0.7.2)
|
activejob (7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.0.7.2)
|
activemodel (7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
activerecord (7.0.7.2)
|
activerecord (7.0.8)
|
||||||
activemodel (= 7.0.7.2)
|
activemodel (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
activestorage (7.0.7.2)
|
activestorage (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
activejob (= 7.0.7.2)
|
activejob (= 7.0.8)
|
||||||
activerecord (= 7.0.7.2)
|
activerecord (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
mini_mime (>= 1.1.0)
|
mini_mime (>= 1.1.0)
|
||||||
activesupport (7.0.7.2)
|
activesupport (7.0.8)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
@ -556,20 +556,20 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (2.1.0)
|
rack-test (2.1.0)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rails (7.0.7.2)
|
rails (7.0.8)
|
||||||
actioncable (= 7.0.7.2)
|
actioncable (= 7.0.8)
|
||||||
actionmailbox (= 7.0.7.2)
|
actionmailbox (= 7.0.8)
|
||||||
actionmailer (= 7.0.7.2)
|
actionmailer (= 7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
actiontext (= 7.0.7.2)
|
actiontext (= 7.0.8)
|
||||||
actionview (= 7.0.7.2)
|
actionview (= 7.0.8)
|
||||||
activejob (= 7.0.7.2)
|
activejob (= 7.0.8)
|
||||||
activemodel (= 7.0.7.2)
|
activemodel (= 7.0.8)
|
||||||
activerecord (= 7.0.7.2)
|
activerecord (= 7.0.8)
|
||||||
activestorage (= 7.0.7.2)
|
activestorage (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.0.7.2)
|
railties (= 7.0.8)
|
||||||
rails-controller-testing (1.0.5)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.rc1)
|
actionpack (>= 5.0.1.rc1)
|
||||||
actionview (>= 5.0.1.rc1)
|
actionview (>= 5.0.1.rc1)
|
||||||
|
@ -584,9 +584,9 @@ GEM
|
||||||
rails-i18n (7.0.7)
|
rails-i18n (7.0.7)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 8)
|
railties (>= 6.0.0, < 8)
|
||||||
railties (7.0.7.2)
|
railties (7.0.8)
|
||||||
actionpack (= 7.0.7.2)
|
actionpack (= 7.0.8)
|
||||||
activesupport (= 7.0.7.2)
|
activesupport (= 7.0.8)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
@ -747,7 +747,7 @@ GEM
|
||||||
unicode-display_width (>= 1.1.1, < 3)
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
terrapin (0.6.0)
|
terrapin (0.6.0)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
test-prof (1.2.2)
|
test-prof (1.2.3)
|
||||||
thor (1.2.2)
|
thor (1.2.2)
|
||||||
tilt (2.2.0)
|
tilt (2.2.0)
|
||||||
timeout (0.4.0)
|
timeout (0.4.0)
|
||||||
|
|
74
app/controllers/api/v1/admin/tags_controller.rb
Normal file
74
app/controllers/api/v1/admin/tags_controller.rb
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Api::V1::Admin::TagsController < Api::BaseController
|
||||||
|
include Authorization
|
||||||
|
before_action -> { authorize_if_got_token! :'admin:read' }, only: [:index, :show]
|
||||||
|
before_action -> { authorize_if_got_token! :'admin:write' }, only: :update
|
||||||
|
|
||||||
|
before_action :set_tags, only: :index
|
||||||
|
before_action :set_tag, except: :index
|
||||||
|
|
||||||
|
after_action :insert_pagination_headers, only: :index
|
||||||
|
after_action :verify_authorized
|
||||||
|
|
||||||
|
LIMIT = 100
|
||||||
|
PAGINATION_PARAMS = %i(limit).freeze
|
||||||
|
|
||||||
|
def index
|
||||||
|
authorize :tag, :index?
|
||||||
|
render json: @tags, each_serializer: REST::Admin::TagSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
authorize @tag, :show?
|
||||||
|
render json: @tag, serializer: REST::Admin::TagSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
authorize @tag, :update?
|
||||||
|
@tag.update!(tag_params.merge(reviewed_at: Time.now.utc))
|
||||||
|
render json: @tag, serializer: REST::Admin::TagSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_tag
|
||||||
|
@tag = Tag.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_tags
|
||||||
|
@tags = Tag.all.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_params
|
||||||
|
params.permit(:display_name, :trendable, :usable, :listable)
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_pagination_headers
|
||||||
|
set_pagination_headers(next_path, prev_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_path
|
||||||
|
api_v1_admin_tags_url(pagination_params(max_id: pagination_max_id)) if records_continue?
|
||||||
|
end
|
||||||
|
|
||||||
|
def prev_path
|
||||||
|
api_v1_admin_tags_url(pagination_params(min_id: pagination_since_id)) unless @tags.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_max_id
|
||||||
|
@tags.last.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_since_id
|
||||||
|
@tags.first.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def records_continue?
|
||||||
|
@tags.size == limit_param(LIMIT)
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_params(core_params)
|
||||||
|
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@ module WebAppControllerConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def skip_csrf_meta_tags?
|
def skip_csrf_meta_tags?
|
||||||
!(ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1) && current_user.nil?
|
!(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1) && current_user.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_app_body_class
|
def set_app_body_class
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
importFetchedStatuses,
|
importFetchedStatuses,
|
||||||
} from './importer';
|
} from './importer';
|
||||||
import { submitMarkers } from './markers';
|
import { submitMarkers } from './markers';
|
||||||
|
import { register as registerPushNotifications } from './push_notifications';
|
||||||
import { saveSettings } from './settings';
|
import { saveSettings } from './settings';
|
||||||
import { STATUS_EMOJI_REACTION_UPDATE } from './statuses';
|
import { STATUS_EMOJI_REACTION_UPDATE } from './statuses';
|
||||||
|
|
||||||
|
@ -305,6 +306,10 @@ export function requestBrowserPermission(callback = noOp) {
|
||||||
requestNotificationPermission((permission) => {
|
requestNotificationPermission((permission) => {
|
||||||
dispatch(setBrowserPermission(permission));
|
dispatch(setBrowserPermission(permission));
|
||||||
callback(permission);
|
callback(permission);
|
||||||
|
|
||||||
|
if (permission === 'granted') {
|
||||||
|
dispatch(registerPushNotifications());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ function main() {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registration) {
|
if (registration && 'Notification' in window && Notification.permission === 'granted') {
|
||||||
const registerPushNotifications = await import('mastodon/actions/push_notifications');
|
const registerPushNotifications = await import('mastodon/actions/push_notifications');
|
||||||
|
|
||||||
store.dispatch(registerPushNotifications.register());
|
store.dispatch(registerPushNotifications.register());
|
||||||
|
|
|
@ -73,6 +73,7 @@ export default function relationships(state = initialState, action) {
|
||||||
case ACCOUNT_UNMUTE_SUCCESS:
|
case ACCOUNT_UNMUTE_SUCCESS:
|
||||||
case ACCOUNT_PIN_SUCCESS:
|
case ACCOUNT_PIN_SUCCESS:
|
||||||
case ACCOUNT_UNPIN_SUCCESS:
|
case ACCOUNT_UNPIN_SUCCESS:
|
||||||
|
return normalizeRelationship(state, action.relationship);
|
||||||
case RELATIONSHIPS_FETCH_SUCCESS:
|
case RELATIONSHIPS_FETCH_SUCCESS:
|
||||||
return normalizeRelationships(state, action.relationships);
|
return normalizeRelationships(state, action.relationships);
|
||||||
case submitAccountNote.fulfilled:
|
case submitAccountNote.fulfilled:
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { showAlertForError } from '../../actions/alerts';
|
||||||
|
|
||||||
const defaultFailSuffix = 'FAIL';
|
const defaultFailSuffix = 'FAIL';
|
||||||
|
|
||||||
export const errorsMiddleware: Middleware<Record<string, never>, RootState> =
|
export const errorsMiddleware: Middleware<unknown, RootState> =
|
||||||
({ dispatch }) =>
|
({ dispatch }) =>
|
||||||
(next) =>
|
(next) =>
|
||||||
(action: AnyAction & { skipAlert?: boolean; skipNotFound?: boolean }) => {
|
(action: AnyAction & { skipAlert?: boolean; skipNotFound?: boolean }) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const defaultTypeSuffixes: Config['promiseTypeSuffixes'] = [
|
||||||
|
|
||||||
export const loadingBarMiddleware = (
|
export const loadingBarMiddleware = (
|
||||||
config: Config = {},
|
config: Config = {},
|
||||||
): Middleware<Record<string, never>, RootState> => {
|
): Middleware<unknown, RootState> => {
|
||||||
const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes;
|
const promiseTypeSuffixes = config.promiseTypeSuffixes ?? defaultTypeSuffixes;
|
||||||
|
|
||||||
return ({ dispatch }) =>
|
return ({ dispatch }) =>
|
||||||
|
|
|
@ -34,10 +34,7 @@ const play = (audio: HTMLAudioElement) => {
|
||||||
void audio.play();
|
void audio.play();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const soundsMiddleware = (): Middleware<
|
export const soundsMiddleware = (): Middleware<unknown, RootState> => {
|
||||||
Record<string, never>,
|
|
||||||
RootState
|
|
||||||
> => {
|
|
||||||
const soundCache: Record<string, HTMLAudioElement> = {};
|
const soundCache: Record<string, HTMLAudioElement> = {};
|
||||||
|
|
||||||
void ready(() => {
|
void ready(() => {
|
||||||
|
|
|
@ -12,5 +12,4 @@ export const createAppAsyncThunk = createAsyncThunk.withTypes<{
|
||||||
state: RootState;
|
state: RootState;
|
||||||
dispatch: AppDispatch;
|
dispatch: AppDispatch;
|
||||||
rejectValue: string;
|
rejectValue: string;
|
||||||
extra: { s: string; n: number };
|
|
||||||
}>();
|
}>();
|
||||||
|
|
|
@ -5274,6 +5274,11 @@ a.status-card {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
overflow: inherit;
|
||||||
|
text-overflow: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class Tag < ApplicationRecord
|
class Tag < ApplicationRecord
|
||||||
|
include Paginable
|
||||||
has_and_belongs_to_many :statuses
|
has_and_belongs_to_many :statuses
|
||||||
has_and_belongs_to_many :accounts
|
has_and_belongs_to_many :accounts
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,6 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def sso_redirect
|
def sso_redirect
|
||||||
"/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1
|
"/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::Admin::TagSerializer < REST::TagSerializer
|
class REST::Admin::TagSerializer < REST::TagSerializer
|
||||||
attributes :id, :trendable, :usable, :requires_review
|
attributes :id, :trendable, :usable, :requires_review, :listable
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
|
|
|
@ -19,6 +19,22 @@ media_host ||= host_to_url(ENV['AZURE_ALIAS_HOST'])
|
||||||
media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true'
|
media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true'
|
||||||
media_host ||= assets_host
|
media_host ||= assets_host
|
||||||
|
|
||||||
|
def sso_host
|
||||||
|
return unless ENV['ONE_CLICK_SSO_LOGIN'] == 'true'
|
||||||
|
return unless ENV['OMNIAUTH_ONLY'] == 'true'
|
||||||
|
return unless Devise.omniauth_providers.length == 1
|
||||||
|
|
||||||
|
provider = Devise.omniauth_configs[Devise.omniauth_providers[0]]
|
||||||
|
@sso_host ||= begin
|
||||||
|
# using CAS
|
||||||
|
provider.cas_url if ENV['CAS_ENABLED'] == 'true'
|
||||||
|
# using SAML
|
||||||
|
provider.options[:idp_sso_target_url] if ENV['SAML_ENABLED'] == 'true'
|
||||||
|
# or using OIDC
|
||||||
|
ENV['OIDC_AUTH_ENDPOINT'] || (OpenIDConnect::Discovery::Provider::Config.discover!(ENV['OIDC_ISSUER']).authorization_endpoint if ENV['OIDC_ENABLED'] == 'true')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Rails.application.config.content_security_policy do |p|
|
Rails.application.config.content_security_policy do |p|
|
||||||
p.base_uri :none
|
p.base_uri :none
|
||||||
p.default_src :none
|
p.default_src :none
|
||||||
|
@ -29,7 +45,13 @@ Rails.application.config.content_security_policy do |p|
|
||||||
p.media_src :self, :https, :data, assets_host
|
p.media_src :self, :https, :data, assets_host
|
||||||
p.frame_src :self, :https
|
p.frame_src :self, :https
|
||||||
p.manifest_src :self, assets_host
|
p.manifest_src :self, assets_host
|
||||||
|
|
||||||
|
if sso_host.present?
|
||||||
|
p.form_action :self, sso_host
|
||||||
|
else
|
||||||
p.form_action :self
|
p.form_action :self
|
||||||
|
end
|
||||||
|
|
||||||
p.child_src :self, :blob, assets_host
|
p.child_src :self, :blob, assets_host
|
||||||
p.worker_src :self, :blob, assets_host
|
p.worker_src :self, :blob, assets_host
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,8 @@ namespace :api, format: false do
|
||||||
post :test
|
post :test
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :tags, only: [:index, :show, :update]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Mastodon::CLI
|
||||||
|
|
||||||
option :concurrency, type: :numeric, default: 5, aliases: [:c], desc: 'Workload will be split between this number of threads'
|
option :concurrency, type: :numeric, default: 5, aliases: [:c], desc: 'Workload will be split between this number of threads'
|
||||||
option :batch_size, type: :numeric, default: 100, aliases: [:b], desc: 'Number of records in each batch'
|
option :batch_size, type: :numeric, default: 100, aliases: [:b], desc: 'Number of records in each batch'
|
||||||
option :only, type: :array, enum: %w(instances accounts tags statuses), desc: 'Only process these indices'
|
option :only, type: :array, enum: %w(instances accounts tags statuses public_statuses), desc: 'Only process these indices'
|
||||||
option :import, type: :boolean, default: true, desc: 'Import data from the database to the index'
|
option :import, type: :boolean, default: true, desc: 'Import data from the database to the index'
|
||||||
option :clean, type: :boolean, default: true, desc: 'Remove outdated documents from the index'
|
option :clean, type: :boolean, default: true, desc: 'Remove outdated documents from the index'
|
||||||
option :reset_chewy, type: :boolean, default: false, desc: "Reset Chewy's internal index"
|
option :reset_chewy, type: :boolean, default: false, desc: "Reset Chewy's internal index"
|
||||||
|
|
141
spec/requests/api/v1/admin/tags_spec.rb
Normal file
141
spec/requests/api/v1/admin/tags_spec.rb
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Tags' do
|
||||||
|
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||||
|
let(:user) { Fabricate(:user, role: role) }
|
||||||
|
let(:scopes) { 'admin:read admin:write' }
|
||||||
|
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||||
|
let(:tag) { Fabricate(:tag) }
|
||||||
|
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||||
|
|
||||||
|
describe 'GET /api/v1/admin/tags' do
|
||||||
|
subject do
|
||||||
|
get '/api/v1/admin/tags', headers: headers, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:params) { {} }
|
||||||
|
|
||||||
|
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||||
|
it_behaves_like 'forbidden for wrong role', ''
|
||||||
|
|
||||||
|
it 'returns http success' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are no tags' do
|
||||||
|
it 'returns an empty list' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(body_as_json).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there are tagss' do
|
||||||
|
let!(:tags) do
|
||||||
|
[
|
||||||
|
Fabricate(:tag),
|
||||||
|
Fabricate(:tag),
|
||||||
|
Fabricate(:tag),
|
||||||
|
Fabricate(:tag),
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the expected tags' do
|
||||||
|
subject
|
||||||
|
tags.each do |tag|
|
||||||
|
expect(body_as_json.find { |item| item[:id] == tag.id.to_s && item[:name] == tag.name }).to_not be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with limit param' do
|
||||||
|
let(:params) { { limit: 2 } }
|
||||||
|
|
||||||
|
it 'returns only the requested number of tags' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(body_as_json.size).to eq(params[:limit])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET /api/v1/admin/tags/:id' do
|
||||||
|
subject do
|
||||||
|
get "/api/v1/admin/tags/#{tag.id}", headers: headers
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:tag) { Fabricate(:tag) }
|
||||||
|
|
||||||
|
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||||
|
it_behaves_like 'forbidden for wrong role', ''
|
||||||
|
|
||||||
|
it 'returns http success' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns expected tag content' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(body_as_json[:id].to_i).to eq(tag.id)
|
||||||
|
expect(body_as_json[:name]).to eq(tag.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the requested tag does not exist' do
|
||||||
|
it 'returns http not found' do
|
||||||
|
get '/api/v1/admin/tags/-1', headers: headers
|
||||||
|
|
||||||
|
expect(response).to have_http_status(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PUT /api/v1/admin/tags/:id' do
|
||||||
|
subject do
|
||||||
|
put "/api/v1/admin/tags/#{tag.id}", headers: headers, params: params
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:tag) { Fabricate(:tag) }
|
||||||
|
let(:params) { { display_name: tag.name.upcase } }
|
||||||
|
|
||||||
|
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||||
|
it_behaves_like 'forbidden for wrong scope', 'admin:read'
|
||||||
|
it_behaves_like 'forbidden for wrong role', ''
|
||||||
|
|
||||||
|
it 'returns http success' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns updated tag' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(body_as_json[:id].to_i).to eq(tag.id)
|
||||||
|
expect(body_as_json[:name]).to eq(tag.name.upcase)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the updated display name is invalid' do
|
||||||
|
let(:params) { { display_name: tag.name + tag.id.to_s } }
|
||||||
|
|
||||||
|
it 'returns http unprocessable content' do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the requested tag does not exist' do
|
||||||
|
it 'returns http not found' do
|
||||||
|
get '/api/v1/admin/tags/-1', headers: headers
|
||||||
|
|
||||||
|
expect(response).to have_http_status(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -12379,9 +12379,9 @@ uuid@^8.3.2:
|
||||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||||
|
|
||||||
uuid@^9.0.0:
|
uuid@^9.0.0:
|
||||||
version "9.0.0"
|
version "9.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
|
||||||
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
|
||||||
|
|
||||||
v8-compile-cache@^2.1.1:
|
v8-compile-cache@^2.1.1:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue