diff --git a/includes/admin/onboarding.php b/includes/admin/onboarding.php
index f66d1881..5d991058 100644
--- a/includes/admin/onboarding.php
+++ b/includes/admin/onboarding.php
@@ -64,35 +64,21 @@ function onboarding_action_handler() {
return;
}
- $podcast_name = isset( $_POST['podcast-name'] ) ? sanitize_text_field( wp_unslash( $_POST['podcast-name'] ) ) : null;
- $podcast_description = isset( $_POST['podcast-description'] ) ? sanitize_text_field( wp_unslash( $_POST['podcast-description'] ) ) : null;
- $podcast_category = isset( $_POST['podcast-category'] ) ? sanitize_text_field( wp_unslash( $_POST['podcast-category'] ) ) : null;
- $podcast_cover_id = isset( $_POST['podcast-cover-image-id'] ) ? absint( wp_unslash( $_POST['podcast-cover-image-id'] ) ) : null;
-
- if ( empty( $podcast_name ) || empty( $podcast_category ) ) {
- add_action(
- 'admin_notices',
- function() use ( $podcast_name, $podcast_category ) {
- ?>
-
- $podcasting_talent_name,
+ 'podcasting_summary' => $podcast_description,
+ 'podcasting_image' => $podcast_cover_id,
+ ]
);
if ( is_wp_error( $result ) ) {
@@ -109,6 +95,11 @@ function() use ( $result ) {
return;
}
+ /* Add podcast author. */
+ if ( $podcasting_talent_name ) {
+ update_term_meta( $result['term_id'], 'podcasting_talent_name', $podcasting_talent_name );
+ }
+
/** Add podcast summary. */
if ( $podcast_description ) {
update_term_meta( $result['term_id'], 'podcasting_summary', $podcast_description );
diff --git a/includes/admin/views/onboarding-page-one.php b/includes/admin/views/onboarding-page-one.php
index ea3affea..ebca8e1e 100644
--- a/includes/admin/views/onboarding-page-one.php
+++ b/includes/admin/views/onboarding-page-one.php
@@ -14,36 +14,43 @@
+
+
+
-
-
diff --git a/includes/datatypes.php b/includes/datatypes.php
index 96af2059..42fff3fc 100644
--- a/includes/datatypes.php
+++ b/includes/datatypes.php
@@ -502,7 +502,7 @@ function get_meta_fields() {
),
array(
'slug' => 'podcasting_talent_name',
- 'title' => __( 'Artist / Author name', 'simple-podcasting' ),
+ 'title' => __( 'Artist / Author name (required)', 'simple-podcasting' ),
'type' => 'textfield',
),
array(
@@ -512,7 +512,7 @@ function get_meta_fields() {
),
array(
'slug' => 'podcasting_summary',
- 'title' => __( 'Summary', 'simple-podcasting' ),
+ 'title' => __( 'Summary (required)', 'simple-podcasting' ),
'type' => 'textarea',
),
array(
@@ -538,7 +538,7 @@ function get_meta_fields() {
),
array(
'slug' => 'podcasting_image',
- 'title' => __( 'Cover image', 'simple-podcasting' ),
+ 'title' => __( 'Cover image (required)', 'simple-podcasting' ),
'type' => 'image',
'description' => __( 'Minimum size: 1400px x 1400 px — maximum size: 2048px x 2048px', 'simple-podcasting' ),
),
@@ -560,7 +560,7 @@ function get_meta_fields() {
),
array(
'slug' => 'podcasting_category_1',
- 'title' => __( 'Category 1', 'simple-podcasting' ),
+ 'title' => __( 'Category 1 (required)', 'simple-podcasting' ),
'type' => 'select',
'options' => get_podcasting_categories_options(),
),
@@ -826,3 +826,77 @@ function get_podcasting_language_options() {
)
);
}
+
+/**
+ * Validate Podcast Taxonomy Fields.
+ *
+ * @param string $term Term.
+ * @param string $taxonomy Taxonomy Name.
+ * @param array $args List of arguments.
+ *
+ * @return string
+ */
+function validate_taxonomy_fields( $term, $taxonomy, $args = [] ) {
+ // Bailout, if not the podcasts taxonomy.
+ if ( 'podcasting_podcasts' !== $taxonomy ) {
+ return $term;
+ }
+
+ $referer = sanitize_text_field( $_POST['_wp_http_referer'] );
+ $query_string = parse_url( $referer, PHP_URL_QUERY );
+ parse_str( $query_string, $query );
+
+ $is_onboarding_step_1 = isset( $query['page'] ) && isset( $query['step'] )
+ && 'simple-podcasting-onboarding' === $query['page'] && '1' === $query['step'];
+
+ if ( ! $is_onboarding_step_1 && empty( trim( $term ) ) ) {
+ return new \WP_Error( 'empty_term_name', __( 'A podcast name is required.', 'simple-podcasting' ) );
+ }
+
+ // The third argument was only introduced in the `pre_insert_term` filter in WP 6.1, so bail if it's empty.
+ if ( empty( $args ) ) {
+ return $term;
+ }
+
+ if ( $is_onboarding_step_1 ) {
+ $args['tag-name'] = sanitize_title( wp_unslash( $_POST['podcast-name'] ) );
+ $args['podcasting_category_1'] = sanitize_text_field( wp_unslash( $_POST['podcast-category'] ) );
+ }
+
+ // Require podcast name.
+ if ( empty( trim( $args['tag-name'] ) ) ) {
+ return new \WP_Error( 'empty_term_name', __( 'A podcast name is required.', 'simple-podcasting' ) );
+ }
+
+ // Require podcast author name only on term edit screen.
+ if ( empty( trim( $args['podcasting_talent_name'] ) ) ) {
+ return new \WP_Error( 'empty_term_talent_name', __( 'A podcast artist or author name is required.', 'simple-podcasting' ) );
+ }
+
+ // Require podcast description.
+ if ( empty( trim( $args['podcasting_summary'] ) ) ) {
+ return new \WP_Error( 'empty_term_summary', __( 'A podcast summary is required.', 'simple-podcasting' ) );
+ }
+
+ // Require podcast image.
+ if ( empty( trim( $args['podcasting_image'] ) ) ) {
+ return new \WP_Error( 'empty_term_cover_image', __( 'A podcast cover image is required.', 'simple-podcasting' ) );
+ }
+
+ // Require podcast category.
+ $is_missing_category = $is_onboarding_step_1 ?
+ empty( trim( $args['podcasting_category_1'] ) ) :
+ (
+ empty( trim( $args['podcasting_category_1'] ) ) &&
+ empty( trim( $args['podcasting_category_2'] ) ) &&
+ empty( trim( $args['podcasting_category_3'] ) )
+ );
+
+ if ( $is_missing_category ) {
+ return new \WP_Error( 'empty_term_category', __( 'A podcast category is required.', 'simple-podcasting' ) );
+ }
+
+ return $term;
+}
+
+add_filter( 'pre_insert_term', __NAMESPACE__ . '\validate_taxonomy_fields', 10, 3 );
diff --git a/package-lock.json b/package-lock.json
index 8f99d7ae..1029400c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"copy-webpack-plugin": "^11.0.0",
"cypress": "^11.2.0",
"cypress-file-upload": "^5.0.8",
+ "cypress-localstorage-commands": "^2.2.2",
"cypress-mochawesome-reporter": "^3.4.0",
"eslint-plugin-cypress": "^2.12.1",
"husky": "^8.0.1",
@@ -6801,6 +6802,18 @@
"cypress": ">3.0.0"
}
},
+ "node_modules/cypress-localstorage-commands": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/cypress-localstorage-commands/-/cypress-localstorage-commands-2.2.3.tgz",
+ "integrity": "sha512-EUEaHzbstw9AsEheIqr+RyXuxIzUS64nBBwl+Q4/mSdzfXpfcaV1nrHF+6H9zbTuFVTc+oWu6eC1l8aSjiWW6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "cypress": ">=2.1.0"
+ }
+ },
"node_modules/cypress-mochawesome-reporter": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/cypress-mochawesome-reporter/-/cypress-mochawesome-reporter-3.4.0.tgz",
@@ -24175,6 +24188,13 @@
"dev": true,
"requires": {}
},
+ "cypress-localstorage-commands": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/cypress-localstorage-commands/-/cypress-localstorage-commands-2.2.3.tgz",
+ "integrity": "sha512-EUEaHzbstw9AsEheIqr+RyXuxIzUS64nBBwl+Q4/mSdzfXpfcaV1nrHF+6H9zbTuFVTc+oWu6eC1l8aSjiWW6w==",
+ "dev": true,
+ "requires": {}
+ },
"cypress-mochawesome-reporter": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/cypress-mochawesome-reporter/-/cypress-mochawesome-reporter-3.4.0.tgz",
diff --git a/package.json b/package.json
index 2fc30f65..0b98ede5 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"copy-webpack-plugin": "^11.0.0",
"cypress": "^11.2.0",
"cypress-file-upload": "^5.0.8",
+ "cypress-localstorage-commands": "^2.2.2",
"cypress-mochawesome-reporter": "^3.4.0",
"eslint-plugin-cypress": "^2.12.1",
"husky": "^8.0.1",
diff --git a/tests/cypress/fixtures/example.jpg b/tests/cypress/fixtures/example.jpg
new file mode 100644
index 00000000..b0f2052e
Binary files /dev/null and b/tests/cypress/fixtures/example.jpg differ
diff --git a/tests/cypress/integration/block.test.js b/tests/cypress/integration/block.test.js
index 6976fdf9..a23f096e 100644
--- a/tests/cypress/integration/block.test.js
+++ b/tests/cypress/integration/block.test.js
@@ -1,11 +1,38 @@
+import 'cypress-localstorage-commands';
+const { populatePodcast } = require('../support/functions');
+
describe('Admin can publish posts with podcast block', () => {
const taxonomy = 'Remote work';
+ before(() => {
+ const userId = '1';
+ cy.setLocalStorage(
+ `WP_DATA_USER_${userId}`,
+ JSON.stringify({
+ 'core/edit-post': {
+ preferences: {
+ features: {
+ welcomeGuide: false,
+ },
+ },
+ },
+ })
+ );
+ });
+
if (Cypress.env('HAS_BLOCK_EDITOR')) {
it('Can insert the block and publish the post', () => {
cy.login();
-
- cy.createTerm(taxonomy, 'podcasting_podcasts');
+ cy.uploadMedia('tests/cypress/fixtures/example.jpg');
+ cy.createTerm(taxonomy, 'podcasting_podcasts', {
+ beforeSave: () => {
+ populatePodcast({
+ author: 'Person Doe',
+ summary: 'Lorem ipsum dolor',
+ category: 'arts:food',
+ });
+ },
+ });
cy.visit('/wp-admin/post-new.php');
cy.closeWelcomeGuide();
@@ -20,7 +47,9 @@ describe('Admin can publish posts with podcast block', () => {
.first()
.as('block-search');
cy.get('@block-search').click().type('Podcast');
- cy.get('.editor-block-list-item-podcasting-podcast').click();
+ cy.get('.editor-block-list-item-podcasting-podcast', {
+ timeout: 4000,
+ }).click();
cy.get('.edit-post-header-toolbar__inserter-toggle').click();
cy.get(
'.wp-block-podcasting-podcast input[type="file"]'
diff --git a/tests/cypress/integration/onboarding.test.js b/tests/cypress/integration/onboarding.test.js
index e0f335cf..0161f727 100644
--- a/tests/cypress/integration/onboarding.test.js
+++ b/tests/cypress/integration/onboarding.test.js
@@ -1,4 +1,4 @@
-const { randomName } = require('../support/functions');
+const { randomName, populatePodcast } = require('../support/functions');
describe('Onboarding tests', () => {
before(() => {
@@ -6,6 +6,7 @@ describe('Onboarding tests', () => {
});
beforeEach(() => {
+ cy.uploadMedia('tests/cypress/fixtures/example.jpg');
cy.activatePlugin('simple-podcasting');
cy.deleteAllTerms('podcasting_podcasts');
cy.deactivatePlugin('simple-podcasting');
@@ -29,8 +30,11 @@ describe('Onboarding tests', () => {
.closest('form')
.submit();
- cy.contains('Show name is required.');
- cy.contains('Podcast category is required.');
+ cy.get('input[name="podcast-name"]').then(($input) => {
+ expect($input[0].validationMessage).to.eq(
+ 'Please fill out this field.'
+ );
+ });
});
it('Should pass onboarding', () => {
@@ -39,8 +43,12 @@ describe('Onboarding tests', () => {
const podcastName = 'Onboarding ' + randomName();
cy.get('input[name=podcast-name]').click().type(podcastName);
- cy.get('select[name=podcast-category]').select('Arts');
-
+ populatePodcast({
+ author: 'Person Doe',
+ summary: 'Lorem ipsum dolor',
+ category: 'Arts',
+ onboarding: true,
+ });
cy.get('#simple-podcasting__create-podcast-button')
.closest('form')
.submit();
diff --git a/tests/cypress/integration/taxonomy.test.js b/tests/cypress/integration/taxonomy.test.js
index 7ebc1cec..866a176d 100644
--- a/tests/cypress/integration/taxonomy.test.js
+++ b/tests/cypress/integration/taxonomy.test.js
@@ -1,4 +1,4 @@
-const { randomName } = require('../support/functions');
+const { randomName, populatePodcast } = require('../support/functions');
describe('Admin can create and update podcast taxonomy', () => {
before(() => {
@@ -30,7 +30,16 @@ describe('Admin can create and update podcast taxonomy', () => {
});
it('Can add a new taxonomy', () => {
- cy.createTerm('Remote work', 'podcasting_podcasts');
+ cy.uploadMedia('tests/cypress/fixtures/example.jpg');
+ cy.createTerm('Remote work', 'podcasting_podcasts', {
+ beforeSave: () => {
+ populatePodcast({
+ author: 'Person Doe',
+ summary: 'Lorem ipsum dolor',
+ category: 'arts:food',
+ });
+ },
+ });
cy.get('.row-title').should('have.text', 'Remote work');
});
@@ -76,9 +85,15 @@ describe('Admin can create and update podcast taxonomy', () => {
for (const [typeOfShowKey, typeOfShowName] of Object.entries(tests)) {
it(`Can add taxonomy with ${typeOfShowName} type of show`, () => {
const podcastName = 'Podcast ' + randomName();
+ cy.uploadMedia('tests/cypress/fixtures/example.jpg');
cy.createTerm(podcastName, 'podcasting_podcasts', {
beforeSave: () => {
- cy.get('#podcasting_type_of_show').select(typeOfShowName);
+ populatePodcast({
+ typeOfShowName,
+ author: 'Person Doe',
+ summary: 'Lorem ipsum dolor',
+ category: 'arts:food',
+ });
},
}).then((term) => {
cy.visit(
diff --git a/tests/cypress/support/functions.js b/tests/cypress/support/functions.js
index c638c025..c6cbc483 100644
--- a/tests/cypress/support/functions.js
+++ b/tests/cypress/support/functions.js
@@ -1 +1,54 @@
export const randomName = () => Math.random().toString(16).substring(7);
+
+export const getFirstImage = () => {
+ cy.get('#menu-item-browse').click();
+ cy.get('ul.attachments li:first-of-type').click();
+ cy.get('.media-button-select').click();
+};
+
+/**
+ * Populates a podcast taxonomy.
+ * @param {Object} args The podcast data to populate.
+ * @param {string} args.typeOfShowName The type of show.
+ * @param {string} args.author The author of the podcast.
+ * @param {string} args.summary The summary of the podcast.
+ * @param {string} args.category The category of the podcast.
+ * @param {boolean} args.onboarding Whether this is onboarding or not.
+ */
+export const populatePodcast = (args) => {
+ for (const [key, value] of Object.entries(args)) {
+ switch (key) {
+ case 'typeOfShowName':
+ cy.get('#podcasting_type_of_show').select(value);
+ break;
+ case 'author':
+ if (args.onboarding) {
+ cy.get('input[name="podcast-artist"]').type(value);
+ } else {
+ cy.get('#podcasting_talent_name').type(value);
+ }
+ break;
+ case 'summary':
+ if (args.onboarding) {
+ cy.get('textarea[name="podcast-description"]').type(value);
+ } else {
+ cy.get('#podcasting_summary').type(value);
+ }
+ break;
+ case 'category':
+ if (args.onboarding) {
+ cy.get('select[name=podcast-category]').select(value);
+ } else {
+ cy.get('#podcasting_category_1').select(value);
+ }
+ break;
+ }
+ }
+ // Get first image from media library.
+ if (args.onboarding) {
+ cy.get('#simple-podcasting__upload-cover-image').click();
+ } else {
+ cy.get('#image-podcasting_image').click();
+ }
+ getFirstImage();
+};