Merge branch 'feature/add-missing-settings' into 'develop'

Add missing settings

Closes #132

See merge request pleroma/admin-fe!151
This commit is contained in:
Angelina Filippova 2020-08-13 11:51:04 +00:00
commit 37df2725ac
16 changed files with 295 additions and 74 deletions

View File

@ -18,7 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add ability to disable multi-factor authentication for a user
- Add ability to manually evict and ban URLs from the Pleroma MediaProxy cache
- Add Invalidation settings on MediaProxy tab
- Ability to configure S3 settings on Upload tab
- Ability to configure S3 settings on Upload tab, Pleroma.Web.ApiSpec.CastAndValidate and :modules settings on Other tab, Pools, Connections pools and Hackney pools settings on Job Queue tab, :restrict_unauthenticated settings on Authentication tab, :favicons and :welcome settings on Instance tab, :frontends settings on Frontend tab
- Show number of open reports in Sidebar Menu
- Add confirmation message when deleting a user
@ -31,7 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- When rendering user's profile, statuses, reports and notes check if required properties exist
- Remove ability to moderate users that don't have valid nickname
- Displays both labels and description in the header of group of settiings
- Ability to add custom values in Pleroma.Upload.Filter.Mogrify setting
- Ability to add custom values in Pleroma.Upload.Filter.Mogrify setting in the following format: '{"implode", "1"}'
- Change types of the following settings: ':groups', ':replace', ':federated_timeline_removal', ':reject', ':match_actor'. Update functions that parses and wraps settings data according to this change.
- Move rendering Crontab setting from a separate component to EditableKeyword component
- Show only those MRF settings that have been enabled in MRF Policies setting
@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Send `true` and `false` as booleans if they are values of single selects on the Settings page
- Fix sorting users on Users page if there is an acount with missing nickname or ID
- Add new type of settings: `['string', 'image']`. Render Image upload Input depending on the type of setting, not its key
## [2.0.3] - 2020-04-29

View File

