fix: remove the fragmentation handling stranded by #1303
#1298 and #1303 merged together. #1298 taught the creation paths to resolve a fragmentation_level default; #1303 removed everything that consumed it. Neither conflicted textually, so main ended up validating the field on create and update, copying it on duplicate, resolving default_fragmentation_level for it, and advertising it in the v1 API docs — for a value nothing reads and a setting the Image Security tab no longer exposes. Inert rather than broken, which is exactly why it needed removing on purpose: dead code that contradicts the PR that just deleted the feature is how the next reader concludes fragmentation still works. The events.fragmentation_level column and the app_settings row stay, as #1303 decided — dropping a column is irreversible and the stored values are harmless once nothing reads them. Refs #1300
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* rendered as toggles, and read by nothing:
|
||||
*
|
||||
* default_protection_level, default_image_quality,
|
||||
* enable_canvas_rendering, default_fragmentation_level
|
||||
* enable_canvas_rendering
|
||||
*
|
||||
* Each maps onto an `events` column migration 038 already created, and each
|
||||
* is labelled "… by default". `enable_devtools_protection` was the only one
|
||||
@@ -46,7 +46,7 @@ describe('image-security creation defaults', () => {
|
||||
beforeEach(async () => {
|
||||
await db('app_settings').whereIn('setting_key', [
|
||||
'default_protection_level', 'default_image_quality',
|
||||
'enable_canvas_rendering', 'default_fragmentation_level',
|
||||
'enable_canvas_rendering',
|
||||
]).del();
|
||||
});
|
||||
|
||||
@@ -60,13 +60,11 @@ describe('image-security creation defaults', () => {
|
||||
await setSetting('default_protection_level', 'enhanced');
|
||||
await setSetting('default_image_quality', 72);
|
||||
await setSetting('enable_canvas_rendering', true);
|
||||
await setSetting('default_fragmentation_level', 5);
|
||||
|
||||
expect(await getImageSecurityDefaults()).toEqual({
|
||||
protection_level: 'enhanced',
|
||||
image_quality: 72,
|
||||
use_canvas_rendering: true,
|
||||
fragmentation_level: 5,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -83,7 +81,6 @@ describe('image-security creation defaults', () => {
|
||||
['image quality above 100', 'default_image_quality', 250],
|
||||
['image quality of zero', 'default_image_quality', 0],
|
||||
['a non-numeric quality', 'default_image_quality', 'high'],
|
||||
['fragmentation above the range', 'default_fragmentation_level', 99],
|
||||
['a non-boolean canvas value', 'enable_canvas_rendering', 'yes'],
|
||||
// parseInt would have rescued each of these into a valid-looking
|
||||
// integer. The settings PUT stores values without validating them, so
|
||||
@@ -91,8 +88,6 @@ describe('image-security creation defaults', () => {
|
||||
['a numeric prefix with trailing junk', 'default_image_quality', '72oops'],
|
||||
['a fractional quality', 'default_image_quality', 72.5],
|
||||
['a single-element array', 'default_image_quality', [72]],
|
||||
['a fractional fragmentation level', 'default_fragmentation_level', 3.7],
|
||||
['a fragmentation level with trailing junk', 'default_fragmentation_level', '3x'],
|
||||
])('ignores %s and falls through to the column default', async (_label, key, value) => {
|
||||
await setSetting(key, value);
|
||||
expect(await getImageSecurityDefaults()).toEqual({});
|
||||
@@ -210,11 +205,10 @@ describe('image-security creation defaults', () => {
|
||||
it('resolves each column independently', () => {
|
||||
expect(resolveImageSecurityColumns(
|
||||
{ image_quality: 60 },
|
||||
{ protection_level: 'enhanced', fragmentation_level: 4 },
|
||||
{ protection_level: 'enhanced' },
|
||||
)).toEqual({
|
||||
protection_level: 'enhanced',
|
||||
image_quality: 60,
|
||||
fragmentation_level: 4,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -224,7 +224,6 @@ describe('admin events CRUD endpoints (smoke)', () => {
|
||||
['image_quality', [72]],
|
||||
['protection_level', ['basic']],
|
||||
['use_canvas_rendering', [false]],
|
||||
['fragmentation_level', [3]],
|
||||
// Not a protection field: the guard is not scoped to that block.
|
||||
['event_name', ['Arrayed']],
|
||||
['allow_downloads', [false]],
|
||||
|
||||
@@ -235,7 +235,6 @@ module.exports = (router) => {
|
||||
body('protection_level').optional().not().isArray().isIn(['basic', 'standard', 'enhanced', 'maximum']),
|
||||
body('use_canvas_rendering').optional().not().isArray().isBoolean().toBoolean(),
|
||||
body('image_quality').optional().not().isArray().isInt({ min: 1, max: 100 }).toInt(),
|
||||
body('fragmentation_level').optional().not().isArray().isInt({ min: 1, max: 10 }).toInt(),
|
||||
body('watermark_downloads').optional().isBoolean(),
|
||||
body('watermark_text').optional().trim(),
|
||||
// #328 follow-up: per-event opt-in for presigned-URL "Download All".
|
||||
@@ -1427,7 +1426,6 @@ module.exports = (router) => {
|
||||
protection_level: source.protection_level,
|
||||
image_quality: source.image_quality,
|
||||
use_canvas_rendering: source.use_canvas_rendering,
|
||||
fragmentation_level: source.fragmentation_level,
|
||||
watermark_downloads: source.watermark_downloads,
|
||||
watermark_text: source.watermark_text,
|
||||
allow_presigned_download: source.allow_presigned_download,
|
||||
|
||||
@@ -127,7 +127,6 @@ const getDownloadProtectionDefaults = async () => {
|
||||
* default_protection_level → events.protection_level
|
||||
* default_image_quality → events.image_quality
|
||||
* enable_canvas_rendering → events.use_canvas_rendering
|
||||
* default_fragmentation_level → events.fragmentation_level
|
||||
*
|
||||
* Each maps onto a column migration 038 already created, and each is
|
||||
* labelled "… by default", so applying them at creation is what the panel
|
||||
@@ -172,7 +171,6 @@ const getImageSecurityDefaults = async (trx = null) => {
|
||||
'default_protection_level',
|
||||
'default_image_quality',
|
||||
'enable_canvas_rendering',
|
||||
'default_fragmentation_level',
|
||||
])
|
||||
.select('setting_key', 'setting_value');
|
||||
|
||||
@@ -214,10 +212,6 @@ const getImageSecurityDefaults = async (trx = null) => {
|
||||
defaults.use_canvas_rendering = canvas;
|
||||
}
|
||||
|
||||
const fragmentation = toInteger(read('default_fragmentation_level'));
|
||||
if (fragmentation !== undefined && fragmentation >= 1 && fragmentation <= 10) {
|
||||
defaults.fragmentation_level = fragmentation;
|
||||
}
|
||||
} catch (error) {
|
||||
// A settings read must never block event creation; the column defaults
|
||||
// are a correct fallback.
|
||||
@@ -262,8 +256,6 @@ const resolveImageSecurityColumns = (body = {}, defaults = {}) => {
|
||||
const canvas = pick('use_canvas_rendering');
|
||||
if (canvas !== undefined) columns.use_canvas_rendering = formatBoolean(canvas);
|
||||
|
||||
const fragmentation = pick('fragmentation_level');
|
||||
if (fragmentation !== undefined) columns.fragmentation_level = fragmentation;
|
||||
|
||||
return columns;
|
||||
};
|
||||
|
||||
@@ -138,7 +138,6 @@ const photoUpload = async (req, res, next) => {
|
||||
* protection_level: { type: string, nullable: true, enum: [basic, standard, enhanced, maximum], description: "Image protection level. When omitted, falls back to the global default_protection_level setting." }
|
||||
* use_canvas_rendering: { type: boolean, nullable: true, description: "Render gallery images to a canvas instead of an img tag. When omitted, falls back to the global enable_canvas_rendering setting." }
|
||||
* image_quality: { type: integer, minimum: 1, maximum: 100, nullable: true, description: "Served image quality percentage. When omitted, falls back to the global default_image_quality setting." }
|
||||
* fragmentation_level: { type: integer, minimum: 1, maximum: 10, nullable: true, description: "Stored for future use; no renderer consumes it yet. When omitted, falls back to the global default_fragmentation_level setting." }
|
||||
* hero_logo_visible: { type: boolean, nullable: true, description: "Show event logo in the hero block. When omitted, falls back to the global branding_logo_display_hero setting." }
|
||||
* hero_logo_size: { type: string, nullable: true, enum: [small, medium, large, xlarge], description: "Hero logo size. When omitted, falls back to the global branding_logo_size setting." }
|
||||
* hero_logo_position: { type: string, nullable: true, enum: [top, center, bottom], description: "Hero logo position. Defaults to 'top' (not settings-backed — see migration 084)." }
|
||||
@@ -187,7 +186,6 @@ router.post(
|
||||
body('protection_level').optional().not().isArray().isIn(['basic', 'standard', 'enhanced', 'maximum']),
|
||||
body('use_canvas_rendering').optional().not().isArray().isBoolean().toBoolean(),
|
||||
body('image_quality').optional().not().isArray().isInt({ min: 1, max: 100 }).toInt(),
|
||||
body('fragmentation_level').optional().not().isArray().isInt({ min: 1, max: 10 }).toInt(),
|
||||
body('hero_logo_visible').optional().isBoolean(),
|
||||
body('hero_logo_size').optional().isIn(['small', 'medium', 'large', 'xlarge']),
|
||||
body('hero_logo_position').optional().isIn(['top', 'center', 'bottom'])
|
||||
|
||||
Reference in New Issue
Block a user