From 0518aba2a9b73f329ebbbd75d65eb6d39dc8d314 Mon Sep 17 00:00:00 2001
From: Simon Urli <simon.urli@xwiki.com>
Date: Mon, 20 Dec 2021 11:09:23 +0100
Subject: [PATCH] XWIKI-19212: recomputeAverageRating cannot recompute a like
 count to 0

  * Fix case when there's no vote
  * Ensure to cover it with test case
---
 .../ratings/internal/SolrRatingsManager.java  |  2 +-
 .../internal/SolrRatingsManagerTest.java      | 41 +++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/main/java/org/xwiki/ratings/internal/SolrRatingsManager.java b/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/main/java/org/xwiki/ratings/internal/SolrRatingsManager.java
index 446c4ad336f..e316110e001 100644
--- a/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/main/java/org/xwiki/ratings/internal/SolrRatingsManager.java
+++ b/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/main/java/org/xwiki/ratings/internal/SolrRatingsManager.java
@@ -554,7 +554,7 @@ public AverageRating recomputeAverageRating(EntityReference entityReference) thr
                 offsetIndex += BULK_OPERATIONS_BATCH_SIZE;
             } while (!ratings.isEmpty());
 
-            float newAverage = Float.valueOf(sumOfVotes) / numberOfVotes;
+            float newAverage = (numberOfVotes > 0) ? Float.valueOf(sumOfVotes) / numberOfVotes : 0;
             return this.getAverageRatingManager().resetAverageRating(entityReference, newAverage, numberOfVotes);
         } else {
             throw new RatingsException(AVERAGE_RATING_NOT_ENABLED_ERROR_MESSAGE);
diff --git a/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/test/java/org/xwiki/ratings/internal/SolrRatingsManagerTest.java b/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/test/java/org/xwiki/ratings/internal/SolrRatingsManagerTest.java
index 23669edbe6d..0b88491df0e 100644
--- a/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/test/java/org/xwiki/ratings/internal/SolrRatingsManagerTest.java
+++ b/xwiki-platform-core/xwiki-platform-ratings/xwiki-platform-ratings-api/src/test/java/org/xwiki/ratings/internal/SolrRatingsManagerTest.java
@@ -822,6 +822,47 @@ void recomputeAverageRating() throws Exception
         assertEquals(averageRating, this.manager.recomputeAverageRating(inputReference));
     }
 
+    @Test
+    void recomputeAverageRatings_noVote() throws Exception
+    {
+        when(this.configuration.isAverageStored()).thenReturn(true);
+        when(this.solr.getClient(RatingSolrCoreInitializer.DEFAULT_RATINGS_SOLR_CORE)).thenReturn(this.solrClient);
+        EntityReference inputReference = mock(EntityReference.class);
+        when(inputReference.toString()).thenReturn("document:Input.Reference");
+        String managerId = "myManager";
+
+        this.manager.setIdentifier(managerId);
+
+        String filterQuery = String.format("filter(%s:%s) AND filter(%s:%s)",
+            RatingQueryField.ENTITY_REFERENCE.getFieldName(), "document\\:Input.Reference",
+            RatingQueryField.MANAGER_ID.getFieldName(), managerId);
+
+        SolrQuery expectedQuery = new SolrQuery()
+            .addFilterQuery(filterQuery)
+            .setRows(100)
+            .setStart(0)
+            .setSort(RatingQueryField.CREATED_DATE.getFieldName(), SolrQuery.ORDER.asc);
+
+        QueryResponse response1 = mock(QueryResponse.class);
+        when(solrClient.query(any())).then(invocationOnMock -> {
+            SolrQuery givenQuery = invocationOnMock.getArgument(0);
+            QueryResponse result = null;
+            assertEquals(expectedQuery.getQuery(), givenQuery.getQuery());
+            assertArrayEquals(expectedQuery.getFilterQueries(), givenQuery.getFilterQueries());
+            assertEquals(expectedQuery.getRows(), givenQuery.getRows());
+            assertEquals(expectedQuery.getStart(), givenQuery.getStart());
+            assertEquals(expectedQuery.getSorts(), givenQuery.getSorts());
+            result = response1;
+            return result;
+        });
+        // empty response
+        when(response1.getResults()).thenReturn(new SolrDocumentList());
+
+        AverageRating averageRating = mock(AverageRating.class);
+        when(this.averageRatingManager.resetAverageRating(inputReference, 0, 0)).thenReturn(averageRating);
+        assertEquals(averageRating, this.manager.recomputeAverageRating(inputReference));
+    }
+
     @Test
     void removeRatings() throws Exception
     {
-- 
GitLab