diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml new file mode 100644 index 00000000..e8c73690 --- /dev/null +++ b/.github/workflows/run_tests.yml @@ -0,0 +1,105 @@ +name: CI + +on: + pull_request: + branches: + - develop + - master + +permissions: + contents: read + +jobs: + run_tests: + name: Run Unit & Acceptance Tests + runs-on: ubuntu-latest + services: + mysql: + image: mysql:8 + env: + MYSQL_ROOT_PASSWORD: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + MYSQL_DATABASE: wordpress_test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + coverage: none + tools: wp-cli + + - name: Install Composer dependencies + run: composer install + + - name: Setup Node + uses: actions/setup-node@v2 + with: + node-version: '17' + + - name: Prepare testing environment + run: | + # Move the plugin files to the separate folder + mkdir ssp && mv `ls -A | grep -v ssp` ssp + + # Download WordPress + wp core download --allow-root + + # Set up .env + echo "TEST_WP_ROOT=$(pwd)" > .env.testing + echo "TEST_DB_HOST=127.0.0.1" >> .env.testing + echo "TEST_DB_NAME=wordpress_test" >> .env.testing + echo "TEST_DB_USER=wordpress" >> .env.testing + echo "TEST_DB_PASSWORD=wordpress" >> .env.testing + echo "TEST_DOMAIN=localhost" >> .env.testing + mv .env.testing ssp/ + + # Move the plugin to the plugins folder + mv ssp ./wp-content/plugins/seriously-simple-podcasting + cd wp-content/plugins/seriously-simple-podcasting + npm install -g grunt-cli + npm install + npm rebuild node-sass + grunt uglify && grunt cssmin && npm run build + + - name: Run Unit tests + run: cd wp-content/plugins/seriously-simple-podcasting && vendor/bin/codecept run wpunit + + - name: Run Acceptance tests + run: | + wp config create --dbname=wordpress_test --dbuser=wordpress --dbpass=wordpress --dbhost=127.0.0.1 --dbprefix=wsy_ --allow-root + wp config set WP_SITEURL http://localhost:8000 --type=constant --allow-root + wp config set WP_HOME http://localhost:8000 --type=constant --allow-root + nohup php -S localhost:8000 & + cd wp-content/plugins/seriously-simple-podcasting + echo "SITE_URL=http://localhost:8000" >> .env.testing + echo "SITE_USER=autotest" >> .env.testing + echo "SITE_USER_PASS=password" >> .env.testing + echo "PODCAST_GUID=dd94465b-580a-501c-a892-caf224d23d7a" >> .env.testing + sudo apt-get update -qq + sudo env DEBIAN_FRONTEND=noninteractive apt-get install -qq mysql-client default-libmysqlclient-dev + gzip -d tests/seed.sql.gz && wp db import tests/seed.sql --allow-root + wp core update-db --allow-root + wp theme activate twentytwentyfour --allow-root + wp plugin install classic-editor --allow-root + vendor/bin/codecept run acceptance --steps + + - name: Upload codeception output on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: acceptance-tests + path: wp-content/plugins/seriously-simple-podcasting/tests/_output + + - name: Upload PHP server logs on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: acceptance-tests + path: nohup.out diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9caf71f3..c9b187e4 100755 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,7 +46,6 @@ unit_tests: # Prepare testing environment file - touch .env.testing - - echo "TEST_WP_ROOT=$(pwd)" - echo "TEST_WP_ROOT=$(pwd)" >> .env.testing - echo "TEST_DB_HOST=db" >> .env.testing - echo "TEST_DB_NAME=$MYSQL_DATABASE" >> .env.testing @@ -151,6 +150,7 @@ acceptance_tests: - echo "SITE_URL=$SSH_USER" >> .env.testing - echo "SITE_USER=$SITE_USER" >> .env.testing - echo "SITE_USER_PASS=$SITE_USER_PASS" >> .env.testing + - echo "PODCAST_GUID=115e423a-72d2-531e-9d3c-ece7dd4b74fe" >> .env.testing # Run Acceptance tests - vendor/bin/codecept run acceptance --steps diff --git a/assets/admin/css/admin.css b/assets/admin/css/admin.css index e2597b1f..249a1268 100644 --- a/assets/admin/css/admin.css +++ b/assets/admin/css/admin.css @@ -204,6 +204,16 @@ textarea#episode_embed_code { font-size: 16px; top: -3px; } +#podmotor_account_api_token { + width: 100%; + min-width: 100%; + display: block; + margin-bottom: 8px; } + +.ssp-settings-integrations table label { + margin-top: 10px; + display: block; } + .ssp-settings:not(.ssp-settings-extensions, .ssp-settings-integrations) { background: #FFFFFF; margin-top: 28px; @@ -219,8 +229,6 @@ textarea#episode_embed_code { .ssp-settings table input.regular-text { max-width: 90%; background: #F1F5F9; } - .ssp-settings .validate-api-credentials-message { - margin-left: 30px; } .ssp-settings .loader { position: relative; } .ssp-settings .loader:after { @@ -243,6 +251,32 @@ textarea#episode_embed_code { .ssp-settings .ssp-sync-msg.success .sync-overview { color: #4caf50; } +.ssp-main-settings .error { + color: #DF4E4F; } + +.ssp-main-settings .hidden { + display: none; } + +.ssp-main-settings .disconnect-castos { + margin-right: 8px; + vertical-align: middle; } + +.ssp-main-settings.tab-castos-hosting .loader { + position: relative; } + .ssp-main-settings.tab-castos-hosting .loader:after { + content: ''; + display: block; + background: url(../img/loader2.svg) no-repeat; + position: absolute; + right: -50px; + top: -9px; + background-size: contain; + width: 44px; + height: 44px; } + +.connect-castos-message { + margin-left: 20px; } + .ssp-sync-podcast { display: flex; justify-content: space-between; @@ -467,6 +501,8 @@ textarea#episode_embed_code { right: 350px; } .ssp-onboarding-step-4 .ssp-onboarding__steps::after { right: 180px; } + .ssp-onboarding-step-4 .ssp-onboarding__settings-body { + padding: 24px 24px 36px; } .ssp-onboarding-step-4__info { display: flex; flex-direction: column; @@ -659,7 +695,7 @@ textarea#episode_embed_code { z-index: 0; visibility: hidden; transition: .6s; - margin-top: -444px; } + margin-top: -345px; } .ssp-onboarding-step-4__form--opened { visibility: visible; margin-top: 0; } @@ -749,6 +785,10 @@ textarea#episode_embed_code { text-align: right; margin-top: 25px; position: relative; } + .ssp-onboarding__submit span.connect-castos-message { + display: block; + text-align: left; + margin: 20px 0 0; } .ssp-onboarding__submit button[type=submit], .ssp-onboarding__submit .button { position: relative; height: 50px; @@ -794,39 +834,56 @@ textarea#episode_embed_code { background: #516178; } .ssp-onboarding__submit .button span { line-height: 50px; } - .ssp-onboarding__submit .validate-token { + .ssp-onboarding__submit .castos-connect { float: left; position: relative; padding: 0 20px 0 45px; } - .ssp-onboarding__submit .validate-token:after { + .ssp-onboarding__submit .castos-connect:after { content: ''; display: block; position: absolute; - background: url(../img/validate.svg) no-repeat; - background-size: cover; - left: 19px; - top: 17px; - width: 14px; - height: 18px; - filter: none; } - .ssp-onboarding__submit .validate-token.validating { - background: #374151; } - .ssp-onboarding__submit .validate-token.validating:hover, .ssp-onboarding__submit .validate-token.validating:active, .ssp-onboarding__submit .validate-token.validating:focus { - background: #374151; } - .ssp-onboarding__submit .validate-token.validating:after { + background: url(../img/connect.svg) no-repeat; + left: 13px; + top: 13px; + width: 25px; + height: 23px; + filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(198deg) brightness(101%) contrast(102%); + background-size: contain; } + .ssp-onboarding__submit .castos-connect:disabled { + background: #9CA3AF !important; + color: #D1D5DB !important; } + .ssp-onboarding__submit .castos-connect:disabled:after { + filter: invert(94%) sepia(8%) saturate(150%) hue-rotate(177deg) brightness(90%) contrast(93%); + transition: none; } + .ssp-onboarding__submit .castos-connect.connecting { + background: #DE7373 !important; + color: #FFFFFF !important; } + .ssp-onboarding__submit .castos-connect.connecting:hover, .ssp-onboarding__submit .castos-connect.connecting:active, .ssp-onboarding__submit .castos-connect.connecting:focus, .ssp-onboarding__submit .castos-connect.connecting:disabled { + background: #DE7373; } + .ssp-onboarding__submit .castos-connect.connecting:after { width: 17px; height: 18px; - background-image: url(../img/validating.svg); } - .ssp-onboarding__submit .validate-token.valid { - background: #10B981; - padding: 0 16px 0 45px; } - .ssp-onboarding__submit .validate-token.valid:hover, .ssp-onboarding__submit .validate-token.valid:active, .ssp-onboarding__submit .validate-token.valid:focus { + background-image: url(../img/connecting.svg); + animation: rotation 2s infinite linear; + filter: none; + transition: none; + top: 15px; + left: 15px; } + .ssp-onboarding__submit .castos-connect.connected { + background: #10B981 !important; + color: #FFFFFF !important; + padding: 0 16px 0 45px; + opacity: .7; } + .ssp-onboarding__submit .castos-connect.connected:hover, .ssp-onboarding__submit .castos-connect.connected:active, .ssp-onboarding__submit .castos-connect.connected:focus { background: #10B981; } - .ssp-onboarding__submit .validate-token.valid:after { - width: 16px; - height: 12px; - top: 19px; - background-image: url(../img/checkbox.svg); } + .ssp-onboarding__submit .castos-connect.connected:after { + background-image: url(../img/connect.svg); + left: 13px; + top: 13px; + width: 25px; + height: 23px; + filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(198deg) brightness(101%) contrast(102%); + background-size: contain; } .ssp-onboarding__image-info { position: absolute; display: flex; @@ -864,10 +921,6 @@ textarea#episode_embed_code { transform: rotate(-45deg); } .ssp-onboarding__delete-image:hover:before, .ssp-onboarding__delete-image:hover:after { background: #fff; } - .ssp-onboarding .validate-api-credentials-message { - position: absolute; - left: 0; - bottom: -18px; } .ssp-onboarding__links { display: flex; text-align: left; } @@ -977,17 +1030,17 @@ textarea#episode_embed_code { font-family: dashicons, 'Inter', sans-serif; } /* Hide the WP bars */ -.admin_page_ssp-onboarding-1 #adminmenumain, .admin_page_ssp-onboarding-1 #wpadminbar, .admin_page_ssp-onboarding-1 #wpfooter, .admin_page_ssp-onboarding-2 #adminmenumain, .admin_page_ssp-onboarding-2 #wpadminbar, .admin_page_ssp-onboarding-2 #wpfooter, .admin_page_ssp-onboarding-3 #adminmenumain, .admin_page_ssp-onboarding-3 #wpadminbar, .admin_page_ssp-onboarding-3 #wpfooter, .admin_page_ssp-onboarding-4 #adminmenumain, .admin_page_ssp-onboarding-4 #wpadminbar, .admin_page_ssp-onboarding-4 #wpfooter, .admin_page_ssp-onboarding-5 #adminmenumain, .admin_page_ssp-onboarding-5 #wpadminbar, .admin_page_ssp-onboarding-5 #wpfooter { +.podcast_page_ssp-onboarding-1 #adminmenumain, .podcast_page_ssp-onboarding-1 #wpadminbar, .podcast_page_ssp-onboarding-1 #wpfooter, .admin_page_ssp-onboarding-1 #adminmenumain, .admin_page_ssp-onboarding-1 #wpadminbar, .admin_page_ssp-onboarding-1 #wpfooter, .admin_page_ssp-onboarding-2 #adminmenumain, .admin_page_ssp-onboarding-2 #wpadminbar, .admin_page_ssp-onboarding-2 #wpfooter, .admin_page_ssp-onboarding-3 #adminmenumain, .admin_page_ssp-onboarding-3 #wpadminbar, .admin_page_ssp-onboarding-3 #wpfooter, .admin_page_ssp-onboarding-4 #adminmenumain, .admin_page_ssp-onboarding-4 #wpadminbar, .admin_page_ssp-onboarding-4 #wpfooter, .admin_page_ssp-onboarding-5 #adminmenumain, .admin_page_ssp-onboarding-5 #wpadminbar, .admin_page_ssp-onboarding-5 #wpfooter { display: none; } -.admin_page_ssp-onboarding-1 #wpcontent, .admin_page_ssp-onboarding-2 #wpcontent, .admin_page_ssp-onboarding-3 #wpcontent, .admin_page_ssp-onboarding-4 #wpcontent, .admin_page_ssp-onboarding-5 #wpcontent { +.podcast_page_ssp-onboarding-1 #wpcontent, .admin_page_ssp-onboarding-1 #wpcontent, .admin_page_ssp-onboarding-2 #wpcontent, .admin_page_ssp-onboarding-3 #wpcontent, .admin_page_ssp-onboarding-4 #wpcontent, .admin_page_ssp-onboarding-5 #wpcontent { margin-left: 0; padding-left: 0; } -.admin_page_ssp-onboarding-1 #wpbody-content, .admin_page_ssp-onboarding-2 #wpbody-content, .admin_page_ssp-onboarding-3 #wpbody-content, .admin_page_ssp-onboarding-4 #wpbody-content, .admin_page_ssp-onboarding-5 #wpbody-content { +.podcast_page_ssp-onboarding-1 #wpbody-content, .admin_page_ssp-onboarding-1 #wpbody-content, .admin_page_ssp-onboarding-2 #wpbody-content, .admin_page_ssp-onboarding-3 #wpbody-content, .admin_page_ssp-onboarding-4 #wpbody-content, .admin_page_ssp-onboarding-5 #wpbody-content { padding-bottom: 30px; } -.admin_page_ssp-onboarding-1 .notice, .admin_page_ssp-onboarding-1 .error, .admin_page_ssp-onboarding-2 .notice, .admin_page_ssp-onboarding-2 .error, .admin_page_ssp-onboarding-3 .notice, .admin_page_ssp-onboarding-3 .error, .admin_page_ssp-onboarding-4 .notice, .admin_page_ssp-onboarding-4 .error, .admin_page_ssp-onboarding-5 .notice, .admin_page_ssp-onboarding-5 .error { +.podcast_page_ssp-onboarding-1 .notice, .podcast_page_ssp-onboarding-1 .error, .admin_page_ssp-onboarding-1 .notice, .admin_page_ssp-onboarding-1 .error, .admin_page_ssp-onboarding-2 .notice, .admin_page_ssp-onboarding-2 .error, .admin_page_ssp-onboarding-3 .notice, .admin_page_ssp-onboarding-3 .error, .admin_page_ssp-onboarding-4 .notice, .admin_page_ssp-onboarding-4 .error, .admin_page_ssp-onboarding-5 .notice, .admin_page_ssp-onboarding-5 .error { display: none; } .ssp-review-notice { @@ -1077,3 +1130,246 @@ textarea#episode_embed_code { align-self: stretch; } .ssp-post-publish__btn a:hover { background: #eff0f0; } + +#ssp-episode-meta-sidebar\:ssp-episode-meta-sidebar .interface-complementary-area-header__title { + font-size: 12px; } + +.ssp-episode-meta-sidebar .ssp-accordion, .ssp-sidebar-panel .ssp-accordion { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + padding: 16px; + font-weight: 500; + margin: 0; + background: #fafcfe; + transition: 0.4s; } + .ssp-episode-meta-sidebar .ssp-accordion:hover, .ssp-sidebar-panel .ssp-accordion:hover { + background: #f0f7ff; } + .ssp-episode-meta-sidebar .ssp-accordion:after, .ssp-sidebar-panel .ssp-accordion:after { + content: ''; + display: inline-block; + position: relative; + width: 10px; + height: 10px; + border-right: 2px solid #383838; + border-bottom: 2px solid #383838; + transform: rotate(45deg); } + .ssp-episode-meta-sidebar .ssp-accordion.open, .ssp-sidebar-panel .ssp-accordion.open { + border-bottom: 1px solid #ddd; } + .ssp-episode-meta-sidebar .ssp-accordion.open:after, .ssp-sidebar-panel .ssp-accordion.open:after { + transform: rotate(-135deg); + top: 3px; } + +.ssp-episode-meta-sidebar .ssp-sync-label, .ssp-sidebar-panel .ssp-sync-label { + margin-top: 8px; } + +.ssp-episode-meta-sidebar .ssp-sync-message, .ssp-sidebar-panel .ssp-sync-message { + margin-top: 8px; } + +.ssp-sidebar-panel { + width: 100%; } + .ssp-sidebar-panel .ssp-accordion { + background: none; + width: calc(100% + 32px); + margin-left: -16px; + margin-bottom: -16px; + border-top: 1px solid #ddd; + padding: 8px 16px; } + .ssp-sidebar-panel .ssp-accordion svg { + transform: rotate(180deg); } + .ssp-sidebar-panel .ssp-accordion:hover { + background: #f0f0f0; } + .ssp-sidebar-panel .ssp-accordion.open { + border-bottom: none; + margin-bottom: 0; } + .ssp-sidebar-panel .ssp-accordion.open svg { + transform: rotate(0); } + .ssp-sidebar-panel .ssp-accordion:after { + display: none; } + .ssp-sidebar-panel .ssp-file-info { + display: flex; + margin-top: 8px; + align-items: center; + gap: 4px; } + .ssp-sidebar-panel .ssp-file-info img { + position: relative; + top: -2px; } + .ssp-sidebar-panel .ssp-file-info span { + color: #555555; } + .ssp-sidebar-panel .ssp-open-meta-btn { + margin: 16px 0 4px; + color: #555555; + font-weight: 500; + height: 100%; + padding: 4px 0; + text-align: center; + display: flex; + justify-content: center; + min-height: 32px; + overflow: hidden; + transition: .4s; + width: 100%; + background: #F7F7F7; + border-radius: 3px; + border-width: 1px 1px 2px 1px; + border-style: solid; + border-color: #CCCCCC; + box-shadow: none; } + .ssp-sidebar-panel .ssp-open-meta-btn:hover { + box-shadow: none; + color: #007cba; + opacity: 0.8; } + +.ssp-episode-meta-sidebar .interface-complementary-area-header { + background: #f8fafb; } + +.ssp-episode-meta-sidebar .components-panel__body { + padding: 0; } + .ssp-episode-meta-sidebar .components-panel__body:last-child { + border-bottom: 1px solid #ddd; } + +.ssp-episode-meta-sidebar input[type=text] { + border-radius: 3px; } + +.ssp-episode-meta-sidebar input[type=checkbox] { + border: 1px solid #CBD5E1; + border-radius: 5px; } + +.ssp-episode-meta-sidebar .components-checkbox-control__label { + color: #334155; } + +.ssp-episode-meta-sidebar .components-radio-control .components-base-control__field > div { + flex-direction: row; + gap: 0.5rem; + justify-content: start; } + +.ssp-episode-meta-sidebar h3 { + text-transform: none; + font-size: 13px; + font-weight: 500; + margin: 8px 0; } + +.ssp-episode-meta-sidebar .description { + margin: 12px 0; + font-size: 11px; + line-height: 13px; + color: #64748B; } + +.ssp-episode-meta-sidebar .ssp-sidebar-content { + padding: 8px 16px; } + +.ssp-episode-meta-sidebar .ssp-sidebar-field-section { + margin-bottom: 16px; } + +.ssp-episode-meta-sidebar .flex { + display: flex; } + +.ssp-episode-meta-sidebar .gap-2 { + gap: 0.5rem; } + +.ssp-episode-meta-sidebar .w-full { + width: 100%; } + +.ssp-episode-meta-sidebar .mb-2 { + margin-bottom: 0.5rem; } + +.ssp-episode-meta-sidebar .ssp-image-uploader { + margin-top: 8px; } + .ssp-episode-meta-sidebar .ssp-image-uploader img { + transition: 0.4s; + box-shadow: 1px 1px 6px 0 rgba(0, 0, 20, 0.2); } + .ssp-episode-meta-sidebar .ssp-image-uploader img:hover { + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); } + .ssp-episode-meta-sidebar .ssp-image-uploader .no-image { + height: 230px; + background: #F6F7F7; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + color: #555; + box-shadow: 1px 1px 6px 0 rgba(0, 0, 20, 0.2); + transition: 0.4s; } + .ssp-episode-meta-sidebar .ssp-image-uploader .no-image:hover { + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); } + .ssp-episode-meta-sidebar .ssp-image-uploader .remove-image { + position: absolute; + top: 4px; + right: 4px; + background: white; + border-radius: 50%; + width: 24px; + height: 24px; + min-width: 24px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } + +.ssp-episode-meta-sidebar .ssp-promo-sidebar { + margin-right: -16px; + margin-left: -16px; + background: #EBF6FF; + padding: 16px; + margin-bottom: -24px; } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__description { + color: #2271B1; } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__description-row { + display: flex; + gap: 12px; + margin-bottom: 12px; } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__bell { + width: 40px; + min-width: 40px; + height: 40px; + background: #BFDBFE; + border-radius: 4px; } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__bell img { + padding: 8px; } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__btn { + display: block; + border: 1px solid #2271B1; + border-radius: 3px; + padding: 8px; + width: 100%; + text-decoration: none; + text-align: center; + transition: .4s; + box-shadow: 0 0 4px 0 rgba(0, 0, 20, 0.2); } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__btn:hover { + background: #eff5fb; + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); } + .ssp-episode-meta-sidebar .ssp-promo-sidebar__btn img { + position: relative; + top: 3px; + left: 4px; } + +.ssp-episode-meta-sidebar .button { + border: 1px solid #2271B1; + box-shadow: 0 0 4px 0 rgba(0, 0, 20, 0.2); + transition: .4s; } + .ssp-episode-meta-sidebar .button:hover:not(:disabled) { + border: 1px solid #2271B1; + background: #f6f7f7; + box-shadow: 1px 1px 4px 0 rgba(0, 0, 20, 0.2); } + +.ssp-date-input .components-popover__content { + padding: 8px; } + +.ssp-date-input .components-datetime__time fieldset:first-child { + display: none; } + +.ssp-calendar-icon { + position: relative; } + .ssp-calendar-icon:after { + content: ''; + display: inline-block; + position: absolute; + right: 6px; + background: url(../img/calendar.svg) no-repeat; + background-size: contain; + width: 17px; + height: 16px; + top: 7px; } + +.ssp-gut-sidebar-notice { + margin-top: 8px; } diff --git a/assets/admin/img/calendar.svg b/assets/admin/img/calendar.svg new file mode 100644 index 00000000..43531745 --- /dev/null +++ b/assets/admin/img/calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/admin/img/connect.svg b/assets/admin/img/connect.svg new file mode 100644 index 00000000..463acfb4 --- /dev/null +++ b/assets/admin/img/connect.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/admin/img/connecting.svg b/assets/admin/img/connecting.svg new file mode 100644 index 00000000..23295e5b --- /dev/null +++ b/assets/admin/img/connecting.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/admin/img/loader2.svg b/assets/admin/img/loader2.svg new file mode 100644 index 00000000..25f1ca19 --- /dev/null +++ b/assets/admin/img/loader2.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/admin/js/onboarding.js b/assets/admin/js/onboarding.js index 9c46ad01..ccbb5c90 100644 --- a/assets/admin/js/onboarding.js +++ b/assets/admin/js/onboarding.js @@ -5,7 +5,7 @@ jQuery(document).ready(function($) { $imgName = $imgInfo.find('.js-onboarding-img-name'), $fields = $('.js-onboarding-field'), $btn = $('.js-onboarding-btn'), - $validateTokenBtn = $('.js-onboarding-validate-token'), + $connectCastosBtn = $('.js-onboarding-castos-connect'), $hostingStep2 = $('.js-hosting-form'), $accordion = $('.js-accordion'), $dragable = $('.js-onboarding-dragable'), @@ -26,7 +26,7 @@ jQuery(document).ready(function($) { } }, initDeleteImgInfo = function(){ - $imgInfo.find('.js-onboarding-delete-img-info').click(function(){ + $imgInfo.find('.js-onboarding-delete-img-info').on('click', function(){ $imgInput.val(''); $imgInfo.hide(); validateOnboarding(); @@ -54,29 +54,33 @@ jQuery(document).ready(function($) { }); }, initTokenValidation = function(){ - $validateTokenBtn.on('validated', function () { - //don't use $btn since it has custom validation - var $form = $validateTokenBtn.closest('form'), - $nextButton = $form.find('button[type=submit]'); - $(this).removeClass('validating'); - if ($validateTokenBtn.hasClass('valid')) { + $connectCastosBtn.on('connected', function (e, response) { + var $form = $connectCastosBtn.closest('form'), + $nextButton = $form.find('button[type=submit]'), + $me = $(this), + $msg = $form.find('.connect-castos-message'), + $field = $('.js-onboarding-castos-connect-field'); + $me.removeClass('connecting'); + $msg.show(); + + if ("success" === response.status) { + $me.html($me.data('connected-txt')); + $field.attr('disabled', 'disabled'); $nextButton.removeAttr('disabled'); - $form.find('.validate-api-credentials-message').html(''); - $(this).html($(this).data('valid-txt')); } else { - $(this).html($(this).data('initial-txt')); + $me.html($me.data('initial-txt')); $nextButton.attr('disabled', 'disabled'); } }); - $validateTokenBtn.on('click', function(){ - $(this).addClass('validating').html($(this).data('validating-txt')); + $connectCastosBtn.on('connecting', function(){ + $(this).addClass('connecting').html($(this).data('connecting-txt')); }); - $('.js-onboarding-validate-token-field').on('change paste keyup', function(){ - var $nextButton = $validateTokenBtn.closest('form').find('button[type=submit]'); - $validateTokenBtn.html($validateTokenBtn.data('initial-txt')); - $validateTokenBtn.removeClass('valid'); + $('.js-onboarding-castos-connect-field').on('change paste keyup', function(){ + var $nextButton = $connectCastosBtn.closest('form').find('button[type=submit]'); + $connectCastosBtn.html($connectCastosBtn.data('initial-txt')); + $connectCastosBtn.removeClass('valid'); $nextButton.attr('disabled', 'disabled'); }); }, @@ -85,7 +89,7 @@ jQuery(document).ready(function($) { validateOnboarding(); }, initHostingConnectionSteps = function(){ - $accordion.click(function () { + $accordion.on('click', function () { let openedClass = 'ssp-onboarding-step-4__accordion--opened', openedFormClass = 'ssp-onboarding-step-4__form--opened'; if ($accordion.hasClass(openedClass)) { @@ -113,7 +117,7 @@ jQuery(document).ready(function($) { e.stopPropagation(); $uploadImageBtn.trigger('click'); }); - $dragable.click(function(){ + $dragable.on('click', function(){ $uploadImageBtn.trigger('click'); }); }, diff --git a/assets/admin/scss/_admin.scss b/assets/admin/scss/_admin.scss index ce7728fd..e85ff61b 100644 --- a/assets/admin/scss/_admin.scss +++ b/assets/admin/scss/_admin.scss @@ -271,6 +271,19 @@ textarea#episode_embed_code { } } +#podmotor_account_api_token { + width: 100%; + min-width: 100%; + display: block; + margin-bottom: 8px; +} + +.ssp-settings-integrations { + table label { + margin-top: 10px; + display: block; + } +} .ssp-settings:not(.ssp-settings-extensions,.ssp-settings-integrations) { background: $clr_white; @@ -298,10 +311,6 @@ textarea#episode_embed_code { } } - .validate-api-credentials-message { - margin-left: 30px; - } - .loader { position: relative; &:after { @@ -334,6 +343,42 @@ textarea#episode_embed_code { } } +.ssp-main-settings { + .error { + color: $clr_red_400; + } + + .hidden { + display: none; + } + + .disconnect-castos { + margin-right: 8px; + vertical-align: middle; + } + + &.tab-castos-hosting { + .loader { + position: relative; + &:after { + content: ''; + display: block; + background: url(../img/loader2.svg) no-repeat; + position: absolute; + right: -50px; + top: -9px; + background-size: contain; + width: 44px; + height: 44px; + } + } + } +} + +.connect-castos-message { + margin-left: 20px; +} + .ssp-sync-podcast { display: flex; justify-content: space-between; diff --git a/assets/admin/scss/_episode-meta-sidebar.scss b/assets/admin/scss/_episode-meta-sidebar.scss new file mode 100644 index 00000000..6b751193 --- /dev/null +++ b/assets/admin/scss/_episode-meta-sidebar.scss @@ -0,0 +1,337 @@ +#ssp-episode-meta-sidebar\:ssp-episode-meta-sidebar { + .interface-complementary-area-header__title { + font-size: 12px; + } +} + +.ssp-episode-meta-sidebar, .ssp-sidebar-panel { + .ssp-accordion { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + padding: 16px; + font-weight: 500; + margin: 0; + background: #fafcfe; + transition: 0.4s; + + &:hover { + background: #f0f7ff; + } + + &:after { + content: ''; + display: inline-block; + position: relative; + width: 10px; + height: 10px; + border-right: 2px solid #383838; + border-bottom: 2px solid #383838; + transform: rotate(45deg); + } + + &.open { + &:after { + transform: rotate(-135deg); + top: 3px; + } + border-bottom: 1px solid #ddd; + } + } + + .ssp-sync-label { + margin-top: 8px; + } + + .ssp-sync-message { + margin-top: 8px; + } +} + +.ssp-sidebar-panel { + width: 100%; + + .ssp-accordion { + background: none; + width: calc(100% + 32px); + margin-left: -16px; + margin-bottom: -16px; + border-top: 1px solid #ddd; + padding: 8px 16px; + + svg { + transform: rotate(180deg); + } + + &:hover { + background: #f0f0f0; + } + &.open { + border-bottom: none; + margin-bottom: 0; + + svg { + transform: rotate(0); + } + } + &:after { + display: none; + } + } + + .ssp-file-info { + display: flex; + margin-top: 8px; + align-items: center; + gap: 4px; + + img { + position: relative; + top: -2px; + } + + span { + color: #555555; + } + } + + .ssp-open-meta-btn { + margin: 16px 0 4px; + color: #555555; + font-weight: 500; + height: 100%; + padding: 4px 0; + text-align: center;; + display: flex; + justify-content: center; + min-height: 32px; + overflow: hidden; + transition: .4s; + width: 100%; + background: #F7F7F7; + + border-radius: 3px; + border-width: 1px 1px 2px 1px; + border-style: solid; + border-color: #CCCCCC; + box-shadow: none; + + &:hover { + box-shadow: none; + color: #007cba; + opacity: 0.8; + } + } +} + +.ssp-episode-meta-sidebar { + .interface-complementary-area-header { + background: #f8fafb; + } + + .components-panel__body { + padding: 0; + &:last-child { + border-bottom: 1px solid #ddd; + } + } + + input[type=text] { + border-radius: 3px; + } + + input[type=checkbox] { + border: 1px solid #CBD5E1; + border-radius: 5px; + } + + .components-checkbox-control__label { + color: #334155; + } + + + .components-radio-control .components-base-control__field > div { + flex-direction: row; + gap: 0.5rem; + justify-content: start; + } + + h3 { + text-transform: none; + font-size: 13px; + font-weight: 500; + margin: 8px 0; + } + + .description { + margin: 12px 0; + font-size: 11px; + line-height: 13px; + color: #64748B; + } + + .ssp-sidebar-content { + padding: 8px 16px; + } + + .ssp-sidebar-field-section { + margin-bottom: 16px; + } + + .flex { + display: flex; + } + + .gap-2 { + gap: 0.5rem; + } + + .w-full { + width: 100%; + } + + .mb-2 { + margin-bottom: 0.5rem; + } + + .ssp-image-uploader { + margin-top: 8px; + + img { + transition:0.4s; + box-shadow: 1px 1px 6px 0 rgba(0, 0, 20, 0.2); + + &:hover { + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); + } + } + + .no-image { + height: 230px; + background: #F6F7F7; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + color: #555; + box-shadow:1px 1px 6px 0 rgba(0, 0, 20, 0.2); + transition:0.4s; + + &:hover { + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); + } + } + + .remove-image { + position: absolute; + top: 4px; + right: 4px; + background: white; + border-radius: 50%; + width: 24px; + height: 24px; + min-width: 24px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + } + } + + .ssp-promo-sidebar { + margin-right: -16px; + margin-left: -16px; + background: #EBF6FF; + padding: 16px; + margin-bottom: -24px; + + &__description { + color: #2271B1; + } + + &__description-row { + display: flex; + gap: 12px; + margin-bottom: 12px; + } + + &__bell { + width: 40px; + min-width: 40px; + height: 40px; + background: #BFDBFE; + border-radius: 4px; + img { + padding: 8px; + } + } + + &__btn { + display: block; + border: 1px solid #2271B1; + border-radius: 3px; + padding: 8px; + width: 100%; + text-decoration: none; + text-align: center; + transition: .4s; + box-shadow: 0 0 4px 0 rgba(0, 0, 20, 0.2); + + &:hover { + background: #eff5fb; + box-shadow: 1px 1px 8px 0 rgba(0, 0, 20, 0.3); + } + + img { + position: relative; + top: 3px; + left: 4px; + } + } + } + + .button { + border: 1px solid #2271B1; + box-shadow: 0 0 4px 0 rgba(0, 0, 20, 0.2); + transition: .4s; + + &:hover:not(:disabled) { + border: 1px solid #2271B1; + background: #f6f7f7; + box-shadow: 1px 1px 4px 0 rgba(0, 0, 20, 0.2); + } + } + + +} + +.ssp-date-input { + .components-popover__content { + padding: 8px; + } + + .components-datetime__time { + fieldset:first-child { + display: none; + } + } +} + +.ssp-calendar-icon { + position: relative; + &:after { + content: ''; + display: inline-block; + position: absolute; + right: 6px; + background: url(../img/calendar.svg) no-repeat; + background-size: contain; + width: 17px; + height: 16px; + top: 7px; + } +} + +.ssp-gut-sidebar-notice { + margin-top: 8px; +} + diff --git a/assets/admin/scss/_onboarding.scss b/assets/admin/scss/_onboarding.scss index a9bda3c3..7eb298af 100644 --- a/assets/admin/scss/_onboarding.scss +++ b/assets/admin/scss/_onboarding.scss @@ -156,7 +156,7 @@ &-step-2, &-step-3, &-step-4, &-step-5 { .ssp-onboarding__steps::after { - background: #DF4E4F; + background: $clr_red_400; width: initial; } } @@ -191,6 +191,10 @@ right: 180px; } + .ssp-onboarding__settings-body { + padding: 24px 24px 36px; + } + &__info { display: flex; flex-direction: column; @@ -317,7 +321,7 @@ li { &:hover { svg path, svg rect { - fill: #DF4E4F; + fill: $clr_red_400; } } } @@ -452,7 +456,7 @@ z-index: 0; visibility: hidden; transition: .6s; - margin-top: -444px; + margin-top: -345px; &--opened { visibility: visible; @@ -585,13 +589,19 @@ margin-top: 25px; position: relative; + span.connect-castos-message { + display: block; + text-align: left; + margin: 20px 0 0; + } + button[type=submit], .button { position: relative; height: 50px; border-radius: 6px; border: 0; color: #FFFFFF; - background: #DF4E4F; + background: $clr_red_400; font-size: 18px; padding: 0 55px 0 33px; transition: .3s; @@ -650,7 +660,7 @@ } } - .validate-token { + .castos-connect { float: left; position: relative; padding: 0 20px 0 45px; @@ -659,42 +669,62 @@ content: ''; display: block; position: absolute; - background: url(../img/validate.svg) no-repeat; - background-size: cover; - left: 19px; - top: 17px; - width: 14px; - height: 18px; - filter: none; + background: url(../img/connect.svg) no-repeat; + left: 13px; + top: 13px; + width: 25px; + height: 23px; + filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(198deg) brightness(101%) contrast(102%); + background-size: contain; + } + + &:disabled { + background: #9CA3AF !important; + color: #D1D5DB !important; + &:after { + //filter: invert(92%) sepia(17%) saturate(74%) hue-rotate(176deg) brightness(92%) contrast(88%); + filter: invert(94%) sepia(8%) saturate(150%) hue-rotate(177deg) brightness(90%) contrast(93%); + transition: none; + } } - &.validating { - background: #374151; + &.connecting { + background: #DE7373 !important; + color: #FFFFFF !important; - &:hover, &:active, &:focus { - background: #374151; + &:hover, &:active, &:focus, &:disabled { + background: #DE7373; } &:after { width: 17px; height: 18px; - background-image: url(../img/validating.svg); + background-image: url(../img/connecting.svg); + animation: rotation 2s infinite linear; + filter: none; + transition: none; + top: 15px; + left: 15px; } } - &.valid { - background: #10B981; + &.connected { + background: #10B981 !important; + color: $clr_white !important; padding: 0 16px 0 45px; - &:hover, &:active, &:focus { background: #10B981; } + opacity: .7; &:after { - width: 16px; - height: 12px; - top: 19px; - background-image: url(../img/checkbox.svg); + background-image: url(../img/connect.svg); + left: 13px; + top: 13px; + width: 25px; + height: 23px; + filter: invert(100%) sepia(100%) saturate(0%) hue-rotate(198deg) brightness(101%) contrast(102%); + background-size: contain; } } } @@ -732,7 +762,7 @@ display: block; height: 1.5px; width: 14px; - background: #DF4E4F; + background: $clr_red_400; position: absolute; left: 7px; top: 46%; @@ -752,12 +782,6 @@ } } - .validate-api-credentials-message { - position: absolute; - left: 0; - bottom: -18px; - } - &__links { display: flex; text-align: left; @@ -822,7 +846,7 @@ width: 30px; height: 30px; background: #FFF; - color: #DF4E4F; + color: $clr_red_400; font-size: 20px; font-weight: 600; border-radius: 50%; @@ -907,7 +931,7 @@ } /* Hide the WP bars */ -.admin_page_ssp-onboarding-1, .admin_page_ssp-onboarding-2, .admin_page_ssp-onboarding-3, .admin_page_ssp-onboarding-4, .admin_page_ssp-onboarding-5 { +.podcast_page_ssp-onboarding-1, .admin_page_ssp-onboarding-1, .admin_page_ssp-onboarding-2, .admin_page_ssp-onboarding-3, .admin_page_ssp-onboarding-4, .admin_page_ssp-onboarding-5 { #adminmenumain, #wpadminbar, #wpfooter { display: none; } diff --git a/assets/admin/scss/all.scss b/assets/admin/scss/all.scss index a35f334c..54727abb 100644 --- a/assets/admin/scss/all.scss +++ b/assets/admin/scss/all.scss @@ -3,3 +3,4 @@ @import "onboarding"; @import "review"; @import "post-publish-panel"; +@import "episode-meta-sidebar"; diff --git a/assets/css/blocks/podcast-list.min.css b/assets/css/blocks/podcast-list.min.css new file mode 100644 index 00000000..60b02276 --- /dev/null +++ b/assets/css/blocks/podcast-list.min.css @@ -0,0 +1 @@ +:root{--ssp-podcast-list-title-size:16px;--ssp-podcast-list-article-margin-bottom:40px;--ssp-podcast-list-gap:10px;--ssp-podcast-list-cols:1}.ssp-podcast-list__articles{display:flex;flex-direction:row;flex-wrap:wrap;gap:var(--ssp-podcast-list-gap)}.ssp-podcast-list__pagination{display:flex;justify-content:space-between}.ssp-podcast-list article{display:flex;flex-direction:column;flex-basis:calc((100% - calc(var(--ssp-podcast-list-gap) * (var(--ssp-podcast-list-cols) - 1)))/ var(--ssp-podcast-list-cols));margin-bottom:var(--ssp-podcast-list-article-margin-bottom);min-width:100px}.ssp-podcast-list article h3{font-size:var(--ssp-podcast-list-title-size)}@media (max-width:1024px){.ssp-podcast-list article{flex-basis:calc((100% - calc(var(--ssp-podcast-list-gap) * (max(2,var(--ssp-podcast-list-cols))/ 2 - 1)))/ (max(2,var(--ssp-podcast-list-cols))/ 2))}}@media (max-width:480px){.ssp-podcast-list article{flex-basis:100%}} \ No newline at end of file diff --git a/assets/css/castos-player.css b/assets/css/castos-player.css index b63f8670..f17c9cb0 100644 --- a/assets/css/castos-player.css +++ b/assets/css/castos-player.css @@ -719,6 +719,7 @@ height: 44px; display: block; border-radius: 50%; + box-sizing: border-box; } .castos-player .play-pause-controls button { position: absolute; diff --git a/assets/css/settings.css b/assets/css/settings.css index 95cb20c5..de8323bb 100644 --- a/assets/css/settings.css +++ b/assets/css/settings.css @@ -18,7 +18,7 @@ height: auto; } -#ssp-main-settings { +#ssp-main-settings.castos-disconnected { width: 75%; float: left; } @@ -36,11 +36,6 @@ overflow: hidden; } -#ssp-sidebar .sidebar-content.castos-connected { - border: none; - background: none; -} - #ssp-sidebar .sidebar-content h3 { color: #6c25d0; margin: -20px -20px 0 -20px; diff --git a/assets/js/admin-menu.js b/assets/js/admin-menu.js new file mode 100644 index 00000000..e75ddc8f --- /dev/null +++ b/assets/js/admin-menu.js @@ -0,0 +1,11 @@ +jQuery( document ).ready( function( $ ) { + var initOnboardingMenu = function() { + var $firstMenuItem = $( '#menu-posts-podcast' ).find( '.wp-submenu a.wp-first-item' ); + + if ( $firstMenuItem.length && $firstMenuItem.attr( 'href' ).includes( 'page=ssp-onboarding-1' ) ) { + $firstMenuItem.closest('ul').find('li').not('.wp-first-item').hide(); + } + } + + initOnboardingMenu(); +} ); diff --git a/assets/js/admin.js b/assets/js/admin.js index 65937b54..575f8f85 100644 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -3,10 +3,10 @@ jQuery(document).ready(function($) { // Uploading files var file_frame, series_img_frame; - $.fn.ssp_upload_media_file = function( button, preview_media, validateImageSize = false ) { - var button_id = button.attr('id'); - var field_id = button_id.replace( '_button', '' ); - var preview_id = button_id.replace( '_button', '_preview' ); + $.fn.ssp_upload_media_file = function( button, validateCallback = null ) { + //var button_id = button.attr('id'); + var field_class = button.data( 'field' ); + var preview_class = button.data( 'preview' ); // Create the media frame. file_frame = wp.media.frames.file_frame = wp.media({ @@ -19,16 +19,16 @@ jQuery(document).ready(function($) { // When an image is selected, run a callback. file_frame.on( 'select', function() { - var attachment = file_frame.state().get('selection').first().toJSON(); + var attachment = file_frame.state().get('selection').first().toJSON(); - if ( typeof validateImageSize === 'function' && !validateImageSize( attachment ) ) { - return; - } + if ( typeof validateCallback === 'function' && ! validateCallback(attachment) ) { + return; + } - $("#"+field_id).val(attachment.url); - if ( preview_media ) { - $("#"+preview_id).attr('src',attachment.url); - } + $('input.' + field_class).val(attachment.url).trigger('change'); + if ( preview_class ) { + $('.' + preview_class).attr('src', attachment.url); + } }); // Finally, open the modal @@ -36,7 +36,7 @@ jQuery(document).ready(function($) { }; /* Add/Edit Series Image */ - $('#series_upload_image_button').click(function( event ){ + $('#series_upload_image_button').on('click', function( event ){ event.preventDefault(); var send_attachment_bkp = wp.media.editor.send.attachment; var button = $(this); @@ -78,7 +78,7 @@ jQuery(document).ready(function($) { }); /* Remove/clear Series Image */ - $('#series_remove_image_button').click(function( event ){ + $('#series_remove_image_button').on('click', function( event ){ event.preventDefault(); var button = $(this); var button_id = button.attr('id'); @@ -93,17 +93,16 @@ jQuery(document).ready(function($) { }); /* ADD/EDIT EPISODE */ - - $('#upload_audio_file_button').click(function( event ){ + $('body').on('click', '.ssp-upload-file', function( event ){ event.preventDefault(); - $.fn.ssp_upload_media_file( $(this), false ); + $.fn.ssp_upload_media_file( $(this) ); }); - $('#episode_embed_code').click(function() { + $('#episode_embed_code').on('click', function() { $(this).select(); }); - $( '.episode_embed_code_size_option' ).change(function() { + $( '.episode_embed_code_size_option' ).on('change', function() { var width = $( '#episode_embed_code_width' ).val(); var height = $( '#episode_embed_code_height' ).val(); @@ -139,7 +138,7 @@ jQuery(document).ready(function($) { var d = $.datepicker.parseDate("d MM, yy", dateText); var date = $.datepicker.formatDate("yy-mm-dd", d); var save_field = $(this).attr('id').replace( '_display', '' ); - $( '#' + save_field ).val( date ); + $( '#' + save_field ).val( date ).trigger('change'); } }); @@ -154,7 +153,7 @@ jQuery(document).ready(function($) { /* SETTINGS PAGE */ - $('#feed-series-toggle').click(function(e) { + $('#feed-series-toggle').on('click', function(e) { if ( $(this).hasClass( 'series-open' ) ) { $('#feed-series-list').slideUp('fast'); @@ -170,13 +169,13 @@ jQuery(document).ready(function($) { }); - $('#ss_podcasting_data_image_delete').click(function() { + $('#ss_podcasting_data_image_delete').on('click', function() { $( '#ss_podcasting_data_image' ).val( '' ); $( '#ss_podcasting_data_image_preview' ).attr('src', ''); return false; }); - $('#cover_image_button, #ss_podcasting_data_image_button').click(function (e) { + $('#cover_image_button, #ss_podcasting_data_image_button').on('click', function (e) { var coverImgValidator = function (attachment) { return attachment.width === attachment.height && attachment.width >= 300; }, @@ -187,18 +186,18 @@ jQuery(document).ready(function($) { attachment.width <= maxWidth && attachment.height === attachment.width; }, - validateImageSize = 'cover_image_button' === $(e.target).prop('id') ? coverImgValidator : feedImgValidator, + validateImage = 'cover_image' === $(e.target).data('validator') ? coverImgValidator : feedImgValidator, description = $(this).parent().find('.description'), $img = 'cover_image_button' === $(e.target).prop('id') ? $('#cover_image_id') : $('#ss_podcasting_data_image_preview'); - $.fn.ssp_upload_media_file($(this), true, validateImageSize); + $.fn.ssp_upload_media_file($(this), validateImage); description.css('color', ''); file_frame.on('select', function () { var attachment = file_frame.state().get('selection').first().toJSON(); - if (validateImageSize(attachment)) { + if (validateImage(attachment)) { $img.val(attachment.id); } else { description.css('color', 'red'); @@ -206,9 +205,9 @@ jQuery(document).ready(function($) { }); }); - $('#cover_image_delete').click(function() { - $( '#cover_image, #cover_image_id' ).val( '' ); - $( '#cover_image_preview' ).attr( 'src', '' ); + $('.ssp-image-delete').on('click', function(){ + $('.' + $(this).data('field')).val('').trigger('change'); + $('.' + $(this).data('preview')).attr('src', '').trigger('change'); }); $('.js-ssp-select2').select2(); @@ -253,9 +252,52 @@ jQuery(document).ready(function($) { subtitle = $dynamo.data('default-podcast-title'); } - changeUrlArg('s', subtitle) + changeUrlArg('s', subtitle.replace(" (default)", "")) }); } + var initNotifications = function () { + $('.notice.is-constant').on( 'click', '.notice-dismiss', function () { + var $notice = $(this).closest('.notice'), + data = { + 'action': 'remove_constant_notice', + 'id': $notice.data('id'), + 'nonce': $notice.data('nonce'), + }; + + $.post(ajaxurl, data); + }); + }; + + var initSSPControls = function () { + $('.js-open-ssp-controls').on('click', function () { + $('.ssp-open').trigger('click'); + }); + + // Send changed event to Gutenberg + $('.ssp-sync').on('change', function () { + var value = $(this).val(); + value = 'checkbox' === $(this).attr('type') && ! $(this).is(':checked') ? '' : value; + document.dispatchEvent(new CustomEvent('changedSSPField', { + 'detail': { field: $(this).prop('name'), value: value } + })); + }); + + // Listen changed event from Gutenberg + document.addEventListener('changedSSPGutField', function ( event ) { + var data = event.detail; + + $('input.ssp-sync[type="text"][name="' + data.field + '"]').val(data.value); + $('input.ssp-sync[type="number"][name="' + data.field + '"]').val(data.value); + $('input.ssp-sync[type="hidden"][name="' + data.field + '"]').val(data.value); + $('input.ssp-sync[type="radio"][name="' + data.field + '"][value="' + data.value + '"]').prop('checked', true); + $('select.ssp-sync[name="' + data.field + '"] option[value="' + data.value + '"]').prop('selected', true); + $('input.ssp-sync[type="checkbox"][name="' + data.field + '"]').prop('checked', 'on' === data.value); + $('img.ssp-sync.ssp-preview-' + data.field).prop('src', data.value); + }); + }; + initDynamoBtn(); + initNotifications(); + initSSPControls(); }); diff --git a/assets/js/fileupload.js b/assets/js/fileupload.js index 8567d5b7..de2137ca 100644 --- a/assets/js/fileupload.js +++ b/assets/js/fileupload.js @@ -56,23 +56,21 @@ jQuery( document ).ready( function ( $ ) { * If the upload_credentials object isn't available */ if ( typeof upload_credentials != "undefined" ) { - initUploader(); + initUploader({ + runtimes: 'html5', + browse_button: 'ssp_select_file', + multi_selection: false, + container: 'ssp_upload_container', + url: upload_credentials.castos_api_url + 'files', + }); } - function initUploader(){ + function initUploader(config){ /** * Creates instance of plupload * @type {module:plupload.Uploader} */ - var uploader = new plupload.Uploader( - { - runtimes: 'html5', - browse_button: 'ssp_select_file', - multi_selection: false, - container: 'ssp_upload_container', - url: upload_credentials.castos_api_url + 'files', - } - ); + var uploader = new plupload.Uploader(config); /** * Init Uploader @@ -151,11 +149,11 @@ jQuery( document ).ready( function ( $ ) { var file = response.file, fileName = up.files[0].name; - $( "#podmotor_file_id" ).val( file.id ); - $( "#filesize_raw" ).val( file.file_size ); - $( "#filesize" ).val( plupload.formatSize( file.file_size ) ); - $( "#duration" ).val( file.file_duration ); - $( '#upload_audio_file' ).val( file.file_path ); + $( "#podmotor_file_id" ).val( file.id ).trigger('change'); + $( "#filesize_raw" ).val( file.file_size ).trigger('change'); + $( "#filesize" ).val( plupload.formatSize( file.file_size ) ).trigger('change'); + $( "#duration" ).val( file.file_duration ).trigger('change'); + $( '#upload_audio_file' ).val( file.file_path ).trigger('change'); $( '.peek-a-bar' ).fadeOut( 5000 ); $('#castos_file_data').val(JSON.stringify({ path: file.file_path, diff --git a/assets/js/jquery.peekabar.js b/assets/js/jquery.peekabar.js index 9a94a2ed..ca6e1bea 100644 --- a/assets/js/jquery.peekabar.js +++ b/assets/js/jquery.peekabar.js @@ -157,7 +157,7 @@ /** Close the bar on click */ var _applyCloseOnClick = function() { if(that.settings.closeOnClick) { - that.bar.click(function() { + that.bar.on('click', function() { that.hide(); }); } diff --git a/assets/js/settings.js b/assets/js/settings.js index d6bad924..f9ad1116 100644 --- a/assets/js/settings.js +++ b/assets/js/settings.js @@ -5,11 +5,8 @@ */ jQuery(document).ready(function($) { - - var $podmotorAccountEmail = $("#podmotor_account_email"), - $podmotorAccountAPIToken = $("#podmotor_account_api_token"), - $parentCategories = $('.js-parent-category'), - $validateBtn = $("#validate_api_credentials"); + var $podmotorAccountAPIToken = $("#podmotor_account_api_token"), + $parentCategories = $('.js-parent-category'); const { __ } = wp.i18n; @@ -35,103 +32,106 @@ jQuery(document).ready(function($) { } function initCastosAPICredentials() { - var disableSubmitButton = function () { - /** - * If either API field is empty, disable the submit button - */ - if ($podmotorAccountEmail.val() === '' || $podmotorAccountAPIToken.val() === '') { - $("#ssp-settings-submit").prop("disabled", "disabled"); - } - - /** - * If the user changes the email, disable the submit button - */ - $podmotorAccountEmail.on("change paste keydown keyup", function () { - $("#ssp-settings-submit").prop("disabled", "disabled"); - }); - - /** - * If the user changes the account api key, disable the submit button - */ - $podmotorAccountAPIToken.on("change paste keydown keyup", function () { - $("#ssp-settings-submit").prop("disabled", "disabled"); - }); - }, - /** - * Validate the api credentials - */ - validateAPICredentials = function () { - $validateBtn.on("click", function () { - - var podmotor_account_email = $("#podmotor_account_email").val(), - podmotor_account_api_token = $("#podmotor_account_api_token").val(), - nonce = $("#podcast_settings_tab_nonce").val(), - $msg = $('.validate-api-credentials-message'); - - if (!$msg.length) { - $msg = $(''); - $validateBtn.parent().append($msg); - } - - $msg.html("Validating API credentials..."); - - $validateBtn.addClass('loader'); - - $.ajax({ - method: "GET", - url: ajaxurl, - data: { - action: "validate_castos_credentials", - api_token: podmotor_account_api_token, - email: podmotor_account_email, - nonce: nonce - } - }) - .done(function (response) { - $validateBtn.removeClass('loader'); - if (response.status === 'success') { - $(".validate-api-credentials-message").html("Credentials Valid. Please click 'Save Settings' to save Credentials."); - $("#ssp-settings-submit").prop("disabled", ""); - $validateBtn.val('Valid Credentials'); - $validateBtn.addClass('valid'); - } else { - $validateBtn.addClass('invalid'); - $(".validate-api-credentials-message").html(response.message); - } - $validateBtn.trigger('validated'); - }); - }); - }, - /** - * Disconnect Castos checkbox on change, renders a confirmation message to the user. - */ - disconnectCastos = function () { - $('#podmotor_disconnect').on('change', function (event) { - var $checkbox = $(this); - - // if the change is to uncheck the checkbox - if (!$checkbox.is(':checked')) { - return; - } - - var $message = 'If you disconnect from Castos hosting you will no longer be able to upload media files to the Castos hosting platform. If you’re no longer a Castos customer your media files may no longer be available to your listeners.'; - var user_input = confirm($message); - if (user_input !== true) { - // Ensures this code runs AFTER the browser handles click however it wants. - setTimeout(function () { - $checkbox.removeAttr('checked'); - }, 0); - event.preventDefault(); - event.stopPropagation(); - } - }); - } - - if ($podmotorAccountEmail.length > 0 && $podmotorAccountAPIToken.length > 0) { - disableSubmitButton(); - validateAPICredentials(); - disconnectCastos(); + var $connectBtn = $(".castos-connect"), + disableConnectButton = function(){ + $connectBtn.prop("disabled", "disabled"); + }, + enableConnectButton = function(){ + $connectBtn.prop("disabled", "").removeClass('disabled'); + }, + connectButtonStates = function () { + if ($podmotorAccountAPIToken.length) { + $connectBtn.show(); + } + $podmotorAccountAPIToken.on("focus change paste keydown keyup", function () { + $podmotorAccountAPIToken.val() ? enableConnectButton() : disableConnectButton(); + }); + + $podmotorAccountAPIToken.on("focus", function(){ + $('.connect-castos-message').html('').removeClass('error'); + }); + }, + /** + * Validate the api credentials + */ + initConnect = function () { + $connectBtn.on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + $connectBtn.prop('disabled', 'disabled'); + $connectBtn.trigger('connecting'); + + var podmotor_account_api_token = $('#podmotor_account_api_token').val(), + nonce = $('#podcast_settings_tab_nonce').val(), + $msg = $('.connect-castos-message'); + + if ($msg.length) { + $msg.html('').removeClass('error'); + } else { + $msg = $(''); + $connectBtn.parent().append($msg); + } + + $connectBtn.addClass('loader'); + + $.ajax({ + method: 'GET', + url: ajaxurl, + data: { + action: 'connect_castos', + api_token: podmotor_account_api_token, + nonce: nonce, + }, + }) + .done(function (response) { + $connectBtn.trigger('connected', response); + if (response.status === 'success') { + $connectBtn.addClass('connected'); + if ( ! $connectBtn.data( 'no-reload' ) ) { + window.location.reload(); + } else { + $msg.html( response.message ); + } + } else { + $connectBtn.removeClass('loader'); + $msg.addClass('error'); + $msg.html(response.message); + } + }) + }) + }, + /** + * Disconnect Castos checkbox on change, renders a confirmation message to the user. + */ + initDisconnect = function () { + var $disconnect = $('#disconnect_castos'); + $disconnect.on('click', function (event) { + var $message = 'If you disconnect from Castos hosting you will no longer be able to upload media files to the Castos hosting platform. If you’re no longer a Castos customer your media files may no longer be available to your listeners.'; + var user_input = confirm($message); + if (user_input === true) { + $disconnect.addClass('loader'); + $disconnect.parent().find('label').remove(); + $.ajax({ + method: 'GET', + url: ajaxurl, + data: { + action: 'disconnect_castos', + nonce: $('#podcast_settings_tab_nonce').val(), + }, + }) + .done(function (response) { + window.location.reload(); + }) + } + }); + } + + if ($podmotorAccountAPIToken.length > 0) { + connectButtonStates(); + initConnect(); } + + initDisconnect(); } function initSubcategoryFiltration(){ @@ -167,11 +167,11 @@ jQuery(document).ready(function($) { } updateSyncBtn(); - getPodcastCheckboxes().change(function(){ + getPodcastCheckboxes().on('change', function(){ updateSyncBtn(); }); - $syncBtn.click(function(){ + $syncBtn.on('click', function(){ $syncBtn.addClass('loader'); var $msg = $('.ssp-sync-msg'), diff --git a/package.json b/package.json index 86cfe793..f5bb8341 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "seriously-simple-podcasting", - "version": "3.2.0", + "version": "3.7.1", "main": "build/index.js", "author": "CastosHQ", "devDependencies": { diff --git a/php/classes/controllers/class-ads-controller.php b/php/classes/controllers/class-ads-controller.php index 61b0a0e5..29f55e43 100644 --- a/php/classes/controllers/class-ads-controller.php +++ b/php/classes/controllers/class-ads-controller.php @@ -113,7 +113,7 @@ protected function is_ads_enabled_in_castos() { $series_id = $this->get_current_feed_series_id(); - if ( empty( $podcasts['data']['podcast_list'] ) ) { + if ( ! is_array( $podcasts ) || empty( $podcasts['data']['podcast_list'] ) ) { return false; } diff --git a/php/classes/controllers/class-app-controller.php b/php/classes/controllers/class-app-controller.php index bafc448a..61db4af3 100644 --- a/php/classes/controllers/class-app-controller.php +++ b/php/classes/controllers/class-app-controller.php @@ -259,7 +259,9 @@ protected function bootstrap() { $this->episode_repository = new Episode_Repository( $this->feed_handler ); - $this->castos_handler = new Castos_Handler( $this->feed_handler, $this->logger ); + $this->admin_notices_handler = new Admin_Notifications_Handler(); + + $this->castos_handler = new Castos_Handler( $this->feed_handler, $this->logger, $this->admin_notices_handler ); $this->onboarding_controller = new Onboarding_Controller( $this->renderer, $this->settings_handler ); @@ -273,15 +275,13 @@ protected function bootstrap() { $this->widgets_controller = new Widgets_Controller( $this->file, $this->version ); - $this->ajax_handler = new Ajax_Handler( $this->castos_handler ); + $this->ajax_handler = new Ajax_Handler( $this->castos_handler, $this->admin_notices_handler ); $this->podping_handler = new Podping_Handler( $this->logger ); - $this->admin_notices_handler = new Admin_Notifications_Handler( $this->token ); - $this->assets_controller = new Assets_Controller(); - $this->series_handler = new Series_Handler( $this->admin_notices_handler, $this->roles_handler, $this->castos_handler, $this->settings_handler, $this->episode_repository ); + $this->series_handler = new Series_Handler( $this->admin_notices_handler, $this->roles_handler, $this->castos_handler, $this->settings_handler, $this->episode_repository ); $this->upgrade_handler = new Upgrade_Handler( $this->episode_repository, $this->castos_handler, $this->series_handler ); @@ -331,7 +331,7 @@ protected function bootstrap() { $this->load_plugin_textdomain(); } - protected function init_integrations(){ + protected function init_integrations() { /* * Gutenberg integration. * Only load Blocks if the WordPress version is newer than 5.0. @@ -348,17 +348,8 @@ protected function init_integrations(){ // Yoast Schema integration. new Schema_Controller( $this->episode_repository ); - // Paid Memberships Pro integration - Paid_Memberships_Pro_Integrator::instance()->init( $this->feed_handler, $this->castos_handler, $this->logger, $this->admin_notices_handler ); - - // Lifter LMS integration - LifterLMS_Integrator::instance()->init( $this->feed_handler, $this->castos_handler, $this->logger ); - - // Paid Memberships Pro integration - Memberpress_Integrator::instance()->init( $this->feed_handler, $this->castos_handler, $this->logger, $this->admin_notices_handler ); - - // Woocommerce Memberships integration - WC_Memberships_Integrator::instance()->init( $this->feed_handler, $this->castos_handler, $this->logger, $this->admin_notices_handler ); + // Membership integrations. + new Integrations_Controller( $this->feed_handler, $this->castos_handler, $this->logger, $this->admin_notices_handler ); } /** @@ -393,7 +384,7 @@ public function get_available_services() { * * @return string * */ - protected function get_wp_version(){ + protected function get_wp_version() { global $wp_version; return $wp_version; @@ -402,7 +393,7 @@ protected function get_wp_version(){ /** * Init REST API */ - protected function init_rest_api(){ + protected function init_rest_api() { global $wp_version; // Only load WP REST API Endpoints if the WordPress version is newer than 4.7. @@ -494,7 +485,6 @@ public function get_settings_handler() { } - /** * Register the Castos Blog dashboard widget * Hooks into the wp_dashboard_setup action hook @@ -547,9 +537,9 @@ public function ssp_castos_dashboard_output( $widget_id, $feeds ) { /** * Check if there is a cached version of the RSS Feed and output it */ - $locale = get_user_locale(); - $cache_key = 'ssp_dash_v2_' . md5( $widget_id . '_' . $locale ); - $rss_output = get_transient( $cache_key ); + $locale = get_user_locale(); + $cache_key = 'ssp_dash_v2_' . md5( $widget_id . '_' . $locale ); + $rss_output = get_transient( $cache_key ); if ( false !== $rss_output ) { return $rss_output; } @@ -568,13 +558,14 @@ public function ssp_castos_dashboard_output( $widget_id, $feeds ) { * Set up the cached version to expire in 12 hours and output the content */ set_transient( $cache_key, $rss_output, 12 * HOUR_IN_SECONDS ); + return $rss_output; } /** * Adding podcast episodes to 'At a glance' dashboard widget * - * @param array $items Existing items + * @param array $items Existing items * * @return array Updated items */ @@ -583,8 +574,8 @@ public function glance_items( $items = array() ) { $num_posts = count( ssp_episodes( - 1, '', false, 'glance' ) ); $post_type_object = get_post_type_object( $this->token ); - $text = _n( '%s Episode', '%s Episodes', $num_posts, 'seriously-simple-podcasting' ); - $text = sprintf( $text, number_format_i18n( $num_posts ) ); + $text = _n( '%s Episode', '%s Episodes', $num_posts, 'seriously-simple-podcasting' ); + $text = sprintf( $text, number_format_i18n( $num_posts ) ); if ( $post_type_object && current_user_can( $post_type_object->cap->edit_posts ) ) { $items[] = sprintf( '%2$s', $this->token, $text ) . "\n"; @@ -598,10 +589,10 @@ public function glance_items( $items = array() ) { /** * Adding appreciation links to the SSP record in the plugin list table * - * @param array $plugin_meta Default plugin meta links - * @param string $plugin_file Plugin file - * @param array $plugin_data Array of plugin data - * @param string $status Plugin status + * @param array $plugin_meta Default plugin meta links + * @param string $plugin_file Plugin file + * @param array $plugin_data Array of plugin data + * @param string $status Plugin status * * @return array Modified plugin meta links */ @@ -613,6 +604,7 @@ public function plugin_row_meta( $plugin_meta = array(), $plugin_file = '', $plu $plugin_meta['docs'] = '' . __( 'Documentation', 'seriously-simple-podcasting' ) . ''; $plugin_meta['addons'] = '' . __( 'Add-ons', 'seriously-simple-podcasting' ) . ''; $plugin_meta['review'] = '' . __( 'Write a review', 'seriously-simple-podcasting' ) . ''; + return $plugin_meta; } @@ -650,7 +642,7 @@ public function load_plugin_textdomain() { /** * Hide RSS footer created by WordPress SEO from podcast RSS feed * - * @param boolean $include_footer Default inclusion value + * @param boolean $include_footer Default inclusion value * * @return boolean Modified inclusion value */ @@ -688,6 +680,7 @@ public function activate() { public function deactivate() { flush_rewrite_rules(); $this->roles_handler->remove_custom_roles(); + $this->castos_handler->remove_api_credentials(); } /** @@ -710,7 +703,7 @@ public function maybe_run_plugin_updates() { /** * Add rating link to admin footer on SSP settings pages * - * @param string $footer_text Default footer text + * @param string $footer_text Default footer text * * @return string Modified footer text */ @@ -722,9 +715,9 @@ public function admin_footer_text( $footer_text ) { // Change the footer text if ( ! get_option( 'ssp_admin_footer_text_rated' ) ) { $footer_text = sprintf( __( 'If you like %1$sSeriously Simple Podcasting%2$s please leave a %3$s★★★★★%4$s rating. A huge thank you in advance!', 'seriously-simple-podcasting' ), '', '', '', '' ); - $footer_text .= sprintf(" - diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php index 269a6c2e..340d8454 100644 --- a/tests/_support/AcceptanceTester.php +++ b/tests/_support/AcceptanceTester.php @@ -473,7 +473,7 @@ protected function isAbsoluteUrl( $url ) { } protected function createEpisode( $args ) { - $this->iClickMenuSubmenu( 'Podcast', "Add New" ); + $this->iClickMenuSubmenu( 'Podcast', "Add New Episode" ); $this->iFillTheFieldWith( 'Episode title', $args[0] ); $this->iFillTheFieldWith( 'Episode content', $args[1] ); @@ -490,6 +490,15 @@ public function iCanSeeInSource( $arg1 ) { if ( false !== strpos( $arg1, '{{base_url}}' ) ) { $arg1 = str_replace( '{{base_url}}', $this->getConfig( 'url' ), $arg1 ); } + elseif ( false !== strpos( $arg1, '{{base_url_without_port}}' ) ) { + $parts = parse_url($this->getConfig( 'url' )); + $url = $parts['scheme'] . '://' . $parts['host']; + $arg1 = str_replace( '{{base_url_without_port}}', $url, $arg1 ); + } + elseif ( false !== strpos( $arg1, '{{podcast_guid}}' ) ) { + $arg1 = str_replace( '{{podcast_guid}}', $this->getConfig( 'podcastGuid' ), $arg1 ); + } + $this->seeInSource( $arg1 ); } } diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 68911396..9cdf995b 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -7,24 +7,13 @@ actor: AcceptanceTester modules: enabled: -# - WPBrowser - PhpBrowser: -# url: http://castos.loc - \Helper\Acceptance -# - WPWebDriver: -# url: 'http://castos.loc' -# browser: phantomjs -# port: 4444 -# restart: true -# wait: 2 -# adminUsername: admin -# adminPassword: password -# adminUrl: /wp-admin - config: PhpBrowser: url: '%SITE_URL%' adminPath: '%SITE_URL%/wp-admin' + podcastGuid: '%PODCAST_GUID%' step_decorators: ~ diff --git a/tests/acceptance/1_onboarding.feature b/tests/acceptance/0_onboarding.feature similarity index 100% rename from tests/acceptance/1_onboarding.feature rename to tests/acceptance/0_onboarding.feature diff --git a/tests/acceptance/0_default_podcast.feature b/tests/acceptance/1_default_podcast.feature similarity index 52% rename from tests/acceptance/0_default_podcast.feature rename to tests/acceptance/1_default_podcast.feature index 05bd3179..96de09ad 100644 --- a/tests/acceptance/0_default_podcast.feature +++ b/tests/acceptance/1_default_podcast.feature @@ -5,20 +5,15 @@ Feature: Login Background: Given I login as admin - And I am on the plugins page - And I can see SSP plugin is deactivated - Then I activate the SSP plugin Scenario: Check the default feed When I go to the "/wp-admin/edit-tags.php?taxonomy=series&post_type=podcast" - Then I can see "My WordPress (default)" - And I can see "my-wordpress" - And I can see "/feed/podcast/my-wordpress" + Then I can see "Automated test show (default)" + And I can see "automated-test-show" + And I can see "/feed/podcast/automated-test-show" Given I want to "Be redirected from the old default feed URL to the term-based URL" When I go to the "/feed/podcast" - Then I can see that current url is "/feed/podcast/my-wordpress" + Then I can see that current url is "/feed/podcast/automated-test-show" When I go to the "/feed/podcast/not-existing-feed" - Then I can see that current url is "/feed/podcast/my-wordpress" - Then I am on the plugins page - And I deactivate the SSP plugin + Then I can see that current url is "/feed/podcast/automated-test-show" diff --git a/tests/acceptance/2_settings-episode-itunes.feature b/tests/acceptance/2_settings-episode-itunes.feature index 110f4b0d..360fd3e7 100644 --- a/tests/acceptance/2_settings-episode-itunes.feature +++ b/tests/acceptance/2_settings-episode-itunes.feature @@ -7,7 +7,7 @@ Feature: Create new episode Given I login as admin Scenario: "Enable iTunes fields" option works properly - When I click "Podcast" submenu "Add New" + When I click "Podcast" submenu "Add New Episode" Then I can see "Add New Episode" And I can not see "iTunes Episode Number:" And I can not see "The iTunes Episode Number. Leave Blank If None." @@ -22,7 +22,7 @@ Feature: Create new episode Then I check "Enable iTunes fields" checkbox And I save settings - When I click "Podcast" submenu "Add New" + When I click "Podcast" submenu "Add New Episode" Then I can see "Add New Episode" And I can see "iTunes Episode Number:" And I can see "The iTunes Episode Number. Leave Blank If None." diff --git a/tests/acceptance/2_settings-hosting.feature b/tests/acceptance/2_settings-hosting.feature index bca393c3..527031d0 100644 --- a/tests/acceptance/2_settings-hosting.feature +++ b/tests/acceptance/2_settings-hosting.feature @@ -12,8 +12,6 @@ Feature: SSP Plugin Hosting Settings Scenario: All hosting settings exist Then I can see "Podcast Hosting" - And I can see "Your email" - And I can see "The email address you used to register your Castos account." - And I can see "Castos API key" - And I can see "Your Castos API key. Available from your Castos account dashboard." - And I can see "Verify Credentials" + And I can see "Castos API token" + And I can see "Your Castos API token. Available from your" + And I can see "Connect" diff --git a/tests/acceptance/3_main-feed.feature b/tests/acceptance/3_main-feed.feature index 81e88d49..e248950b 100644 --- a/tests/acceptance/3_main-feed.feature +++ b/tests/acceptance/3_main-feed.feature @@ -54,8 +54,7 @@ Feature: Login And I can see in source "This show is to test some SSP functionality" And I can see in source "No" And I can see in source "yes" - And I can see in source "115e423a-72d2-531e-9d3c-ece7dd4b74fe" - + And I can see in source "" # Check items And I can see in source "Episode3" @@ -64,7 +63,7 @@ Feature: Login And I can see in source "" And I can see in source "" And I can see in source "" - And I can see in source "" And I can see in source "type=\"audio/mpeg\">" And I can see in source "" And I can see in source "false" diff --git a/tests/seed.sql.gz b/tests/seed.sql.gz new file mode 100644 index 00000000..9356c971 Binary files /dev/null and b/tests/seed.sql.gz differ diff --git a/tests/wpunit/Players_Controller_Test.php b/tests/wpunit/Players_Controller_Test.php index 512e2eb8..0655ecce 100644 --- a/tests/wpunit/Players_Controller_Test.php +++ b/tests/wpunit/Players_Controller_Test.php @@ -1,5 +1,7 @@ episode_repository(); - $this->players_controller = new Players_Controller($renderer, $options_handler, $episode_repository); + $this->players_controller = new Players_Controller( $renderer, $options_handler, $episode_repository ); $episode_id = $this->factory->post->create( array( 'title' => 'My Custom Podcast', @@ -37,12 +39,24 @@ public function test_player_controller_html_player_method() { ) ); $episode = get_post( $episode_id ); + $html_player_content = $this->players_controller->render_html_player( $episode->ID ); + + // Empty, because the file is not assigned + $this->assertEmpty( $html_player_content ); + + // Now, let's check that it's not empty for admin + define( 'WP_ADMIN', true ); + $html_player_content = $this->players_controller->render_html_player( $episode->ID ); + $this->assertNotEmpty( $html_player_content ); + $permalink = get_post_permalink( $episode_id ); $site_url = site_url(); + $this->assertStringContainsString( 'Warning: the player will not be shown', $html_player_content ); + $player_parts = array( - 'class="castos-player dark-mode"', + 'class="castos-player dark-mode', '
', sprintf( '
%s
', $episode->post_title ), '
', @@ -84,7 +98,7 @@ public function test_player_controller_html_player_method() { '
', 'RSS Feed', - sprintf( '', $site_url, $episode_id ), + sprintf( '', $site_url, $episode_id ), sprintf( '', $episode_id ), @@ -110,7 +124,7 @@ public function test_player_controller_html_player_method() { 'target="_blank" rel="noopener noreferrer" class="share-icon download" title="Download" download>', '
', 'Link', - sprintf( '', $permalink, $episode_id ), + sprintf( '', $permalink, $episode_id ), sprintf( '', $episode_id ), '
', 'Embed',