initial commit
This commit is contained in:
parent
d066133bd4
commit
e6f71e3706
55 changed files with 11928 additions and 0 deletions
40
native/wordpress/maple-fonts-wp/tests/bootstrap.php
Normal file
40
native/wordpress/maple-fonts-wp/tests/bootstrap.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPUnit bootstrap file for Maple Local Fonts.
|
||||
*
|
||||
* @package Maple_Local_Fonts
|
||||
*/
|
||||
|
||||
// Composer autoloader.
|
||||
$autoload = dirname(__DIR__) . '/vendor/autoload.php';
|
||||
if (file_exists($autoload)) {
|
||||
require_once $autoload;
|
||||
}
|
||||
|
||||
// Get the tests directory.
|
||||
$_tests_dir = getenv('WP_TESTS_DIR');
|
||||
|
||||
// Try to find the WP test suite.
|
||||
if (!$_tests_dir) {
|
||||
$_tests_dir = rtrim(sys_get_temp_dir(), '/\\') . '/wordpress-tests-lib';
|
||||
}
|
||||
|
||||
// Check if the test suite exists.
|
||||
if (!file_exists($_tests_dir . '/includes/functions.php')) {
|
||||
echo "Could not find $_tests_dir/includes/functions.php, have you run bin/install-wp-tests.sh?" . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Give access to tests_add_filter() function.
|
||||
require_once $_tests_dir . '/includes/functions.php';
|
||||
|
||||
/**
|
||||
* Manually load the plugin being tested.
|
||||
*/
|
||||
function _manually_load_plugin() {
|
||||
require dirname(__DIR__) . '/maple-local-fonts.php';
|
||||
}
|
||||
tests_add_filter('muplugins_loaded', '_manually_load_plugin');
|
||||
|
||||
// Start up the WP testing environment.
|
||||
require $_tests_dir . '/includes/bootstrap.php';
|
||||
2
native/wordpress/maple-fonts-wp/tests/index.php
Normal file
2
native/wordpress/maple-fonts-wp/tests/index.php
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<?php
|
||||
// Silence is golden.
|
||||
426
native/wordpress/maple-fonts-wp/tests/test-ajax-handler.php
Normal file
426
native/wordpress/maple-fonts-wp/tests/test-ajax-handler.php
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for MLF_Ajax_Handler class.
|
||||
*
|
||||
* @package Maple_Local_Fonts
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Test_MLF_Ajax_Handler
|
||||
*
|
||||
* @covers MLF_Ajax_Handler
|
||||
*/
|
||||
class Test_MLF_Ajax_Handler extends WP_Ajax_UnitTestCase {
|
||||
|
||||
/**
|
||||
* Admin user ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $admin_id;
|
||||
|
||||
/**
|
||||
* Subscriber user ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $subscriber_id;
|
||||
|
||||
/**
|
||||
* Set up test fixtures.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
|
||||
// Create users
|
||||
$this->admin_id = $this->factory->user->create(['role' => 'administrator']);
|
||||
$this->subscriber_id = $this->factory->user->create(['role' => 'subscriber']);
|
||||
|
||||
// Initialize the handler
|
||||
new MLF_Ajax_Handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after tests.
|
||||
*/
|
||||
public function tear_down() {
|
||||
// Clean up test fonts
|
||||
$fonts = get_posts([
|
||||
'post_type' => 'wp_font_family',
|
||||
'posts_per_page' => -1,
|
||||
'meta_key' => '_mlf_imported',
|
||||
'meta_value' => '1',
|
||||
'fields' => 'ids',
|
||||
]);
|
||||
|
||||
foreach ($fonts as $font_id) {
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
wp_set_current_user(0);
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
|
||||
parent::tear_down();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download without nonce.
|
||||
*/
|
||||
public function test_download_without_nonce() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Security', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with invalid nonce.
|
||||
*/
|
||||
public function test_download_with_invalid_nonce() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = 'invalid_nonce';
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download without proper capability.
|
||||
*/
|
||||
public function test_download_without_capability() {
|
||||
wp_set_current_user($this->subscriber_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Unauthorized', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with empty font name.
|
||||
*/
|
||||
public function test_download_empty_font_name() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = '';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('required', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with invalid font name (XSS attempt).
|
||||
*/
|
||||
public function test_download_invalid_font_name_xss() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = '<script>alert("xss")</script>';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Invalid font name', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with path traversal in font name.
|
||||
*/
|
||||
public function test_download_path_traversal() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = '../../../etc/passwd';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Invalid font name', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with font name too long.
|
||||
*/
|
||||
public function test_download_font_name_too_long() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = str_repeat('a', 101);
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('too long', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with no weights.
|
||||
*/
|
||||
public function test_download_no_weights() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [];
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('weight', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with invalid weights.
|
||||
*/
|
||||
public function test_download_invalid_weights() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [999, 1000]; // Invalid weights
|
||||
$_POST['styles'] = ['normal'];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('weight', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test download with no styles.
|
||||
*/
|
||||
public function test_download_no_styles() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_download_font');
|
||||
$_POST['font_name'] = 'Open Sans';
|
||||
$_POST['weights'] = [400];
|
||||
$_POST['styles'] = [];
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_download_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('style', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete without nonce.
|
||||
*/
|
||||
public function test_delete_without_nonce() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$font_id = $this->create_test_font();
|
||||
$_POST['font_id'] = $font_id;
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_delete_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete without capability.
|
||||
*/
|
||||
public function test_delete_without_capability() {
|
||||
wp_set_current_user($this->subscriber_id);
|
||||
|
||||
$font_id = $this->create_test_font();
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_delete_font');
|
||||
$_POST['font_id'] = $font_id;
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_delete_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Unauthorized', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete with invalid font ID.
|
||||
*/
|
||||
public function test_delete_invalid_font_id() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_delete_font');
|
||||
$_POST['font_id'] = 0;
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_delete_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('Invalid', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete font not found.
|
||||
*/
|
||||
public function test_delete_font_not_found() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_delete_font');
|
||||
$_POST['font_id'] = 99999;
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_delete_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('not found', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete font not imported by plugin.
|
||||
*/
|
||||
public function test_delete_font_not_ours() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
// Create font without our meta
|
||||
$font_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_family',
|
||||
'post_title' => 'Theme Font',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$_POST['nonce'] = wp_create_nonce('mlf_delete_font');
|
||||
$_POST['font_id'] = $font_id;
|
||||
|
||||
$this->expectException('WPAjaxDieStopException');
|
||||
|
||||
try {
|
||||
$this->_handleAjax('mlf_delete_font');
|
||||
} catch (WPAjaxDieStopException $e) {
|
||||
$response = json_decode($this->_last_response, true);
|
||||
$this->assertFalse($response['success']);
|
||||
$this->assertStringContainsString('not imported', $response['data']['message']);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a test font.
|
||||
*
|
||||
* @return int Font ID.
|
||||
*/
|
||||
private function create_test_font() {
|
||||
$font_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_family',
|
||||
'post_title' => 'Test Font',
|
||||
'post_name' => 'test-font',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
update_post_meta($font_id, '_mlf_imported', '1');
|
||||
|
||||
return $font_id;
|
||||
}
|
||||
}
|
||||
303
native/wordpress/maple-fonts-wp/tests/test-font-registry.php
Normal file
303
native/wordpress/maple-fonts-wp/tests/test-font-registry.php
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for MLF_Font_Registry class.
|
||||
*
|
||||
* @package Maple_Local_Fonts
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Test_MLF_Font_Registry
|
||||
*
|
||||
* @covers MLF_Font_Registry
|
||||
*/
|
||||
class Test_MLF_Font_Registry extends WP_UnitTestCase {
|
||||
|
||||
/**
|
||||
* Font registry instance.
|
||||
*
|
||||
* @var MLF_Font_Registry
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* Set up test fixtures.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
$this->registry = new MLF_Font_Registry();
|
||||
|
||||
// Clear font cache
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after tests.
|
||||
*/
|
||||
public function tear_down() {
|
||||
// Clean up any test fonts
|
||||
$fonts = get_posts([
|
||||
'post_type' => 'wp_font_family',
|
||||
'posts_per_page' => -1,
|
||||
'meta_key' => '_mlf_imported',
|
||||
'meta_value' => '1',
|
||||
'fields' => 'ids',
|
||||
]);
|
||||
|
||||
foreach ($fonts as $font_id) {
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
parent::tear_down();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that get_imported_fonts returns empty array when no fonts installed.
|
||||
*/
|
||||
public function test_get_imported_fonts_empty() {
|
||||
$fonts = $this->registry->get_imported_fonts();
|
||||
$this->assertIsArray($fonts);
|
||||
$this->assertEmpty($fonts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test font registration.
|
||||
*/
|
||||
public function test_register_font() {
|
||||
$font_name = 'Test Font';
|
||||
$font_slug = 'test-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/test-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
// Create a dummy file for the test
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
$result = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
|
||||
$this->assertIsInt($result);
|
||||
$this->assertGreaterThan(0, $result);
|
||||
|
||||
// Verify font was registered
|
||||
$font = get_post($result);
|
||||
$this->assertEquals('wp_font_family', $font->post_type);
|
||||
$this->assertEquals($font_name, $font->post_title);
|
||||
|
||||
// Clean up
|
||||
unlink($files[0]['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that duplicate fonts are rejected.
|
||||
*/
|
||||
public function test_register_font_duplicate() {
|
||||
$font_name = 'Duplicate Font';
|
||||
$font_slug = 'duplicate-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/duplicate-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
// Register first time
|
||||
$result1 = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
$this->assertIsInt($result1);
|
||||
|
||||
// Try to register again
|
||||
$result2 = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
$this->assertWPError($result2);
|
||||
$this->assertEquals('font_exists', $result2->get_error_code());
|
||||
|
||||
// Clean up
|
||||
unlink($files[0]['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_imported_fonts returns registered fonts.
|
||||
*/
|
||||
public function test_get_imported_fonts_returns_fonts() {
|
||||
$font_name = 'Listed Font';
|
||||
$font_slug = 'listed-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/listed-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
[
|
||||
'path' => '/tmp/listed-font_normal_700.woff2',
|
||||
'weight' => '700',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($files as $file) {
|
||||
file_put_contents($file['path'], 'wOF2dummy');
|
||||
}
|
||||
|
||||
$font_id = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
|
||||
// Clear cache to test fresh retrieval
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
|
||||
$fonts = $this->registry->get_imported_fonts();
|
||||
|
||||
$this->assertCount(1, $fonts);
|
||||
$this->assertEquals($font_id, $fonts[0]['id']);
|
||||
$this->assertEquals($font_name, $fonts[0]['name']);
|
||||
$this->assertEquals($font_slug, $fonts[0]['slug']);
|
||||
$this->assertCount(2, $fonts[0]['variants']);
|
||||
|
||||
// Clean up
|
||||
foreach ($files as $file) {
|
||||
unlink($file['path']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test font deletion.
|
||||
*/
|
||||
public function test_delete_font() {
|
||||
$font_name = 'Delete Font';
|
||||
$font_slug = 'delete-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/delete-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
$font_id = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
|
||||
// Delete the font
|
||||
$result = $this->registry->delete_font($font_id);
|
||||
$this->assertTrue($result);
|
||||
|
||||
// Verify font is gone
|
||||
$font = get_post($font_id);
|
||||
$this->assertNull($font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_font rejects non-existent fonts.
|
||||
*/
|
||||
public function test_delete_font_not_found() {
|
||||
$result = $this->registry->delete_font(99999);
|
||||
$this->assertWPError($result);
|
||||
$this->assertEquals('not_found', $result->get_error_code());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_font rejects fonts not imported by plugin.
|
||||
*/
|
||||
public function test_delete_font_not_ours() {
|
||||
// Create a font family post without our meta
|
||||
$font_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_family',
|
||||
'post_title' => 'Theme Font',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$result = $this->registry->delete_font($font_id);
|
||||
$this->assertWPError($result);
|
||||
$this->assertEquals('not_ours', $result->get_error_code());
|
||||
|
||||
// Clean up
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cache is cleared on register.
|
||||
*/
|
||||
public function test_cache_cleared_on_register() {
|
||||
// Set a dummy cache
|
||||
set_transient('mlf_imported_fonts_list', ['cached' => true], 300);
|
||||
|
||||
$font_name = 'Cache Test Font';
|
||||
$font_slug = 'cache-test-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/cache-test-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
$this->registry->register_font($font_name, $font_slug, $files);
|
||||
|
||||
// Cache should be cleared
|
||||
$cached = get_transient('mlf_imported_fonts_list');
|
||||
$this->assertFalse($cached);
|
||||
|
||||
// Clean up
|
||||
unlink($files[0]['path']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that cache is cleared on delete.
|
||||
*/
|
||||
public function test_cache_cleared_on_delete() {
|
||||
$font_name = 'Cache Delete Font';
|
||||
$font_slug = 'cache-delete-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/cache-delete-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
$font_id = $this->registry->register_font($font_name, $font_slug, $files);
|
||||
|
||||
// Set a dummy cache
|
||||
set_transient('mlf_imported_fonts_list', ['cached' => true], 300);
|
||||
|
||||
$this->registry->delete_font($font_id);
|
||||
|
||||
// Cache should be cleared
|
||||
$cached = get_transient('mlf_imported_fonts_list');
|
||||
$this->assertFalse($cached);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test font_exists method.
|
||||
*/
|
||||
public function test_font_exists() {
|
||||
$font_name = 'Exists Font';
|
||||
$font_slug = 'exists-font';
|
||||
$files = [
|
||||
[
|
||||
'path' => '/tmp/exists-font_normal_400.woff2',
|
||||
'weight' => '400',
|
||||
'style' => 'normal',
|
||||
],
|
||||
];
|
||||
|
||||
file_put_contents($files[0]['path'], 'wOF2dummy');
|
||||
|
||||
// Before registration
|
||||
$this->assertFalse($this->registry->font_exists($font_slug));
|
||||
|
||||
// After registration
|
||||
$this->registry->register_font($font_name, $font_slug, $files);
|
||||
$this->assertTrue($this->registry->font_exists($font_slug));
|
||||
|
||||
// Clean up
|
||||
unlink($files[0]['path']);
|
||||
}
|
||||
}
|
||||
177
native/wordpress/maple-fonts-wp/tests/test-rate-limiter.php
Normal file
177
native/wordpress/maple-fonts-wp/tests/test-rate-limiter.php
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for MLF_Rate_Limiter class.
|
||||
*
|
||||
* @package Maple_Local_Fonts
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Test_MLF_Rate_Limiter
|
||||
*
|
||||
* @covers MLF_Rate_Limiter
|
||||
*/
|
||||
class Test_MLF_Rate_Limiter extends WP_UnitTestCase {
|
||||
|
||||
/**
|
||||
* Rate limiter instance.
|
||||
*
|
||||
* @var MLF_Rate_Limiter
|
||||
*/
|
||||
private $rate_limiter;
|
||||
|
||||
/**
|
||||
* Set up test fixtures.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
$this->rate_limiter = new MLF_Rate_Limiter(3, 60); // 3 requests per 60 seconds
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after tests.
|
||||
*/
|
||||
public function tear_down() {
|
||||
// Clear any transients
|
||||
$this->rate_limiter->clear('test_action');
|
||||
parent::tear_down();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that first request is not limited.
|
||||
*/
|
||||
public function test_first_request_not_limited() {
|
||||
$this->assertFalse($this->rate_limiter->is_limited('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remaining count starts at limit.
|
||||
*/
|
||||
public function test_remaining_starts_at_limit() {
|
||||
$this->assertEquals(3, $this->rate_limiter->get_remaining('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that check_and_record allows requests within limit.
|
||||
*/
|
||||
public function test_check_and_record_allows_within_limit() {
|
||||
$this->assertTrue($this->rate_limiter->check_and_record('test_action'));
|
||||
$this->assertTrue($this->rate_limiter->check_and_record('test_action'));
|
||||
$this->assertTrue($this->rate_limiter->check_and_record('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that check_and_record blocks after limit exceeded.
|
||||
*/
|
||||
public function test_check_and_record_blocks_after_limit() {
|
||||
// Use up all allowed requests
|
||||
$this->rate_limiter->check_and_record('test_action');
|
||||
$this->rate_limiter->check_and_record('test_action');
|
||||
$this->rate_limiter->check_and_record('test_action');
|
||||
|
||||
// Next request should be blocked
|
||||
$this->assertFalse($this->rate_limiter->check_and_record('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that remaining count decreases correctly.
|
||||
*/
|
||||
public function test_remaining_decreases() {
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->assertEquals(2, $this->rate_limiter->get_remaining('test_action'));
|
||||
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->assertEquals(1, $this->rate_limiter->get_remaining('test_action'));
|
||||
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->assertEquals(0, $this->rate_limiter->get_remaining('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that is_limited returns true after limit exceeded.
|
||||
*/
|
||||
public function test_is_limited_after_exceeding() {
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
|
||||
$this->assertTrue($this->rate_limiter->is_limited('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that clear resets the rate limit.
|
||||
*/
|
||||
public function test_clear_resets_limit() {
|
||||
// Use up all requests
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
|
||||
$this->assertTrue($this->rate_limiter->is_limited('test_action'));
|
||||
|
||||
// Clear and verify reset
|
||||
$this->rate_limiter->clear('test_action');
|
||||
$this->assertFalse($this->rate_limiter->is_limited('test_action'));
|
||||
$this->assertEquals(3, $this->rate_limiter->get_remaining('test_action'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that different actions are tracked separately.
|
||||
*/
|
||||
public function test_different_actions_tracked_separately() {
|
||||
// Use up all requests for action1
|
||||
$this->rate_limiter->record_request('action1');
|
||||
$this->rate_limiter->record_request('action1');
|
||||
$this->rate_limiter->record_request('action1');
|
||||
|
||||
// action1 should be limited
|
||||
$this->assertTrue($this->rate_limiter->is_limited('action1'));
|
||||
|
||||
// action2 should not be limited
|
||||
$this->assertFalse($this->rate_limiter->is_limited('action2'));
|
||||
$this->assertEquals(3, $this->rate_limiter->get_remaining('action2'));
|
||||
|
||||
// Clean up
|
||||
$this->rate_limiter->clear('action1');
|
||||
$this->rate_limiter->clear('action2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that logged in user uses user ID for tracking.
|
||||
*/
|
||||
public function test_logged_in_user_tracking() {
|
||||
// Create and log in a user
|
||||
$user_id = $this->factory->user->create(['role' => 'administrator']);
|
||||
wp_set_current_user($user_id);
|
||||
|
||||
// Use up requests
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
$this->rate_limiter->record_request('test_action');
|
||||
|
||||
$this->assertTrue($this->rate_limiter->is_limited('test_action'));
|
||||
|
||||
// Clean up
|
||||
wp_set_current_user(0);
|
||||
$this->rate_limiter->clear('test_action');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test constructor with custom limits.
|
||||
*/
|
||||
public function test_custom_limits() {
|
||||
$custom_limiter = new MLF_Rate_Limiter(5, 120);
|
||||
|
||||
$this->assertEquals(5, $custom_limiter->get_remaining('custom_action'));
|
||||
|
||||
// Use 5 requests
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$this->assertTrue($custom_limiter->check_and_record('custom_action'));
|
||||
}
|
||||
|
||||
// 6th should be blocked
|
||||
$this->assertFalse($custom_limiter->check_and_record('custom_action'));
|
||||
|
||||
// Clean up
|
||||
$custom_limiter->clear('custom_action');
|
||||
}
|
||||
}
|
||||
387
native/wordpress/maple-fonts-wp/tests/test-rest-controller.php
Normal file
387
native/wordpress/maple-fonts-wp/tests/test-rest-controller.php
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
<?php
|
||||
/**
|
||||
* Tests for MLF_Rest_Controller class.
|
||||
*
|
||||
* @package Maple_Local_Fonts
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Test_MLF_Rest_Controller
|
||||
*
|
||||
* @covers MLF_Rest_Controller
|
||||
*/
|
||||
class Test_MLF_Rest_Controller extends WP_Test_REST_Controller_Testcase {
|
||||
|
||||
/**
|
||||
* REST controller instance.
|
||||
*
|
||||
* @var MLF_Rest_Controller
|
||||
*/
|
||||
private $controller;
|
||||
|
||||
/**
|
||||
* Admin user ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $admin_id;
|
||||
|
||||
/**
|
||||
* Subscriber user ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $subscriber_id;
|
||||
|
||||
/**
|
||||
* Set up test fixtures.
|
||||
*/
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
|
||||
// Register REST routes
|
||||
$this->controller = new MLF_Rest_Controller();
|
||||
$this->controller->register_routes();
|
||||
|
||||
// Create users
|
||||
$this->admin_id = $this->factory->user->create(['role' => 'administrator']);
|
||||
$this->subscriber_id = $this->factory->user->create(['role' => 'subscriber']);
|
||||
|
||||
// Clear any existing fonts and cache
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after tests.
|
||||
*/
|
||||
public function tear_down() {
|
||||
// Clean up test fonts
|
||||
$fonts = get_posts([
|
||||
'post_type' => 'wp_font_family',
|
||||
'posts_per_page' => -1,
|
||||
'meta_key' => '_mlf_imported',
|
||||
'meta_value' => '1',
|
||||
'fields' => 'ids',
|
||||
]);
|
||||
|
||||
foreach ($fonts as $font_id) {
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
wp_set_current_user(0);
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
|
||||
parent::tear_down();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test route registration.
|
||||
*/
|
||||
public function test_register_routes() {
|
||||
$routes = rest_get_server()->get_routes();
|
||||
|
||||
$this->assertArrayHasKey('/mlf/v1/fonts', $routes);
|
||||
$this->assertArrayHasKey('/mlf/v1/fonts/(?P<id>[\d]+)', $routes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_items without authentication.
|
||||
*/
|
||||
public function test_get_items_unauthenticated() {
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(401, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_items with subscriber (insufficient permissions).
|
||||
*/
|
||||
public function test_get_items_insufficient_permissions() {
|
||||
wp_set_current_user($this->subscriber_id);
|
||||
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(403, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_items with admin.
|
||||
*/
|
||||
public function test_get_items_as_admin() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(200, $response->get_status());
|
||||
$this->assertIsArray($response->get_data());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_items returns installed fonts.
|
||||
*/
|
||||
public function test_get_items_returns_fonts() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
// Create a test font
|
||||
$font_id = $this->create_test_font('Test API Font', 'test-api-font');
|
||||
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(200, $response->get_status());
|
||||
$data = $response->get_data();
|
||||
$this->assertCount(1, $data);
|
||||
$this->assertEquals($font_id, $data[0]['id']);
|
||||
$this->assertEquals('Test API Font', $data[0]['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_item.
|
||||
*/
|
||||
public function test_get_item() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$font_id = $this->create_test_font('Single Font', 'single-font');
|
||||
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts/' . $font_id);
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(200, $response->get_status());
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals($font_id, $data['id']);
|
||||
$this->assertEquals('Single Font', $data['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_item not found.
|
||||
*/
|
||||
public function test_get_item_not_found() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('GET', '/mlf/v1/fonts/99999');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(404, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_item without authentication.
|
||||
*/
|
||||
public function test_create_item_unauthenticated() {
|
||||
$request = new WP_REST_Request('POST', '/mlf/v1/fonts');
|
||||
$request->set_param('font_name', 'Open Sans');
|
||||
$request->set_param('weights', [400, 700]);
|
||||
$request->set_param('styles', ['normal']);
|
||||
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(401, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_item with subscriber.
|
||||
*/
|
||||
public function test_create_item_insufficient_permissions() {
|
||||
wp_set_current_user($this->subscriber_id);
|
||||
|
||||
$request = new WP_REST_Request('POST', '/mlf/v1/fonts');
|
||||
$request->set_param('font_name', 'Open Sans');
|
||||
$request->set_param('weights', [400, 700]);
|
||||
$request->set_param('styles', ['normal']);
|
||||
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(403, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_item with invalid font name.
|
||||
*/
|
||||
public function test_create_item_invalid_font_name() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('POST', '/mlf/v1/fonts');
|
||||
$request->set_param('font_name', '<script>alert("xss")</script>');
|
||||
$request->set_param('weights', [400]);
|
||||
$request->set_param('styles', ['normal']);
|
||||
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(400, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_item with no weights.
|
||||
*/
|
||||
public function test_create_item_no_weights() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('POST', '/mlf/v1/fonts');
|
||||
$request->set_param('font_name', 'Test Font');
|
||||
$request->set_param('weights', []);
|
||||
$request->set_param('styles', ['normal']);
|
||||
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(400, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test create_item with no styles.
|
||||
*/
|
||||
public function test_create_item_no_styles() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('POST', '/mlf/v1/fonts');
|
||||
$request->set_param('font_name', 'Test Font');
|
||||
$request->set_param('weights', [400]);
|
||||
$request->set_param('styles', []);
|
||||
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(400, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_item without authentication.
|
||||
*/
|
||||
public function test_delete_item_unauthenticated() {
|
||||
$font_id = $this->create_test_font('Delete Font', 'delete-font');
|
||||
|
||||
$request = new WP_REST_Request('DELETE', '/mlf/v1/fonts/' . $font_id);
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(401, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_item with subscriber.
|
||||
*/
|
||||
public function test_delete_item_insufficient_permissions() {
|
||||
$font_id = $this->create_test_font('Delete Font 2', 'delete-font-2');
|
||||
|
||||
wp_set_current_user($this->subscriber_id);
|
||||
|
||||
$request = new WP_REST_Request('DELETE', '/mlf/v1/fonts/' . $font_id);
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(403, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_item as admin.
|
||||
*/
|
||||
public function test_delete_item_as_admin() {
|
||||
$font_id = $this->create_test_font('Delete Font 3', 'delete-font-3');
|
||||
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('DELETE', '/mlf/v1/fonts/' . $font_id);
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(200, $response->get_status());
|
||||
$data = $response->get_data();
|
||||
$this->assertTrue($data['deleted']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_item not found.
|
||||
*/
|
||||
public function test_delete_item_not_found() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
$request = new WP_REST_Request('DELETE', '/mlf/v1/fonts/99999');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(404, $response->get_status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete_item for font not imported by plugin.
|
||||
*/
|
||||
public function test_delete_item_not_ours() {
|
||||
wp_set_current_user($this->admin_id);
|
||||
|
||||
// Create a font without our meta
|
||||
$font_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_family',
|
||||
'post_title' => 'Theme Font',
|
||||
'post_status' => 'publish',
|
||||
]);
|
||||
|
||||
$request = new WP_REST_Request('DELETE', '/mlf/v1/fonts/' . $font_id);
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
|
||||
$this->assertEquals(403, $response->get_status());
|
||||
|
||||
// Clean up
|
||||
wp_delete_post($font_id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test item schema.
|
||||
*/
|
||||
public function test_get_item_schema() {
|
||||
$request = new WP_REST_Request('OPTIONS', '/mlf/v1/fonts');
|
||||
$response = rest_get_server()->dispatch($request);
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertArrayHasKey('schema', $data);
|
||||
$this->assertEquals('font', $data['schema']['title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test context parameter.
|
||||
*/
|
||||
public function test_context_param() {
|
||||
// This test is inherited from WP_Test_REST_Controller_Testcase
|
||||
// We just need to implement it to satisfy the abstract requirement
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a test font.
|
||||
*
|
||||
* @param string $name Font name.
|
||||
* @param string $slug Font slug.
|
||||
* @return int Font ID.
|
||||
*/
|
||||
private function create_test_font($name, $slug) {
|
||||
// Create font family post
|
||||
$font_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_family',
|
||||
'post_title' => $name,
|
||||
'post_name' => $slug,
|
||||
'post_status' => 'publish',
|
||||
'post_content' => wp_json_encode([
|
||||
'fontFamily' => $name,
|
||||
'slug' => $slug,
|
||||
]),
|
||||
]);
|
||||
|
||||
// Add our meta marker
|
||||
update_post_meta($font_id, '_mlf_imported', '1');
|
||||
|
||||
// Create a font face
|
||||
$face_id = wp_insert_post([
|
||||
'post_type' => 'wp_font_face',
|
||||
'post_title' => $name . ' 400 normal',
|
||||
'post_status' => 'publish',
|
||||
'post_parent' => $font_id,
|
||||
'post_content' => wp_json_encode([
|
||||
'fontFamily' => $name,
|
||||
'fontWeight' => '400',
|
||||
'fontStyle' => 'normal',
|
||||
'src' => ['file:./fonts/' . $slug . '_normal_400.woff2'],
|
||||
]),
|
||||
]);
|
||||
|
||||
// Clear cache
|
||||
delete_transient('mlf_imported_fonts_list');
|
||||
|
||||
return $font_id;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue