diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 000000000..a0777a2a3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+*.build.js
\ No newline at end of file
diff --git a/common/php/class-module.php b/common/php/class-module.php
index 0d7231d66..52c53e762 100644
--- a/common/php/class-module.php
+++ b/common/php/class-module.php
@@ -483,15 +483,20 @@ function users_select_form( $selected = null, $args = null ) {
// Add a class to checkbox of current user so we know not to add them in notified list during notifiedMessage() js function
$current_user_class = ( get_current_user_id() == $user->ID ) ? 'class="post_following_list-current_user" ' : '';
?>
-
+
ID, $checked ) ?>
/>
- display_name ); ?>
- user_email ); ?>
+
+
display_name ); ?>
+
user_email ); ?>
+
+ ID, $checked ); ?>
+
+
diff --git a/modules/notifications/dist/notifications.build.js b/modules/notifications/dist/notifications.build.js
new file mode 100644
index 000000000..561a8d115
--- /dev/null
+++ b/modules/notifications/dist/notifications.build.js
@@ -0,0 +1,2 @@
+!function(e){var t={};function r(o){if(t[o])return t[o].exports;var n=t[o]={i:o,l:!1,exports:{}};return e[o].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(o,n,function(t){return e[t]}.bind(null,n));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){var r="error",o={NO_ACCESS:{id:"no_access",name:ef_notifications_localization.no_access,status:r},NO_EMAIL:{id:"no_email",name:ef_notifications_localization.no_email,status:r},POST_AUTHOR:{id:"post_author",name:ef_notifications_localization.post_author,class:"ef-badge-neutral"},AUTO_SUBSCRIBE:{id:"auto_subscribed",name:ef_notifications_localization.auto_subscribed,class:"ef-badge-neutral"}},n=function(e,t){var r=e.find("[data-badge-id='".concat(t.id,"']"));return r.length?jQuery(r[0]):null},a=function(e,t){n(e,t)||e.append(function(e){var t="ef-user-badge";return r===e.status&&(t+=" ef-user-badge-error"),'').concat(e.name,"
")}(t))},i=function(e,t){var r=n(e,t);r&&r.remove()};jQuery(document).ready(function(e){jQuery("#ef-post_following_users_box ul").listFilterizer();var t,r={action:"save_notifications",post_id:jQuery("#post_ID").val()};"undefined"!=typeof ef_post_author_id&&(t=jQuery("label[for='ef-selected-users-"+ef_post_author_id+"'] .ef-user-list-badges"),a(t,o.POST_AUTHOR));"undefined"!=typeof ef_post_author_auto_subscribe&&(!function(){var e=jQuery("label[for='ef-selected-users-"+ef_post_author_id+"'] .ef-user-list-badges");a(e,o.AUTO_SUBSCRIBE)}(),jQuery("#ef-selected-users-"+ef_post_author_id).prop("disabled",!0)),jQuery(document).on("click",".ef-post_following_list li input:checkbox, .ef-following_usergroups li input:checkbox",function(){var t=[],n=jQuery(this);r.ef_notifications_name=jQuery(this).attr("name"),r._nonce=jQuery("#ef_notifications_nonce").val(),jQuery(this).parents(".ef-post_following_list").find("input:checked").map(function(){t.push(jQuery(this).val())}),r.user_group_ids=t,e.ajax({type:"POST",url:ajaxurl||wpListL10n.url,data:r,success:function(e){var t=e.data.subscribers_with_no_access.includes(parseInt(jQuery(n).val(),10)),r=e.data.subscribers_with_no_email.includes(parseInt(jQuery(n).val(),10));!function(e,t){var r=t.userHasNoAccess,n=t.userHasNoEmail,s=jQuery(e).parent().closest("li").find(".ef-user-list-badges");r?a(s,o.NO_ACCESS):i(s,o.NO_ACCESS),n?a(s,o.NO_EMAIL):i(s,o.NO_EMAIL)}(jQuery(n),{userHasNoAccess:t,userHasNoEmail:r});var s="#90d296";(t||r)&&(s="#ea8484");jQuery(n.parents("label")).animate({backgroundColor:s},200).animate({backgroundColor:"transparent"},200),jQuery("#ef-post_following_box").trigger("following_list_updated")},error:function(){jQuery("#ef-post_following_users_box").prev().append(' There was an error. Please reload the page.
')}})})})}]);
+//# sourceMappingURL=notifications.build.js.map
\ No newline at end of file
diff --git a/modules/notifications/lib/notifications.css b/modules/notifications/lib/notifications.css
index db9cccff2..e1446d40b 100644
--- a/modules/notifications/lib/notifications.css
+++ b/modules/notifications/lib/notifications.css
@@ -7,13 +7,17 @@
}
.ef-post_following_list li {
+ border-bottom: 1px solid #ccc;
+}
+
+.ef-post_following_list li label {
+ min-height: 76px;
padding: 10px 5px 5px 5px;
margin: 0;
- border-bottom: 1px solid #ccc;
- min-height: 36px;
+ display: block;
}
-.ef-post_following_list li:hover {
+.ef-post_following_list li label:hover {
background: #EAF2FA;
}
@@ -35,17 +39,21 @@
font-size: 12px;
}
-.ef-post_following_list li .ef-user-subscribe-actions {
- float: right;
- margin-top: 5px;
+.ef-post_following_list li .ef-user-list-badges {
+ margin-top: 10px;
}
-.ef-post_following_list li .ef-user-subscribe-actions .post_following_list-no_email,
-.ef-post_following_list li .ef-user-subscribe-actions .post_following_list-no_access {
+.ef-post_following_list li .ef-user-badge {
margin-right: 10px;
- border: solid 2px #DC3232;
- color: #DC3232;
+ border: solid 2px #b8b8b8;
+ color: #b8b8b8;
padding: 4px;
+ display: inline-block;
+}
+
+.ef-post_following_list li .ef-user-badge-error {
+ color: #DC3232;
+ border: solid 2px #DC3232;
}
#ef-post_following_box {
@@ -107,4 +115,4 @@
#ef-usergroup-users h4 {
margin-top: 0;
-}
+}
\ No newline at end of file
diff --git a/modules/notifications/lib/notifications.js b/modules/notifications/lib/notifications.js
index 65b161915..6822c8216 100644
--- a/modules/notifications/lib/notifications.js
+++ b/modules/notifications/lib/notifications.js
@@ -1,80 +1,171 @@
-jQuery(document).ready(function($) {
- $('#ef-post_following_users_box ul').listFilterizer();
+/* global wp, jQuery, ajaxurl, ef_notifications_localization, document, wpListL10n, ef_post_author_id */
- var params = {
+const BADGES_STATUS = {
+ error: 'error',
+ warning: 'warning',
+ success: 'success',
+};
+
+const BADGES = {
+ NO_ACCESS: {
+ id: 'no_access',
+ name: ef_notifications_localization.no_access,
+ status: BADGES_STATUS.error,
+ },
+ NO_EMAIL: {
+ id: 'no_email',
+ name: ef_notifications_localization.no_email,
+ status: BADGES_STATUS.error,
+ },
+ POST_AUTHOR: {
+ id: 'post_author',
+ name: ef_notifications_localization.post_author,
+ class: 'ef-badge-neutral',
+ },
+ AUTO_SUBSCRIBE: {
+ id: 'auto_subscribed',
+ name: ef_notifications_localization.auto_subscribed,
+ class: 'ef-badge-neutral',
+ },
+};
+
+const getBadge = ( $el, badge ) => {
+ const exists = $el.find( `[data-badge-id='${ badge.id }']` );
+
+ if ( exists.length ) {
+ return jQuery( exists[ 0 ] );
+ }
+ return null;
+};
+
+const badgeTemplate = badge => {
+ let classes = 'ef-user-badge';
+
+ if ( BADGES_STATUS.error === badge.status ) {
+ classes += ' ef-user-badge-error';
+ }
+
+ return `${ badge.name }
`;
+};
+
+const addBadgeToEl = ( $el, badge ) => {
+ if ( getBadge( $el, badge ) ) {
+ return;
+ }
+
+ $el.append( badgeTemplate( badge ) );
+};
+
+const removeBadgeFromEl = ( $el, badge ) => {
+ const existingBadge = getBadge( $el, badge );
+
+ if ( ! existingBadge ) {
+ return;
+ }
+
+ existingBadge.remove();
+};
+
+jQuery( document ).ready( function( $ ) {
+ jQuery( '#ef-post_following_users_box ul' ).listFilterizer();
+
+ const params = {
action: 'save_notifications',
- post_id: $('#post_ID').val(),
+ post_id: jQuery( '#post_ID' ).val(),
};
-
- var toggle_warning_badges = function( container, response ) {
- // Remove any existing badges
- if ( $( container ).siblings( 'span' ).length ) {
- $( container ).siblings( 'span' ).remove();
- }
-
+
+ const toggleWarningBadges = function( container, { userHasNoAccess, userHasNoEmail } ) {
+ const $el = jQuery( container ).parent();
+ const $badgesContainer = $el.closest( 'li' ).find( '.ef-user-list-badges' );
+
// "No Access" If this user was flagged as not having access
- var user_has_no_access = response.data.subscribers_with_no_access.includes( parseInt( $( container ).val() ) );
- if ( user_has_no_access ) {
- var span = $( ' ' ).addClass( 'post_following_list-no_access' );
- span.text( ef_notifications_localization.no_access );
- $( container ).parent().prepend( span );
- warning_background = true;
+ if ( userHasNoAccess ) {
+ addBadgeToEl( $badgesContainer, BADGES.NO_ACCESS );
+ } else {
+ removeBadgeFromEl( $badgesContainer, BADGES.NO_ACCESS );
}
+
// "No Email" If this user was flagged as not having an email
- var user_has_no_email = response.data.subscribers_with_no_email.includes( parseInt( $( container ).val() ) );
- if ( user_has_no_email ) {
- var span = $( ' ' ).addClass( 'post_following_list-no_email' );
- span.text( ef_notifications_localization.no_email );
- $( container ).parent().prepend( span );
- warning_background = true;
+ if ( userHasNoEmail ) {
+ addBadgeToEl( $badgesContainer, BADGES.NO_EMAIL );
+ } else {
+ removeBadgeFromEl( $badgesContainer, BADGES.NO_EMAIL );
}
+ };
+
+ const show_post_author_badge = () => {
+ const $userListItemActions = jQuery( "label[for='ef-selected-users-" + ef_post_author_id + "'] .ef-user-list-badges" );
+ addBadgeToEl( $userListItemActions, BADGES.POST_AUTHOR );
+ };
+
+ /**
+ * Until assets are correctly loaded on their respective pages, `ef_post_author_id` should
+ * only have a value on a post page, so only execute `show_post_author_badge` if it has a value
+ */
+ if ( 'undefined' !== typeof ef_post_author_id ) {
+ show_post_author_badge();
}
- $(document).on('click','.ef-post_following_list li input:checkbox, .ef-following_usergroups li input:checkbox', function() {
- var user_group_ids = [];
- var parent_this = $(this);
- params.ef_notifications_name = $(this).attr('name');
- params._nonce = $("#ef_notifications_nonce").val();
-
- $(this)
- .parents('.ef-post_following_list')
- .find('input:checked')
- .map(function(){
- user_group_ids.push($(this).val());
- })
-
- params.user_group_ids = user_group_ids;
-
- $.ajax({
- type : 'POST',
- url : (ajaxurl) ? ajaxurl : wpListL10n.url,
- data : params,
-
- success : function( response ) {
- // Reset background color (set during toggle_warning_badges if there's a warning)
- warning_background = false;
-
+ const showAutosubscribedBadge = () => {
+ const $userListItemActions = jQuery( "label[for='ef-selected-users-" + ef_post_author_id + "'] .ef-user-list-badges" );
+ addBadgeToEl( $userListItemActions, BADGES.AUTO_SUBSCRIBE );
+ };
+
+ const disableAutosubscribeCheckbox = () => {
+ jQuery( '#ef-selected-users-' + ef_post_author_id ).prop( 'disabled', true );
+ };
+
+ if ( typeof ef_post_author_auto_subscribe !== 'undefined' ) {
+ showAutosubscribedBadge();
+ disableAutosubscribeCheckbox();
+ }
+
+ jQuery( document ).on( 'click', '.ef-post_following_list li input:checkbox, .ef-following_usergroups li input:checkbox', function() {
+ const userGroupIds = [];
+ const checkbox = jQuery( this );
+ params.ef_notifications_name = jQuery( this ).attr( 'name' );
+ params._nonce = jQuery( '#ef_notifications_nonce' ).val();
+
+ jQuery( this )
+ .parents( '.ef-post_following_list' )
+ .find( 'input:checked' )
+ .map( function() {
+ userGroupIds.push( jQuery( this ).val() );
+ } );
+
+ params.user_group_ids = userGroupIds;
+
+ $.ajax( {
+ type: 'POST',
+ url: ( ajaxurl ) ? ajaxurl : wpListL10n.url,
+ data: params,
+
+ success: function( response ) {
// Toggle the warning badges ("No Access" and "No Email") to signal the user won't receive notifications
- if ( undefined !== response.data ) {
- toggle_warning_badges( $( parent_this ), response );
- }
+ const userHasNoAccess = response.data.subscribers_with_no_access.includes( parseInt( jQuery( checkbox ).val(), 10 ) );
+ const userHasNoEmail = response.data.subscribers_with_no_email.includes( parseInt( jQuery( checkbox ).val(), 10 ) );
+
+ toggleWarningBadges( jQuery( checkbox ), { userHasNoAccess, userHasNoEmail } );
+
// Green 40% by default
- var backgroundHighlightColor = "#90d296";
- if ( warning_background ) {
+ let backgroundHighlightColor = '#90d296';
+
+ if ( userHasNoAccess || userHasNoEmail ) {
// Red 40% if there's a warning
- var backgroundHighlightColor = "#ea8484";
+ backgroundHighlightColor = '#ea8484';
}
- var backgroundColor = parent_this.css( 'background-color' );
- $(parent_this.parents('li'))
- .animate( { 'backgroundColor': backgroundHighlightColor }, 200 )
- .animate( { 'backgroundColor':backgroundColor }, 200 );
-
+
+ const backgroundColor = 'transparent';
+ jQuery( checkbox.parents( 'label' ) )
+ .animate( { backgroundColor: backgroundHighlightColor }, 200 )
+ .animate( { backgroundColor: backgroundColor }, 200 );
+
// This event is used to show an updated list of who will be notified of editorial comments and status updates.
- $( '#ef-post_following_box' ).trigger( 'following_list_updated' );
+ jQuery( '#ef-post_following_box' ).trigger( 'following_list_updated' );
+ },
+ error: function() {
+ jQuery( '#ef-post_following_users_box' ).prev().append( ' There was an error. Please reload the page.
' );
},
- error : function(r) {
- $('#ef-post_following_users_box').prev().append(' There was an error. Please reload the page.
');
- }
- });
- });
-});
\ No newline at end of file
+ } );
+ } );
+} );
diff --git a/modules/notifications/notifications.php b/modules/notifications/notifications.php
index 9b05baa74..f5086bf40 100644
--- a/modules/notifications/notifications.php
+++ b/modules/notifications/notifications.php
@@ -193,13 +193,15 @@ function enqueue_admin_scripts() {
if ( $this->is_whitelisted_functional_view() ) {
wp_enqueue_script( 'jquery-listfilterizer' );
wp_enqueue_script( 'jquery-quicksearch' );
- wp_enqueue_script( 'edit-flow-notifications-js', $this->module_url . 'lib/notifications.js', array( 'jquery', 'jquery-listfilterizer', 'jquery-quicksearch' ), EDIT_FLOW_VERSION, true );
+ wp_enqueue_script( 'edit-flow-notifications-js', EDIT_FLOW_URL . 'modules/notifications/dist/notifications.build.js', array( 'jquery', 'jquery-listfilterizer', 'jquery-quicksearch' ), EDIT_FLOW_VERSION, true );
wp_localize_script(
'edit-flow-notifications-js',
'ef_notifications_localization',
array(
'no_access' => esc_html__( 'No Access', 'edit-flow' ),
- 'no_email' => esc_html__( 'No Email', 'edit-flow' )
+ 'no_email' => esc_html__( 'No Email', 'edit-flow' ),
+ 'post_author' => esc_html__( 'Post Author', 'edit-flow' ),
+ 'auto_subscribed' => esc_html__( 'Auto-Subscribed', 'edit-flow' ),
)
);
}
@@ -343,6 +345,18 @@ function notifications_meta_box() {
get_following_users( $post->ID, 'id' );
+
+ $post_author_is_follower = ! empty( in_array( $post->post_author, $followers ) ) ? 'true' : 'false';
+ $post_author_auto_subscribe = apply_filters( 'ef_notification_auto_subscribe_post_author', true, 'subscription_action' ) ? 'true' : 'false';
+
+ wp_add_inline_script(
+ 'edit-flow-notifications-js',
+ 'var ef_post_author_id = ' . wp_json_encode( $post->post_author ) . '; ' .
+ 'var ef_post_author_is_follower = ' . wp_json_encode( $post_author_is_follower ) . '; ' .
+ 'var ef_post_author_auto_subscribe = ' . wp_json_encode( $post_author_auto_subscribe ) . ';',
+ 'before'
+ );
+
$select_form_args = array(
'list_class' => 'ef-post_following_list',
);
@@ -384,14 +398,14 @@ function display_subscriber_warning_badges( $user_id, $checked ) {
// Add No Access span if they won't be notified
if (! $this->user_can_be_notified( get_user_by( 'id', $user_id ), $post->ID )) {
// span.post_following_list-no_access is also added in notifications.js after AJAX that ticks/unticks a user
- echo '' . esc_html__( 'No Access', 'edit-flow' ) . ' ';
+ echo '' . esc_html__( 'No Access', 'edit-flow' ) . '
';
}
// Add No Email span if they have no email
$user_object = get_user_by( 'id', $user_id );
if ( !is_a( $user_object, 'WP_User') OR empty( $user_object->user_email ) ) {
// span.post_following_list-no_email is also added in notifications.js after AJAX that ticks/unticks a user
- echo '' . esc_html__( 'No Email', 'edit-flow' ) . ' ';
+ echo '' . esc_html__( 'No Email', 'edit-flow' ) . '
';
}
}
diff --git a/modules/user-groups/lib/user-groups.css b/modules/user-groups/lib/user-groups.css
index 23a66ab34..5878d8b74 100644
--- a/modules/user-groups/lib/user-groups.css
+++ b/modules/user-groups/lib/user-groups.css
@@ -3,13 +3,14 @@
}
.ef-post_following_list li {
- padding: 10px 5px 5px 5px;
margin: 0;
border-bottom: 1px solid #ccc;
}
- .ef-post_following_list li:hover {
- background: #EAF2FA;
- }
+
+ .ef-post_following_list li:hover {
+ background: #EAF2FA;
+ }
+
.ef-post_following_list li input {
float: right;
}
diff --git a/package-lock.json b/package-lock.json
index 73a530e3e..5918f6567 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11362,8 +11362,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -11384,14 +11383,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -11406,20 +11403,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -11536,8 +11530,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -11549,7 +11542,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -11564,7 +11556,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -11572,14 +11563,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -11598,7 +11587,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -11679,8 +11667,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -11692,7 +11679,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -11778,8 +11764,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -11815,7 +11800,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -11835,7 +11819,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -11879,14 +11862,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
diff --git a/package.json b/package.json
index a3aa7f86e..d37fa0413 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"lint": "eslint --quiet -f json blocks common modules | eslines --quiet",
"test": "echo \"Error: no test specified\" && exit 1",
"test-e2e": "wp-scripts test-e2e --config tests/e2e/jest.config.js",
+ "debug-test-e2e": "ndb wp-scripts test-e2e --config tests/e2e/jest.config.js",
"test-e2e:watch": "npm run test-e2e -- --watch",
"test-unit-php": "wp-scripts env test-php"
},
diff --git a/tests/e2e/config/setup-test-framework.js b/tests/e2e/config/setup-test-framework.js
index 9ba6e1973..c0042f12c 100644
--- a/tests/e2e/config/setup-test-framework.js
+++ b/tests/e2e/config/setup-test-framework.js
@@ -7,7 +7,6 @@ import { get } from 'lodash';
* WordPress dependencies
*/
import {
- activatePlugin,
clearLocalStorage,
enablePageDialogAccept,
isOfflineMode,
@@ -17,6 +16,9 @@ import {
visitAdminPage,
} from '@wordpress/e2e-test-utils';
+import { AUTHOR1 } from "./users";
+import { createUser } from "../util";
+
/**
* Environment variables
*/
@@ -206,6 +208,10 @@ async function runAxeTestsForBlockEditor() {
// other posts/comments/etc. aren't dirtying tests and tests don't depend on
// each other's side-effects.
beforeAll( async () => {
+ await createUser(AUTHOR1.username, AUTHOR1.email, AUTHOR1.password);
+
+ await visitAdminPage('edit.php');
+
capturePageEventsForTearDown();
enablePageDialogAccept();
observeConsoleLogging();
diff --git a/tests/e2e/config/users.js b/tests/e2e/config/users.js
new file mode 100644
index 000000000..6ff6ed616
--- /dev/null
+++ b/tests/e2e/config/users.js
@@ -0,0 +1,14 @@
+const AUTHOR1 = {
+ username: "author1",
+ email: "author1@test.com",
+ password: "author1"
+}
+
+const ADMIN = {
+ username: "admin",
+ email: "test@test.com",
+ password: "password"
+}
+
+
+export { AUTHOR1, ADMIN };
\ No newline at end of file
diff --git a/tests/e2e/specs/simple.test.js b/tests/e2e/specs/simple.test.js
index 543163dfd..8f5a88b4b 100644
--- a/tests/e2e/specs/simple.test.js
+++ b/tests/e2e/specs/simple.test.js
@@ -6,13 +6,11 @@ import { visitAdminPage, switchUserToAdmin } from "@wordpress/e2e-test-utils";
describe("Edit Flow", () => {
- beforeAll(async () => {
- await visitAdminPage("admin.php", "page=ef-settings");
- });
it("the plugin settings page loads", async () => {
+ await visitAdminPage("admin.php", "page=ef-settings");
const editFlow = await page.$(".edit-flow-admin h2");
- const html = await page.evaluate(body => body.innerHTML, editFlow);
+ const html = await editFlow.evaluate(ef => ef.innerHTML);
expect(html).toEqual("Edit Flow");
});
diff --git a/tests/e2e/specs/user-notifications-post.test.js b/tests/e2e/specs/user-notifications-post.test.js
new file mode 100644
index 000000000..157fb0c06
--- /dev/null
+++ b/tests/e2e/specs/user-notifications-post.test.js
@@ -0,0 +1,86 @@
+/**
+ * WordPress dependencies
+ */
+
+import { createNewPost } from "@wordpress/e2e-test-utils";
+import { AUTHOR1, ADMIN } from "../config/users";
+
+describe("Post User Notifications Signup", () => {
+
+ beforeAll(async () => {
+ await createNewPost();
+ });
+
+ it("loads the user list", async () => {
+ const userList = await page.$('.ef-post_following_list');
+ expect(await userList.$$eval('.ef-user_useremail', nodes => nodes.map(n => n.innerText))).toContain(AUTHOR1.email);
+ });
+
+ it("expects the user who created the post to be auto-subscribed and marked as author", async () => {
+ const userList = await page.$('.ef-post_following_list');
+
+ const users = await userList.$$eval('.ef-user-list-item', nodes => nodes.map(n => {
+ return {
+ userEmail: n.querySelector('.ef-user_useremail').innerText,
+ userBadges: [].slice.call(n.querySelectorAll('.ef-user-badge')).map(b => b.getAttribute('data-badge-id')),
+ }
+ }));
+
+ expect(users.map((u => u.userEmail))).toContain(ADMIN.email);
+ expect(users.find(u => u.userEmail === ADMIN.email).userBadges).toContain("post_author");
+ expect(users.find(u => u.userEmail === ADMIN.email).userBadges).toContain("auto_subscribed");
+ });
+
+ it("expects the user who created the post to be uncheckable", async () => {
+ const userList = await page.$('.ef-post_following_list');
+
+ const users = await userList.$$eval('.ef-user-list-item', nodes => nodes.map(n => {
+ return {
+ userEmail: n.querySelector('.ef-user_useremail').innerText,
+ userBadges: [].slice.call(n.querySelectorAll('.ef-user-badge')).map(b => b.getAttribute('data-badge-id')),
+ }
+ }));
+
+ expect(users.map((u => u.userEmail))).toContain(ADMIN.email);
+ expect(users.find(u => u.userEmail === ADMIN.email).userBadges).toContain("post_author");
+ expect(users.find(u => u.userEmail === ADMIN.email).userBadges).toContain("auto_subscribed");
+ });
+
+ it("expects the user who created the post to be uncheckable", async () => {
+ const userList = await page.$('.ef-post_following_list');
+
+ const postCreatorLabel = (await userList.$x(`//span[@class="ef-user_useremail" and contains(text(),"${ADMIN.email}")]/ancestor::label`));
+ await postCreatorLabel[0].click();
+
+ const checkbox = await postCreatorLabel[0].$('input[type="checkbox"]')
+
+ const isChecked = await (await checkbox.getProperty('checked')).jsonValue();
+
+ expect(isChecked).toBe(false);
+ });
+
+ it("expects a user who did not create the post to be checkable", async () => {
+ const userList = await page.$('.ef-post_following_list');
+
+ const notPostCreatorLabel = await userList.$x(`//span[@class="ef-user_useremail" and not(contains(text(),"test@test.com"))]/ancestor::label`);
+ await notPostCreatorLabel[0].click();
+
+ const checkbox = await notPostCreatorLabel[0].$('input[type="checkbox"]')
+
+ const isChecked = await (await checkbox.getProperty('checked')).jsonValue();
+
+ expect(isChecked).toBe(true);
+ });
+
+ it("expects a user who does not have access to the post to have a No Access badge", async () => {
+ const userList = await page.$('.ef-post_following_list');
+
+ const notPostCreatorLabel = await userList.$x(`//span[@class="ef-user_useremail" and not(contains(text(),"test@test.com"))]/ancestor::label`);
+ await notPostCreatorLabel[0].click();
+
+ const noAccessBadge = await notPostCreatorLabel[0].$('.ef-user-badge-error')
+
+ expect(noAccessBadge).not.toBe(null);
+ });
+});
+
diff --git a/tests/e2e/util/index.js b/tests/e2e/util/index.js
new file mode 100644
index 000000000..a40f2e412
--- /dev/null
+++ b/tests/e2e/util/index.js
@@ -0,0 +1,24 @@
+import { visitAdminPage, loginUser } from "@wordpress/e2e-test-utils";
+
+async function createUser(username, email, password, role = 'author') {
+ await loginUser('admin', 'password');
+
+ await visitAdminPage('user-new.php');
+
+ await page.$eval('#user_login', (el, username) => el.value = username, username);
+ await page.$eval('#email', (el, email) => el.value = email, email);
+
+ await page.click(".wp-generate-pw");
+
+ await page.$eval('#pass1', (el, password) => el.value = password, password);
+ await page.$eval('#pass2', (el, password) => el.value = password, password);
+
+ await page.$eval('.pw-checkbox', (el) => el.checked = true);
+
+ await page.select('#role', role);
+
+
+ await page.click("#createusersub");
+}
+
+export { createUser }
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index dc0d45394..b770b4aa7 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -33,42 +33,72 @@ var scssConfig = {
]
};
-module.exports = {
- context: __dirname,
- devtool: debug ? 'sourcemap' : null,
- mode: debug ? 'development' : 'production',
- // entry: './blocks/src/blocks.js',
- entry: entries,
- output: {
- path: __dirname + '/blocks/dist/',
- filename: "[name].build.js"
- },
- externals: {
- 'react': "React",
- "react-dom": "ReactDOM"
- },
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- use: [
- {
- loader: 'babel-loader'
- }
- ]
- },
- {
- test: /editor\.scss$/,
- exclude: /node_modules/,
- use: extractEditorSCSS.extract(scssConfig)
- },
- {
- test: /style\.scss$/,
- exclude: /node_modules/,
- use: extractBlockSCSS.extract(scssConfig)
- }
- ]
+
+module.exports = [
+ {
+ name: 'blocks',
+ context: __dirname,
+ devtool: debug ? 'sourcemap' : null,
+ mode: debug ? 'development' : 'production',
+ // entry: './blocks/src/blocks.js',
+ entry: entries,
+ output: {
+ path: __dirname + '/blocks/dist/',
+ filename: '[name].build.js'
+ },
+ externals: {
+ 'react': "React",
+ 'react-dom': "ReactDOM"
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: [
+ {
+ loader: 'babel-loader'
+ }
+ ]
+ },
+ {
+ test: /editor\.scss$/,
+ exclude: /node_modules/,
+ use: extractEditorSCSS.extract(scssConfig)
+ },
+ {
+ test: /style\.scss$/,
+ exclude: /node_modules/,
+ use: extractBlockSCSS.extract(scssConfig)
+ }
+ ]
+ },
+ plugins: plugins
},
- plugins: plugins
-};
\ No newline at end of file
+ {
+ name: 'notifications',
+ context: __dirname,
+ devtool: debug ? 'sourcemap' : null,
+ mode: debug ? 'development' : 'production',
+ entry: {
+ notifications: __dirname + '/modules/notifications/lib/notifications.js',
+ },
+ output: {
+ path: __dirname + '/modules/notifications/dist',
+ filename: '[name].build.js'
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: [
+ {
+ loader: 'babel-loader'
+ }
+ ]
+ }
+ ]
+ }
+ }
+];