normalizeInstance: break out instance normalization into its own module

merge-requests/1049/head
Alex Gleason 3 years ago
parent 71378d8764
commit 16da9030ac
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -0,0 +1,101 @@
import { Map as ImmutableMap, fromJS } from 'immutable';
import { normalizeInstance } from '../instance';
describe('normalizeInstance()', () => {
it('normalizes an empty Map', () => {
const expected = ImmutableMap({
description_limit: 1500,
configuration: ImmutableMap({
statuses: ImmutableMap({
max_characters: 500,
max_media_attachments: 4,
}),
polls: ImmutableMap({
max_options: 4,
max_characters_per_option: 25,
min_expiration: 300,
max_expiration: 2629746,
}),
}),
version: '0.0.0',
});
const result = normalizeInstance(ImmutableMap());
expect(result).toEqual(expected);
});
it('normalizes Pleroma instance with Mastodon configuration format', () => {
const instance = fromJS(require('soapbox/__fixtures__/pleroma-instance.json'));
const expected = {
configuration: {
statuses: {
max_characters: 5000,
max_media_attachments: Infinity,
},
polls: {
max_options: 20,
max_characters_per_option: 200,
min_expiration: 0,
max_expiration: 31536000,
},
},
};
const result = normalizeInstance(instance);
expect(result.toJS()).toMatchObject(expected);
});
it('normalizes Mastodon instance with retained configuration', () => {
const instance = fromJS(require('soapbox/__fixtures__/mastodon-instance.json'));
const expected = {
configuration: {
statuses: {
max_characters: 500,
max_media_attachments: 4,
characters_reserved_per_url: 23,
},
media_attachments: {
image_size_limit: 10485760,
image_matrix_limit: 16777216,
video_size_limit: 41943040,
video_frame_rate_limit: 60,
video_matrix_limit: 2304000,
},
polls: {
max_options: 4,
max_characters_per_option: 50,
min_expiration: 300,
max_expiration: 2629746,
},
},
};
const result = normalizeInstance(instance);
expect(result.toJS()).toMatchObject(expected);
});
it('normalizes Mastodon 3.0.0 instance with default configuration', () => {
const instance = fromJS(require('soapbox/__fixtures__/mastodon-3.0.0-instance.json'));
const expected = {
configuration: {
statuses: {
max_characters: 500,
max_media_attachments: 4,
},
polls: {
max_options: 4,
max_characters_per_option: 25,
min_expiration: 300,
max_expiration: 2629746,
},
},
};
const result = normalizeInstance(instance);
expect(result.toJS()).toMatchObject(expected);
});
});

@ -0,0 +1,65 @@
import { Map as ImmutableMap } from 'immutable';
import { parseVersion, PLEROMA } from 'soapbox/utils/features';
import { isNumber } from 'soapbox/utils/numbers';
// Use Mastodon defaults
const baseInstance = ImmutableMap({
description_limit: 1500,
configuration: ImmutableMap({
statuses: ImmutableMap({
max_characters: 500,
max_media_attachments: 4,
}),
polls: ImmutableMap({
max_options: 4,
max_characters_per_option: 25,
min_expiration: 300,
max_expiration: 2629746,
}),
}),
version: '0.0.0',
});
// Build Mastodon configuration from Pleroma instance
const pleromaToMastodonConfig = instance => {
return ImmutableMap({
statuses: ImmutableMap({
max_characters: instance.get('max_toot_chars'),
}),
polls: ImmutableMap({
max_options: instance.getIn(['poll_limits', 'max_options']),
max_characters_per_option: instance.getIn(['poll_limits', 'max_option_chars']),
min_expiration: instance.getIn(['poll_limits', 'min_expiration']),
max_expiration: instance.getIn(['poll_limits', 'max_expiration']),
}),
});
};
// Use new value only if old value is undefined
const mergeDefined = (oldVal, newVal) => oldVal === undefined ? newVal : oldVal;
// Get the software's default attachment limit
const getAttachmentLimit = software => software === PLEROMA ? Infinity : 4;
// Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format
export const normalizeInstance = instance => {
const { software } = parseVersion(instance.get('version'));
const mastodonConfig = pleromaToMastodonConfig(instance);
return instance.withMutations(instance => {
// Merge configuration
instance.update('configuration', ImmutableMap(), configuration => (
configuration.mergeDeepWith(mergeDefined, mastodonConfig)
));
// If max attachments isn't set, check the backend software
instance.updateIn(['configuration', 'statuses', 'max_media_attachments'], value => {
return isNumber(value) ? value : getAttachmentLimit(software);
});
// Merge defaults & cleanup
instance.mergeDeepWith(mergeDefined, baseInstance);
instance.deleteAll(['max_toot_chars', 'poll_limits']);
});
};