@ -50,12 +50,7 @@ export const parseNonTuples = (key, value) => {
return updated
}
if (key === ':args') {
if (typeof value === 'string') {
return [value]
}
const index = value.findIndex(el => typeof el === 'object' && el.tuple.includes('implode'))
const updated = value.map((el, i) => i === index ? 'implode' : el)
return updated
return typeof value === 'string' ? [value] : value
}
return value
}
@ -89,8 +84,8 @@ export const parseTuples = (tuples, key) => {
}, [])
} else if (item.tuple[0] === ':prune') {
accum[item.tuple[0]] = item.tuple[1] === ':disabled' ? [item.tuple[1]] : item.tuple[1].tuple
} else if (item.tuple[0] === ':proxy_url') {
accum[item.tuple[0]] = parseProxyUrl(item.tuple[1])
} else if (item.tuple[0] === ':proxy_url' || item.tuple[0] === ':sender') {
accum[item.tuple[0]] = parseStringOrTupleValue(item.tuple[0], item.tuple[1])
} else if (item.tuple[0] === ':args') {
accum[item.tuple[0]] = parseNonTuples(item.tuple[0], item.tuple[1])
} else if (Array.isArray(item.tuple[1]) &&
@ -122,18 +117,29 @@ const parseObject = object => {
}, {})
}
const parseProxyUrl = value => {
if (value && !Array.isArray(value) &&
typeof value === 'object' &&
value.tuple.length === 3 &&
value.tuple[0] === ':socks5') {
const [, host, port] = value.tuple
return { socks5: true, host, port }
} else if (typeof value === 'string') {
const [host, port] = value.split(':')
return { socks5: false, host, port }
const parseStringOrTupleValue = (key, value) => {
if (key === ':proxy_url') {
if (value && !Array.isArray(value) &&
typeof value === 'object' &&
value.tuple.length === 3 &&
value.tuple[0] === ':socks5') {
const [, host, port] = value.tuple
return { socks5: true, host, port }
} else if (typeof value === 'string') {
const [host, port] = value.split(':')
return { socks5: false, host, port }
}
return { socks5: false, host: null, port: null }
} else if (key === ':sender') {
if (typeof value === 'string') {
return { email: value }
} else if (value &&
typeof value === 'object' &&
value.tuple.length === 2) {
const [nickname, email] = value.tuple
return { nickname, email }
}
}
return { socks5: false, host: null, port: null }
}
const prependWithСolon = (type, value) => {
@ -248,13 +254,6 @@ const wrapValues = (settings, currentState) => {
} else if (setting === ':ip') {
const ip = value.split('.').map(s => parseInt(s, 10))
return { 'tuple': [setting, { 'tuple': ip }] }
} else if (setting === ':args') {
const index = value.findIndex(el => el === 'implode')
const updatedArray = value.slice()
if (index !== -1) {
updatedArray[index] = { 'tuple': ['implode', '1'] }
}
return { 'tuple': [setting, updatedArray] }
} else {
return { 'tuple': [setting, value] }
}

View File

@ -11,10 +11,14 @@
<el-form :model="ldapData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="ldap" :data="ldapData"/>
</el-form>
<el-divider v-if="oauth2" class="divider thick-line"/>
<el-divider v-if="ldap" class="divider thick-line"/>
<el-form :model="oauth2Data" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="oauth2" :data="oauth2Data"/>
</el-form>
<el-divider v-if="oauth2" class="divider thick-line"/>
<el-form :model="restrictUnauthenticatedData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="restrictUnauthenticated" :data="restrictUnauthenticatedData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
</div>
@ -81,6 +85,12 @@ export default {
},
pleromaAuthenticatorData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.Auth.Authenticator']) || {}
},
restrictUnauthenticated() {
return this.settings.description.find(setting => setting.key === ':restrict_unauthenticated')
},
restrictUnauthenticatedData() {
return _.get(this.settings.settings, [':pleroma', ':restrict_unauthenticated']) || {}
}
},
methods: {

View File

@ -8,6 +8,10 @@
<setting :setting-group="staticFe" :data="staticFeData"/>
</el-form>
<el-divider v-if="staticFe" class="divider thick-line"/>
<el-form :model="frontendsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="frontends" :data="frontendsData"/>
</el-form>
<el-divider v-if="frontends" class="divider thick-line"/>
<el-form :model="assetsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="assets" :data="assetsData"/>
</el-form>
@ -66,6 +70,12 @@ export default {
frontendData() {
return _.get(this.settings.settings, [':pleroma', ':frontend_configurations']) || {}
},
frontends() {
return this.settings.description.find(setting => setting.key === ':frontends')
},
frontendsData() {
return _.get(this.settings.settings, [':pleroma', ':frontends']) || {}
},
isMobile() {
return this.$store.state.app.device === 'mobile'
},

View File

@ -112,6 +112,7 @@
<reg-invites-input v-if="[':registrations_open', ':invites_enabled'].includes(setting.key)" :data="data" :setting-group="settingGroup" :setting="setting"/>
<select-input-with-reduced-labels v-if="reducedSelects" :data="data" :setting-group="settingGroup" :setting="setting"/>
<specific-multiple-select v-if="setting.key === ':backends' || setting.key === ':args'" :data="data" :setting-group="settingGroup" :setting="setting"/>
<sender-input v-if="senderInput(setting)" :data="data[setting.key]" :setting-group="settingGroup" :setting="setting" :parents="settingParent"/>
<!-------------------->
<el-tooltip v-if="canBeDeleted && isTablet" :content="$t('settings.removeFromDB')" placement="bottom-end" class="delete-setting-button-container">
<el-button icon="el-icon-delete" circle size="mini" class="delete-setting-button" @click="removeSetting"/>
@ -138,6 +139,7 @@ import {
RateLimitInput,
RegInvitesInput,
SelectInputWithReducedLabels,
SenderInput,
SpecificMultipleSelect } from './inputComponents'
import { getBooleanValue, processNested } from '@/store/modules/normalizers'
import _ from 'lodash'
@ -156,6 +158,7 @@ export default {
RateLimitInput,
RegInvitesInput,
SelectInputWithReducedLabels,
SenderInput,
SpecificMultipleSelect
},
props: {
@ -292,7 +295,7 @@ export default {
return this.$store.state.settings.updatedSettings
},
isImageUrl() {
return [':background', ':logo', ':nsfwCensorImage', ':default_user_avatar', ':instance_thumbnail'].includes(this.setting.key)
return Array.isArray(this.setting.type) && this.setting.type.includes('image')
}
},
methods: {
@ -357,6 +360,9 @@ export default {
renderSingleSelect(type) {
return !this.reducedSelects && (type === 'module' || (type.includes('atom') && type.includes('dropdown')))
},
senderInput({ key, type }) {
return Array.isArray(type) && type.includes('string') && type.includes('tuple') && key === ':sender'
},
update(value, group, key, parents, input, type, nested) {
const updatedValue = this.renderSingleSelect(type) ? getBooleanValue(value) : value
nested

View File

@ -8,6 +8,10 @@
<setting :setting-group="adminToken" :data="adminTokenData"/>
</el-form>
<el-divider v-if="adminToken" class="divider thick-line"/>
<el-form :model="welcomeData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="welcome" :data="welcomeData"/>
</el-form>
<el-divider v-if="welcome" class="divider thick-line"/>
<el-form :model="scheduledActivityData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="scheduledActivity" :data="scheduledActivityData"/>
</el-form>
@ -20,6 +24,10 @@
<setting :setting-group="pleromaUser" :data="pleromaUserData"/>
</el-form>
<el-divider v-if="pleromaUser" class="divider thick-line"/>
<el-form :model="faviconsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="favicons" :data="faviconsData"/>
</el-form>
<el-divider v-if="favicons" class="divider thick-line"/>
<el-form :model="uriSchemesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="uriSchemes" :data="uriSchemesData"/>
</el-form>
@ -27,7 +35,7 @@
<el-form :model="feedData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="feed" :data="feedData"/>
</el-form>
<el-divider v-if="uriSchemes" class="divider thick-line"/>
<el-divider v-if="feed" class="divider thick-line"/>
<el-form :model="streamerData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="streamer" :data="streamerData"/>
</el-form>
@ -58,6 +66,12 @@ export default {
adminTokenData() {
return _.get(this.settings.settings, [':pleroma', ':admin_token']) || {}
},
favicons() {
return this.settings.description.find(setting => setting.key === ':instances_favicons')
},
faviconsData() {
return _.get(this.settings.settings, [':pleroma', ':instances_favicons']) || {}
},
feed() {
return this.settings.description.find(setting => setting.key === ':feed')
},
@ -123,6 +137,12 @@ export default {
},
uriSchemesData() {
return _.get(this.settings.settings, [':pleroma', ':uri_schemes']) || {}
},
welcome() {
return this.settings.description.find(setting => setting.key === ':welcome')
},
welcomeData() {
return _.get(this.settings.settings, [':pleroma', ':welcome']) || {}
}
},
methods: {

View File

@ -11,6 +11,18 @@
<el-form :model="activityExpirationData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="activityExpiration" :data="activityExpirationData"/>
</el-form>
<el-divider v-if="activityExpiration" class="divider thick-line"/>
<el-form :model="connectionsPoolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="connectionsPools" :data="connectionsPoolsData"/>
</el-form>
<el-divider v-if="connectionsPools" class="divider thick-line"/>
<el-form :model="poolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="pools" :data="poolsData"/>
</el-form>
<el-divider v-if="pools" class="divider thick-line"/>
<el-form :model="hackneyPoolsData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="hackneyPools" :data="hackneyPoolsData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
</div>
@ -36,6 +48,18 @@ export default {
activityExpirationData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.ActivityExpiration']) || {}
},
connectionsPools() {
return this.settings.description.find(setting => setting.key === ':connections_pool')
},
connectionsPoolsData() {
return _.get(this.settings.settings, [':pleroma', ':connections_pool']) || {}
},
hackneyPools() {
return this.settings.description.find(setting => setting.key === ':hackney_pools')
},
hackneyPoolsData() {
return _.get(this.settings.settings, [':pleroma', ':hackney_pools']) || {}
},
isMobile() {
return this.$store.state.app.device === 'mobile'
},
@ -66,6 +90,12 @@ export default {
obanQueuesData() {
return _.get(this.settings.settings, [':pleroma', 'Oban']) || {}
},
pools() {
return this.settings.description.find(setting => setting.key === ':pools')
},
poolsData() {
return _.get(this.settings.settings, [':pleroma', ':pools']) || {}
},
workers() {
return this.settings.description.find(setting => setting.key === ':workers')
},

View File

@ -49,9 +49,6 @@ export default {
loading() {
return this.settings.loading
},
modules() {
return this.settings.description.find(setting => setting.key === ':modules')
},
mrfSettings() {
return this.settings.description.filter(el => el.tab === 'mrf')
}

View File

@ -7,6 +7,14 @@
<el-form :model="remoteIpData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="remoteIp" :data="remoteIpData"/>
</el-form>
<el-divider v-if="remoteIpData" class="divider thick-line"/>
<el-form :model="modulesData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="modules" :data="modulesData"/>
</el-form>
<el-divider v-if="castAndValidate" class="divider thick-line"/>
<el-form :model="castAndValidateData" :label-position="labelPosition" :label-width="labelWidth">
<setting :setting-group="castAndValidate" :data="castAndValidateData"/>
</el-form>
<div class="submit-button-container">
<el-button class="submit-button" type="primary" @click="onSubmit">Submit</el-button>
</div>
@ -26,6 +34,12 @@ export default {
...mapGetters([
'settings'
]),
castAndValidate() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Web.ApiSpec.CastAndValidate')
},
castAndValidateData() {
return _.get(this.settings.settings, [':pleroma', 'Pleroma.Web.ApiSpec.CastAndValidate']) || {}
},
isMobile() {
return this.$store.state.app.device === 'mobile'
},
@ -56,6 +70,12 @@ export default {
mimeTypesData() {
return _.get(this.settings.settings, [':mime']) || {}
},
modules() {
return this.settings.description.find(setting => setting.key === ':modules')
},
modulesData() {
return _.get(this.settings.settings, [':pleroma', ':modules']) || {}
},
remoteIp() {
return this.settings.description.find(setting => setting.key === 'Pleroma.Plugs.RemoteIp')
},

View File

@ -0,0 +1,98 @@
<template>
<div :data-search="setting.key || setting.group" class="sender-input">
<el-input
:value="sender.email"
placeholder="email address"
class="email-address-input"
@input="updateSender($event, 'email')"/>
<el-input
:value="sender.nickname"
placeholder="nickname"
class="nickname-input"
@input="updateSender($event, 'nickname')"/>
</div>
</template>
<script>
import { processNested } from '@/store/modules/normalizers'
export default {
name: 'SenderInput',
props: {
data: {
type: [Object, Array],
default: function() {
return {}
}
},
parents: {
type: Array,
default: function() {
return []
},
required: false
},
setting: {
type: Object,
default: function() {
return {}
}
},
settingGroup: {
type: Object,
default: function() {
return {}
}
}
},
computed: {
isDesktop() {
return this.$store.state.app.device === 'desktop'
},
settings() {
return this.$store.state.settings.settings
},
updatedSettings() {
return this.$store.state.settings.updatedSettings
},
sender() {
return Object.keys(this.data).length === 0 ? { email: null, nickname: null } : this.data
}
},
methods: {
updateSender(value, inputType) {
let data
if (inputType === 'email') {
data = { ...this.sender, email: value }
} else {
data = { ...this.sender, nickname: value }
}
this.updateSetting(data, this.settingGroup.group, this.settingGroup.key, this.setting.key, this.setting.type)
},
updateSetting(value, group, key, input, type) {
const assembledData = value.nickname
? [value.nickname, value.email]
: value.email
if (this.parents.length > 0) {
const { valueForState,
valueForUpdatedSettings,
setting } = processNested(value, assembledData, group, key, this.parents.reverse(), this.settings, this.updatedSettings)
this.$store.dispatch('UpdateSettings',
{ group, key, input: setting.key, value: valueForUpdatedSettings, type: setting.type })
this.$store.dispatch('UpdateState',
{ group, key, input: setting.key, value: valueForState })
} else {
this.$store.dispatch('UpdateSettings', { group, key, input, value: assembledData, type })
this.$store.dispatch('UpdateState', { group, key, input, value })
}
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss'>
@import '../../styles/main';
@include settings
</style>

View File

@ -20,9 +20,11 @@
allow-create
class="input"
@change="updateSetting($event, settingGroup.group, settingGroup.key, setting.key, setting.type)">
<el-option value="strip" label="strip"/>
<el-option value="auto-orient" label="auto-orient"/>
<el-option value="implode" label="implode"/>
<el-option value="strip"/>
<el-option value="auto-orient"/>
<!-- eslint-disable -->
<el-option value='{"implode", "1"}'/>
<!-- eslint-enable -->
</el-select>
</div>
</template>

View File

@ -8,4 +8,5 @@ export { default as PruneInput } from './PruneInput'
export { default as RateLimitInput } from './RateLimitInput'
export { default as RegInvitesInput } from './RegInvitesInput'
export { default as SelectInputWithReducedLabels } from './SelectInputWithReducedLabels'
export { default as SenderInput } from './SenderInput'
export { default as SpecificMultipleSelect } from './SpecificMultipleSelect'

View File

@ -6,11 +6,7 @@ export const tabs = description => {
},
'authentication': {
label: 'settings.auth',
settings: [':auth', ':ldap', ':oauth2', 'Pleroma.Web.Auth.Authenticator']
},
'auto-linker': {
label: 'settings.autoLinker',
settings: [':opts']
settings: [':auth', ':ldap', ':oauth2', 'Pleroma.Web.Auth.Authenticator', ':restrict_unauthenticated']
},
'esshd': {
label: 'settings.esshd',
@ -22,7 +18,7 @@ export const tabs = description => {
},
'frontend': {
label: 'settings.frontend',
settings: [':assets', ':chat', ':emoji', ':frontend_configurations', ':markup', ':static_fe']
settings: [':assets', ':chat', ':frontends', ':emoji', ':frontend_configurations', ':markup', ':static_fe']
},
'gopher': {
label: 'settings.gopher',
@ -34,11 +30,15 @@ export const tabs = description => {
},
'instance': {
label: 'settings.instance',
settings: [':admin_token', ':instance', ':manifest', 'Pleroma.User', 'Pleroma.ScheduledActivity', ':uri_schemes', ':feed', ':streamer']
settings: [':admin_token', ':instance', ':instances_favicons', ':welcome', ':manifest', 'Pleroma.User', 'Pleroma.ScheduledActivity', ':uri_schemes', ':feed', ':streamer']
},
'job-queue': {
label: 'settings.jobQueue',
settings: ['Pleroma.ActivityExpiration', 'Oban', ':workers']
settings: ['Pleroma.ActivityExpiration', ':connections_pool', ':hackney_pools', 'Oban', ':pools', ':workers']
},
'link-formatter': {
label: 'settings.linkFormatter',
settings: ['Pleroma.Formatter']
},
'logger': {
label: 'settings.logger',
@ -78,7 +78,7 @@ export const tabs = description => {
},
'other': {
label: 'settings.other',
settings: [':mime', 'Pleroma.Plugs.RemoteIp']
settings: [':mime', 'Pleroma.Plugs.RemoteIp', ':modules', 'Pleroma.Web.ApiSpec.CastAndValidate']
}
}
}

View File

@ -46,6 +46,10 @@
.el-tabs__header {
z-index: 2002;
}
.email-address-input {
width: 50%;
margin-right: 10px;
}
.esshd-list {
margin: 0;
}
@ -175,6 +179,9 @@
width: 30%;
margin-right: 8px
}
.nickname-input {
width: 50%;
}
.no-top-margin {
margin-top: 0;
p {
@ -254,6 +261,12 @@
margin-left: 8px;
margin-right: 10px
}
.sender-input {
display: flex;
align-items: center;
margin-bottom: 10px;
width: 100%;
}
.scale-input {
width: 47%;
margin: 0 1% 5px 0

View File

@ -223,10 +223,10 @@ describe('Parse tuples', () => {
})
it('parses match_actor setting in mrf_subchain group', () => {
const tuples = [{ tuple: [":match_actor",
{ '~r/https:\/\/example.com/s': ["Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy"]}]}]
const expectedResult = { ":match_actor":
[{ '~r/https:\/\/example.com/s': { value: ["Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy"] }}]}
const tuples = [{ tuple: [':match_actor',
{ '~r/https:\/\/example.com/s': ['Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy']}]}]
const expectedResult = { ':match_actor':
[{ '~r/https:\/\/example.com/s': { value: ['Elixir.Pleroma.Web.ActivityPub.MRF.DropPolicy'] }}]}
const parsed = parseTuples(tuples, ':mrf_subchain')
@ -241,7 +241,7 @@ describe('Parse tuples', () => {
})
it('parses options setting in MediaProxy.Invalidation.Http group', () => {
const tuples = [{ tuple: [":options", [{ tuple: [":params", { xxx: "zzz", aaa: "bbb" }]}]]}]
const tuples = [{ tuple: [':options', [{ tuple: [':params', { xxx: 'zzz', aaa: 'bbb' }]}]]}]
const expectedResult = { ':options': { ':params':
[ { xxx: { value: 'zzz' }}, { aaa: { value: 'bbb' }}]
}}
@ -260,14 +260,28 @@ describe('Parse tuples', () => {
expect(_.isEqual(expectedResult, parsed)).toBeTruthy()
})
it('parses proxy_url', () => {
const proxyUrlNull = [{ tuple: [":proxy_url", null] }]
const proxyUrlTuple = [{ tuple: [":proxy_url", { tuple: [":socks5", ":localhost", 3090] }]}]
const proxyUrlString = [{ tuple: [":proxy_url", 'localhost:9020'] }]
it('parses sender setting in :welcome', () => {
const senderEmpty = [{ tuple: [':sender', ''] }]
const senderTuple = [{ tuple: [':sender', { tuple: ['test', 'test@email.com'] }]}]
const senderString = [{ tuple: [':sender', 'test@email.com'] }]
const expectedProxyUrlNull = { ":proxy_url": { socks5: false, host: null, port: null }}
const expectedProxyUrlTuple = { ":proxy_url": { socks5: true, host: ":localhost", port: 3090 }}
const expectedProxyUrlString = { ":proxy_url": { socks5: false, host: 'localhost', port: '9020' }}
const expectedSenderEmpty = { ':sender': { email: '' }}
const expectedSenderTuple = { ':sender': { email: 'test@email.com', nickname: 'test' }}
const expectedSenderString = { ':sender': { email: 'test@email.com' }}
expect(_.isEqual(expectedSenderEmpty, parseTuples(senderEmpty, ':welcome'))).toBeTruthy()
expect(_.isEqual(expectedSenderTuple, parseTuples(senderTuple, ':welcome'))).toBeTruthy()
expect(_.isEqual(expectedSenderString, parseTuples(senderString, ':welcome'))).toBeTruthy()
})
it('parses proxy_url', () => {
const proxyUrlNull = [{ tuple: [':proxy_url', null] }]
const proxyUrlTuple = [{ tuple: [':proxy_url', { tuple: [':socks5', ':localhost', 3090] }]}]
const proxyUrlString = [{ tuple: [':proxy_url', 'localhost:9020'] }]
const expectedProxyUrlNull = { ':proxy_url': { socks5: false, host: null, port: null }}
const expectedProxyUrlTuple = { ':proxy_url': { socks5: true, host: ':localhost', port: 3090 }}
const expectedProxyUrlString = { ':proxy_url': { socks5: false, host: 'localhost', port: '9020' }}
expect(_.isEqual(expectedProxyUrlNull, parseTuples(proxyUrlNull, ':http'))).toBeTruthy()
expect(_.isEqual(expectedProxyUrlTuple, parseTuples(proxyUrlTuple, ':http'))).toBeTruthy()
@ -275,8 +289,8 @@ describe('Parse tuples', () => {
})
it('parses args setting in Pleroma.Upload.Filter.Mogrify', () => {
const tuples = [{ tuple: [":args", ["strip", { tuple: ["implode", "1"] }]]}]
const expectedResult = { ":args": ["strip", "implode"] }
const tuples = [{ tuple: [':args', ['strip', '{ "implode", "1" }']]}]
const expectedResult = { ':args': ['strip', '{ "implode", "1" }'] }
const result = parseTuples(tuples, 'Pleroma.Upload.Filter.Mogrify')
expect(_.isEqual(expectedResult, result)).toBeTruthy()
@ -284,19 +298,19 @@ describe('Parse tuples', () => {
it('parses nested tuples', () => {
const tuples = [{ tuple: [':proxy_opts', [
{ tuple: [":redirect_on_failure", false] },
{ tuple: [":max_body_length", 26214400] },
{ tuple: [":http", [
{ tuple: [":follow_redirect", true] },
{ tuple: [":pool", ":media"] }
{ tuple: [':redirect_on_failure', false] },
{ tuple: [':max_body_length', 26214400] },
{ tuple: [':http', [
{ tuple: [':follow_redirect', true] },
{ tuple: [':pool', ':media'] }
]]},
]]}]
const expectedResult = { ':proxy_opts': {
":redirect_on_failure": false,
":max_body_length": 26214400,
":http": {
":follow_redirect": true,
":pool": ":media"
':redirect_on_failure': false,
':max_body_length': 26214400,
':http': {
':follow_redirect': true,
':pool': ':media'
}
}}
const result = parseTuples(tuples, ':media_proxy')
@ -304,8 +318,8 @@ describe('Parse tuples', () => {
})
it('parses tuples with arrays', () => {
const tuples = [{ tuple: [":ignore_hosts", []]}, { tuple: [":ignore_tld", ["local", "localdomain", "lan"]]}]
const expectedResult = { ":ignore_hosts": [], ":ignore_tld": ["local", "localdomain", "lan"] }
const tuples = [{ tuple: [':ignore_hosts', []]}, { tuple: [':ignore_tld', ['local', 'localdomain', 'lan']]}]
const expectedResult = { ':ignore_hosts': [], ':ignore_tld': ['local', 'localdomain', 'lan'] }
const result = parseTuples(tuples, ':rich_media')
expect(_.isEqual(expectedResult, result)).toBeTruthy()

View File

@ -357,14 +357,14 @@ describe('Wrap settings', () => {
it('wraps args setting in Pleroma.Upload.Filter.Mogrify group', () => {
const settings = { 'Pleroma.Upload.Filter.Mogrify': { ':args': [
['string', ['list', 'string'], ['list', 'tuple']],
['strip', 'implode']
['strip', '{ "implode", "1"]}']
]}}
const state = { ':pleroma': { 'Pleroma.Upload.Filter.Mogrify': {}}}
const result = wrapUpdatedSettings(':pleroma', settings, state)
const expectedResult = [{
group: ':pleroma',
key: 'Pleroma.Upload.Filter.Mogrify',
value: [{tuple: [':args', ['strip', {tuple: ['implode', '1']}]]}]
value: [{tuple: [':args', ['strip', '{ "implode", "1"]}']]}]
}]
expect(_.isEqual(result, expectedResult)).toBeTruthy()