* Add unapproved reviews check

* Add tests

* Add changelog

* Create a review e2e test

* Fix lint

* Rename some constants (https://github.com/woocommerce/woocommerce-admin/pull/8178)

* Renamed `countUnapprovedReviews`

* Renamed `lowStockProductsCount`

* Renamed `unreadOrdersCount`

Co-authored-by: Fernando Marichal <contacto@fernandomarichal.com>

Co-authored-by: Fernando Marichal <contacto@fernandomarichal.com>
This commit is contained in:
Fernando 2022-01-19 13:45:17 -03:00 committed by GitHub
parent ecd8c34c42
commit b74600593e
10 changed files with 94 additions and 38 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: Add
Change the reviews empty state panels logic #8147

View File

@ -34,10 +34,10 @@ export const ActivityPanel = () => {
const totalOrderCount = getAdminSetting( 'orderCount', 0 ); const totalOrderCount = getAdminSetting( 'orderCount', 0 );
const orderStatuses = getOrderStatuses( select ); const orderStatuses = getOrderStatuses( select );
const reviewsEnabled = getAdminSetting( 'reviewsEnabled', 'no' ); const reviewsEnabled = getAdminSetting( 'reviewsEnabled', 'no' );
const countUnreadOrders = getUnreadOrders( select, orderStatuses ); const unreadOrdersCount = getUnreadOrders( select, orderStatuses );
const manageStock = getAdminSetting( 'manageStock', 'no' ); const manageStock = getAdminSetting( 'manageStock', 'no' );
const countLowStockProducts = getLowStockCount( select ); const lowStockProductsCount = getLowStockCount( select );
const countUnapprovedReviews = getUnapprovedReviews( select ); const unapprovedReviewsCount = getUnapprovedReviews( select );
const publishedProductCount = getAdminSetting( const publishedProductCount = getAdminSetting(
'publishedProductCount', 'publishedProductCount',
0 0
@ -45,9 +45,9 @@ export const ActivityPanel = () => {
const taskList = select( ONBOARDING_STORE_NAME ).getTaskList( 'setup' ); const taskList = select( ONBOARDING_STORE_NAME ).getTaskList( 'setup' );
return { return {
countLowStockProducts, lowStockProductsCount,
countUnapprovedReviews, unapprovedReviewsCount,
countUnreadOrders, unreadOrdersCount,
manageStock, manageStock,
isTaskListHidden: taskList?.isHidden, isTaskListHidden: taskList?.isHidden,
publishedProductCount, publishedProductCount,

View File

@ -209,7 +209,7 @@ function renderOrders( orders ) {
); );
} }
function OrdersPanel( { countUnreadOrders, orderStatuses } ) { function OrdersPanel( { unreadOrdersCount, orderStatuses } ) {
const actionableOrdersQuery = useMemo( const actionableOrdersQuery = useMemo(
() => ( { () => ( {
page: 1, page: 1,
@ -233,7 +233,7 @@ function OrdersPanel( { countUnreadOrders, orderStatuses } ) {
ITEMS_STORE_NAME ITEMS_STORE_NAME
); );
if ( ! orderStatuses.length && countUnreadOrders === 0 ) { if ( ! orderStatuses.length && unreadOrdersCount === 0 ) {
return { isRequesting: false }; return { isRequesting: false };
} }
@ -247,7 +247,7 @@ function OrdersPanel( { countUnreadOrders, orderStatuses } ) {
if ( if (
isRequestingActionable || isRequestingActionable ||
countUnreadOrders === null || unreadOrdersCount === null ||
orderItems === null orderItems === null
) { ) {
return { return {
@ -331,7 +331,7 @@ function OrdersPanel( { countUnreadOrders, orderStatuses } ) {
OrdersPanel.propTypes = { OrdersPanel.propTypes = {
isError: PropTypes.bool, isError: PropTypes.bool,
isRequesting: PropTypes.bool, isRequesting: PropTypes.bool,
countUnreadOrders: PropTypes.number, unreadOrdersCount: PropTypes.number,
orders: PropTypes.array.isRequired, orders: PropTypes.array.isRequired,
orderStatuses: PropTypes.array, orderStatuses: PropTypes.array,
}; };

View File

@ -27,7 +27,7 @@ describe( 'OrdersPanel', () => {
isError: false, isError: false,
isRequesting: false, isRequesting: false,
} ); } );
render( <OrdersPanel orderStatuses={ [] } countUnreadOrders={ 0 } /> ); render( <OrdersPanel orderStatuses={ [] } unreadOrdersCount={ 0 } /> );
expect( expect(
screen.queryByText( 'Youve fulfilled all your orders' ) screen.queryByText( 'Youve fulfilled all your orders' )
).toBeInTheDocument(); ).toBeInTheDocument();

View File

@ -11,9 +11,9 @@ import StockPanel from './stock';
import ReviewsPanel from './reviews'; import ReviewsPanel from './reviews';
export function getAllPanels( { export function getAllPanels( {
countLowStockProducts, lowStockProductsCount,
countUnapprovedReviews, unapprovedReviewsCount,
countUnreadOrders, unreadOrdersCount,
manageStock, manageStock,
isTaskListHidden, isTaskListHidden,
orderStatuses, orderStatuses,
@ -28,13 +28,13 @@ export function getAllPanels( {
return [ return [
totalOrderCount > 0 && { totalOrderCount > 0 && {
className: 'woocommerce-homescreen-card', className: 'woocommerce-homescreen-card',
count: countUnreadOrders, count: unreadOrdersCount,
collapsible: true, collapsible: true,
id: 'orders-panel', id: 'orders-panel',
initialOpen: false, initialOpen: false,
panel: ( panel: (
<OrdersPanel <OrdersPanel
countUnreadOrders={ countUnreadOrders } unreadOrdersCount={ unreadOrdersCount }
orderStatuses={ orderStatuses } orderStatuses={ orderStatuses }
/> />
), ),
@ -44,27 +44,28 @@ export function getAllPanels( {
publishedProductCount > 0 && publishedProductCount > 0 &&
manageStock === 'yes' && { manageStock === 'yes' && {
className: 'woocommerce-homescreen-card', className: 'woocommerce-homescreen-card',
count: countLowStockProducts, count: lowStockProductsCount,
id: 'stock-panel', id: 'stock-panel',
initialOpen: false, initialOpen: false,
collapsible: countLowStockProducts !== 0, collapsible: lowStockProductsCount !== 0,
panel: ( panel: (
<StockPanel <StockPanel
countLowStockProducts={ countLowStockProducts } lowStockProductsCount={ lowStockProductsCount }
/> />
), ),
title: __( 'Stock', 'woocommerce-admin' ), title: __( 'Stock', 'woocommerce-admin' ),
}, },
publishedProductCount > 0 && publishedProductCount > 0 &&
unapprovedReviewsCount > 0 &&
reviewsEnabled === 'yes' && { reviewsEnabled === 'yes' && {
className: 'woocommerce-homescreen-card', className: 'woocommerce-homescreen-card',
id: 'reviews-panel', id: 'reviews-panel',
count: countUnapprovedReviews, count: unapprovedReviewsCount,
initialOpen: false, initialOpen: false,
collapsible: countUnapprovedReviews !== 0, collapsible: unapprovedReviewsCount !== 0,
panel: ( panel: (
<ReviewsPanel <ReviewsPanel
hasUnapprovedReviews={ countUnapprovedReviews > 0 } hasUnapprovedReviews={ unapprovedReviewsCount > 0 }
/> />
), ),
title: __( 'Reviews', 'woocommerce-admin' ), title: __( 'Reviews', 'woocommerce-admin' ),

View File

@ -81,7 +81,7 @@ export class StockPanel extends Component {
render() { render() {
const { const {
countLowStockProducts, lowStockProductsCount,
isError, isError,
isRequesting, isRequesting,
products, products,
@ -110,7 +110,7 @@ export class StockPanel extends Component {
// Show placeholders only for the first products fetch. // Show placeholders only for the first products fetch.
if ( isRequesting || ! products.length ) { if ( isRequesting || ! products.length ) {
const numPlaceholders = Math.min( 5, countLowStockProducts ?? 1 ); const numPlaceholders = Math.min( 5, lowStockProductsCount ?? 1 );
const placeholders = Array.from( const placeholders = Array.from(
new Array( numPlaceholders ) new Array( numPlaceholders )
).map( ( v, idx ) => ( ).map( ( v, idx ) => (
@ -130,7 +130,7 @@ export class StockPanel extends Component {
} }
StockPanel.propTypes = { StockPanel.propTypes = {
countLowStockProducts: PropTypes.number, lowStockProductsCount: PropTypes.number,
products: PropTypes.array.isRequired, products: PropTypes.array.isRequired,
isError: PropTypes.bool, isError: PropTypes.bool,
isRequesting: PropTypes.bool, isRequesting: PropTypes.bool,

View File

@ -14,7 +14,7 @@ describe( 'StockPanel', () => {
it( 'should the correct number of placeholders', () => { it( 'should the correct number of placeholders', () => {
const { container } = render( const { container } = render(
<StockPanel <StockPanel
countLowStockProducts={ 3 } lowStockProductsCount={ 3 }
isError={ false } isError={ false }
isRequesting={ true } isRequesting={ true }
products={ [] } products={ [] }
@ -35,7 +35,7 @@ describe( 'StockPanel', () => {
const { getByRole } = render( const { getByRole } = render(
<StockPanel <StockPanel
countLowStockProducts={ 1 } lowStockProductsCount={ 1 }
isError={ false } isError={ false }
isRequesting={ false } isRequesting={ false }
products={ [ products={ [

View File

@ -6,7 +6,7 @@ import { getAllPanels } from '../panels';
describe( 'ActivityPanel', () => { describe( 'ActivityPanel', () => {
it( 'should exclude the orders and stock panels when there are no orders', () => { it( 'should exclude the orders and stock panels when there are no orders', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
countUnreadOrders: 0, unreadOrdersCount: 0,
orderStatuses: [], orderStatuses: [],
totalOrderCount: 0, totalOrderCount: 0,
publishedProductCount: 1, publishedProductCount: 1,
@ -28,7 +28,7 @@ describe( 'ActivityPanel', () => {
it( 'should exclude the reviews and stock panels when there are no published products', () => { it( 'should exclude the reviews and stock panels when there are no published products', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
countUnreadOrders: 0, unreadOrdersCount: 0,
orderStatuses: [], orderStatuses: [],
totalOrderCount: 1, // Yes, I realize this isn't "possible". totalOrderCount: 1, // Yes, I realize this isn't "possible".
publishedProductCount: 0, publishedProductCount: 0,
@ -51,7 +51,7 @@ describe( 'ActivityPanel', () => {
it( 'should exclude any panel when the setup task list is visible', () => { it( 'should exclude any panel when the setup task list is visible', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
countUnreadOrders: 0, unreadOrdersCount: 0,
orderStatuses: [], orderStatuses: [],
totalOrderCount: 1, totalOrderCount: 1,
publishedProductCount: 0, publishedProductCount: 0,
@ -79,7 +79,7 @@ describe( 'ActivityPanel', () => {
it( 'should include the orders panel when there are orders', () => { it( 'should include the orders panel when there are orders', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
countUnreadOrders: 1, unreadOrdersCount: 1,
orderStatuses: [], orderStatuses: [],
totalOrderCount: 10, totalOrderCount: 10,
isTaskListHidden: 'yes', isTaskListHidden: 'yes',
@ -94,7 +94,7 @@ describe( 'ActivityPanel', () => {
it( 'should include the stock panel when there are orders, products, and inventory management is enabled', () => { it( 'should include the stock panel when there are orders, products, and inventory management is enabled', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
countUnreadOrders: 1, unreadOrdersCount: 1,
orderStatuses: [], orderStatuses: [],
totalOrderCount: 10, totalOrderCount: 10,
publishedProductCount: 2, publishedProductCount: 2,
@ -109,13 +109,28 @@ describe( 'ActivityPanel', () => {
); );
} ); } );
it( 'should include the reviews panel when there are products and reviews are enabled', () => { it( 'should exclude the reviews panel when there are no reviews', () => {
const panels = getAllPanels( { const panels = getAllPanels( {
publishedProductCount: 5, publishedProductCount: 5,
reviewsEnabled: 'yes', reviewsEnabled: 'yes',
isTaskListHidden: 'yes', isTaskListHidden: 'yes',
} ); } );
expect( panels ).toEqual(
expect.not.arrayContaining( [
expect.objectContaining( { id: 'reviews-panel' } ),
] )
);
} );
it( 'should include the reviews panel when they are enabled, there are products and reviews', () => {
const panels = getAllPanels( {
publishedProductCount: 5,
reviewsEnabled: 'yes',
isTaskListHidden: 'yes',
unapprovedReviewsCount: 3,
} );
expect( panels ).toEqual( expect( panels ).toEqual(
expect.arrayContaining( [ expect.arrayContaining( [
expect.objectContaining( { id: 'reviews-panel' } ), expect.objectContaining( { id: 'reviews-panel' } ),

View File

@ -11,7 +11,7 @@ import { OnboardingWizard } from '../../pages/OnboardingWizard';
import { WcHomescreen } from '../../pages/WcHomescreen'; import { WcHomescreen } from '../../pages/WcHomescreen';
import { createOrder, removeAllOrders, unhideTaskList } from '../../fixtures'; import { createOrder, removeAllOrders, unhideTaskList } from '../../fixtures';
import { OrdersActivityPanel } from '../../elements/OrdersActivityPanel'; import { OrdersActivityPanel } from '../../elements/OrdersActivityPanel';
import { waitForElementByText } from '../../utils/actions'; import { addReviewToProduct, waitForElementByText } from '../../utils/actions';
/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-var-requires */
const { afterAll, beforeAll, describe, it } = require( '@jest/globals' ); const { afterAll, beforeAll, describe, it } = require( '@jest/globals' );
@ -65,10 +65,13 @@ const testAdminHomescreenActivityPanel = () => {
} ); } );
it( 'should show Reviews panel when we have at-least one product', async () => { it( 'should show Reviews panel when we have at-least one product', async () => {
await createSimpleProduct( simpleProductName, '9.99' ); const productId = await createSimpleProduct(
await page.reload( { simpleProductName,
waitUntil: [ 'networkidle0', 'domcontentloaded' ], '9.99'
} ); );
await addReviewToProduct( productId, simpleProductName );
await homeScreen.navigate();
await homeScreen.isDisplayed();
const activityPanels = await homeScreen.getActivityPanels(); const activityPanels = await homeScreen.getActivityPanels();
expect( activityPanels ).toHaveLength( 1 ); expect( activityPanels ).toHaveLength( 1 );
expect( activityPanels ).toEqual( expect( activityPanels ).toEqual(

View File

@ -7,6 +7,7 @@ import { ElementHandle } from 'puppeteer';
* Internal dependencies * Internal dependencies
*/ */
import { NewOrder } from '../pages/NewOrder'; import { NewOrder } from '../pages/NewOrder';
import { Login } from '../pages/Login';
/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-var-requires */
const { expect } = require( '@jest/globals' ); const { expect } = require( '@jest/globals' );
@ -185,6 +186,37 @@ const deactivateAndDeleteExtension = async ( extension: string ) => {
await deleteExtension?.click(); await deleteExtension?.click();
}; };
const addReviewToProduct = async ( productId: number, productName: string ) => {
// we need a guest user
const login = new Login( page );
await login.logout();
const baseUrl = config.get( 'url' );
const productUrl = `/?p=${ productId }`;
await page.goto( baseUrl + productUrl, {
waitUntil: 'networkidle0',
timeout: 10000,
} );
await waitForElementByText( 'h1', productName );
// Reviews tab
const reviewTab = await page.$( '#tab-title-reviews' );
await reviewTab?.click();
const fiveStars = await page.$( '.star-5' );
await fiveStars?.click();
// write a comment
await page.type( '#comment', 'My comment' );
await page.type( '#author', 'John Doe' );
await page.type( '#email', 'john.doe@john.doe' );
const submit = await page.$( '#submit' );
await submit?.click();
// the comment was published
await waitForElementByText( 'p', 'My comment' );
await login.login();
};
export { export {
uiUnblocked, uiUnblocked,
verifyPublishAndTrash, verifyPublishAndTrash,
@ -196,4 +228,5 @@ export {
hasClass, hasClass,
waitForTimeout, waitForTimeout,
deactivateAndDeleteExtension, deactivateAndDeleteExtension,
addReviewToProduct,
}; };