@ -2,10 +2,9 @@ import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import { ADMIN_CONFIG_UPDATE_REQUEST, ADMIN_CONFIG_UPDATE_SUCCESS } from 'soapbox/actions/admin';
import { PLEROMA_PRELOAD_IMPORT } from 'soapbox/actions/preload';
import { normalizeInstance } from 'soapbox/normalizers/instance';
import KVStore from 'soapbox/storage/kv_store';
import { ConfigDB } from 'soapbox/utils/config_db';
import { parseVersion, PLEROMA } from 'soapbox/utils/features';
import { isNumber } from 'soapbox/utils/numbers';
import {
INSTANCE_REMEMBER_SUCCESS,
@ -14,6 +13,8 @@ import {
NODEINFO_FETCH_SUCCESS,
} from '../actions/instance';
const initialState = normalizeInstance(ImmutableMap());
const nodeinfoToInstance = nodeinfo => {
// Match Pleroma's develop branch
return ImmutableMap({
@ -30,67 +31,6 @@ const nodeinfoToInstance = nodeinfo => {
});
};
// Use Mastodon defaults
const initialState = ImmutableMap({
description_limit: 1500,
configuration: ImmutableMap({
statuses: ImmutableMap({
max_characters: 500,
max_media_attachments: 4,
}),
polls: ImmutableMap({
max_options: 4,
max_characters_per_option: 25,
min_expiration: 300,
max_expiration: 2629746,
}),
}),
version: '0.0.0',
});
// Build Mastodon configuration from Pleroma instance
const pleromaToMastodonConfig = instance => {
return ImmutableMap({
statuses: ImmutableMap({
max_characters: instance.get('max_toot_chars'),
}),
polls: ImmutableMap({
max_options: instance.getIn(['poll_limits', 'max_options']),
max_characters_per_option: instance.getIn(['poll_limits', 'max_option_chars']),
min_expiration: instance.getIn(['poll_limits', 'min_expiration']),
max_expiration: instance.getIn(['poll_limits', 'max_expiration']),
}),
});
};
// Use new value only if old value is undefined
const mergeDefined = (oldVal, newVal) => oldVal === undefined ? newVal : oldVal;
// Get the software's default attachment limit
const getAttachmentLimit = software => software === PLEROMA ? Infinity : 4;
// Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format
const normalizeInstance = instance => {
const { software } = parseVersion(instance.get('version'));
const mastodonConfig = pleromaToMastodonConfig(instance);
return instance.withMutations(instance => {
// Merge configuration
instance.update('configuration', ImmutableMap(), configuration => (
configuration.mergeDeepWith(mergeDefined, mastodonConfig)
));
// If max attachments isn't set, check the backend software
instance.updateIn(['configuration', 'statuses', 'max_media_attachments'], value => {
return isNumber(value) ? value : getAttachmentLimit(software);
});
// Merge defaults & cleanup
instance.mergeDeepWith(mergeDefined, initialState);
instance.deleteAll(['max_toot_chars', 'poll_limits']);
});
};
const importInstance = (state, instance) => {
return normalizeInstance(instance);
};

Loading…
Cancel
Save