Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/js/media/models/attachments.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,17 @@ var Attachments = Backbone.Collection.extend(/** @lends wp.media.model.Attachmen
this.props.on( 'change:orderby', this._changeOrderby, this );
this.props.on( 'change:query', this._changeQuery, this );

this.props.set( _.defaults( options.props || {} ) );
options.props = _.defaults( options.props || {} );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_.defaults() only adds properties from the source object if they don't exist in the target. Since options.props || {} creates a fresh object. Direct assignment is cleaner.


// Normalize the order if it exists.
if ( 'string' === typeof options.props.order ) {
options.props.order = options.props.order.toUpperCase();
if ( 'ASC' !== options.props.order && 'DESC' !== options.props.order ) {
options.props.order = 'DESC';
}
Comment on lines +51 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
options.props.order = options.props.order.toUpperCase();
if ( 'ASC' !== options.props.order && 'DESC' !== options.props.order ) {
options.props.order = 'DESC';
}
const normalizedOrder = options.props.order.toUpperCase();
options.props.order = ( 'ASC' === normalizedOrder || 'DESC' === normalizedOrder )
? normalizedOrder
: 'DESC';

Simplified

}

this.props.set( options.props );

if ( options.observe ) {
this.observe( options.observe );
Expand Down
6 changes: 0 additions & 6 deletions src/js/media/models/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,6 @@ Query = Attachments.extend(/** @lends wp.media.model.Query.prototype */{
// Fill default args.
_.defaults( props, defaults );

// Normalize the order.
props.order = props.order.toUpperCase();
if ( 'DESC' !== props.order && 'ASC' !== props.order ) {
props.order = defaults.order.toUpperCase();
}

// Ensure we have a valid orderby value.
if ( ! _.contains( orderby.allowed, props.orderby ) ) {
props.orderby = defaults.orderby;
Expand Down
1 change: 1 addition & 0 deletions tests/qunit/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
<script src="wp-admin/js/customize-header.js"></script>
<script src="wp-admin/js/dashboard.js"></script>
<script src="wp-includes/js/shortcode.js"></script>
<script src="wp-includes/js/media/test-media-models.js"></script>
<script src="wp-includes/js/api-request.js"></script>
<script src="wp-includes/js/jquery.js"></script>
<script src="wp-includes/js/wp-api.js"></script>
Expand Down
248 changes: 248 additions & 0 deletions tests/qunit/wp-includes/js/media/test-media-models.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
/* globals wp */
/* jshint qunit: true */
/* eslint-env qunit */
/* eslint-disable no-magic-numbers */

( function() {
'use strict';

QUnit.module( 'Media Models - Order Normalization' );

// Test valid uppercase values
QUnit.test( 'Attachments should accept uppercase "ASC" order', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'ASC'
}
});

assert.strictEqual( collection.props.get('order'), 'ASC',
'Order should remain ASC when passed as uppercase' );
});

QUnit.test( 'Attachments should accept uppercase "DESC" order', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'DESC'
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Order should remain DESC when passed as uppercase' );
});

// Test lowercase normalization
QUnit.test( 'Attachments should normalize lowercase "asc" to uppercase', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'asc'
}
});

assert.strictEqual( collection.props.get('order'), 'ASC',
'Order should be converted from lowercase asc to uppercase ASC' );
});

QUnit.test( 'Attachments should normalize lowercase "desc" to uppercase', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'desc'
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Order should be converted from lowercase desc to uppercase DESC' );
});

// Test mixed case normalization
QUnit.test( 'Attachments should normalize mixed case "AsC" to uppercase', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'AsC'
}
});

assert.strictEqual( collection.props.get('order'), 'ASC',
'Order should be converted from mixed case AsC to uppercase ASC' );
});

QUnit.test( 'Attachments should normalize mixed case "DeSc" to uppercase', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'DeSc'
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Order should be converted from mixed case DeSc to uppercase DESC' );
});

// Test invalid string values
QUnit.test( 'Attachments should default invalid string order to "DESC"', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'invalid'
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Invalid string order should default to DESC' );
});

QUnit.test( 'Attachments should default empty string order to "DESC"', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: ''
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Empty string order should default to DESC' );
});

// Test non-string type edge cases
QUnit.test( 'Attachments should not process null order value', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: null
}
});

assert.strictEqual( collection.props.get('order'), null,
'Null order should remain null (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process undefined order value', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: undefined
}
});

assert.strictEqual( collection.props.get('order'), undefined,
'Undefined order should remain undefined (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process numeric order value', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 123
}
});

assert.strictEqual( collection.props.get('order'), 123,
'Numeric order should remain unchanged (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process boolean true order value', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: true
}
});

assert.strictEqual( collection.props.get('order'), true,
'Boolean true order should remain unchanged (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process boolean false order value', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: false
}
});

assert.strictEqual( collection.props.get('order'), false,
'Boolean false order should remain unchanged (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process object order value', function( assert ) {
var orderObj = { value: 'ASC' };
var collection = new wp.media.model.Attachments( [], {
props: {
order: orderObj
}
});

assert.strictEqual( collection.props.get('order'), orderObj,
'Object order should remain unchanged (not processed by normalization)' );
});

QUnit.test( 'Attachments should not process array order value', function( assert ) {
var orderArray = ['ASC', 'DESC'];
var collection = new wp.media.model.Attachments( [], {
props: {
order: orderArray
}
});

assert.strictEqual( collection.props.get('order'), orderArray,
'Array order should remain unchanged (not processed by normalization)' );
});

// Test when no order property is provided
QUnit.test( 'Attachments should work when no order property is provided', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
orderby: 'date'
}
});

assert.strictEqual( collection.props.get('order'), undefined,
'Order should be undefined when not provided' );
});

// Test Query model inheritance
QUnit.test( 'Query should inherit order normalization from Attachments', function( assert ) {
var query = new wp.media.model.Query( [], {
props: {
order: 'asc',
query: true
}
});

assert.strictEqual( query.props.get('order'), 'ASC',
'Query model should normalize order through inheritance from Attachments' );
assert.ok( query instanceof wp.media.model.Attachments,
'Query should be instance of Attachments' );
});

QUnit.test( 'Query should default invalid order to "DESC"', function( assert ) {
var query = new wp.media.model.Query( [], {
props: {
order: 'random',
query: true
}
});

assert.strictEqual( query.props.get('order'), 'DESC',
'Query model should default invalid order to DESC' );
});

// Test whitespace handling
QUnit.test( 'Attachments should handle order with whitespace', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: ' asc '
}
});

assert.notStrictEqual( collection.props.get('order'), 'ASC',
'Order with whitespace should not match ASC exactly' );
assert.strictEqual( collection.props.get('order'), 'DESC',
'Order with whitespace should default to DESC as it does not match ASC/DESC after toUpperCase' );
});

// Test unicode characters
QUnit.test( 'Attachments should handle order with unicode characters', function( assert ) {
var collection = new wp.media.model.Attachments( [], {
props: {
order: 'asc\u200B' // Zero-width space
}
});

assert.strictEqual( collection.props.get('order'), 'DESC',
'Order with unicode characters should default to DESC' );
});

})();
Loading