Repository: oppia/oppia

Issue:
Reviewer cannot view pending translations on contributor dashboard
<!--
  - Thanks for taking the time to report a bug in the Oppia project.
  - Before filing a new issue, please do a quick search to check that it hasn't
  - already been filed on the [issue tracker](https://github.com/oppia/oppia/issues)._
  -->

**Describe the bug**
Translations do not appear to reviewers on the contributor dashboard

**To Reproduce**
Steps to reproduce the behavior:
 1. In one account, suggest a translation for some language
 2. In another account, give yourself permission to review for that language and click "Review Translations" on the contributor dashboard

**Observed behavior**
No translations are listed, and a console error appears:

```
ERROR Error: Uncaught (in promise): Error
fetchReviewableTranslationOpportunitiesAsync/</<@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3847:93654
o/</l</e.prototype.invoke@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:7175
onInvoke@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:1377:1773
o/</l</e.prototype.invoke@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:7115
o/</s</t.prototype.run@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:2271
C/<@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3179:2717
o/</l</e.prototype.invokeTask@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:7859
onInvokeTask@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:1377:1589
o/</l</e.prototype.invokeTask@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:7780
o/</s</t.prototype.runTask@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:2934
b@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:10199
o/</d</t.invokeTask@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3171:9044
p@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3202:733
h@https://www.oppiatestserver.org/build/webpack_bundles/contributor_dashboard.fec316fed89eb93899f9.bundle.js:3202:1052
```

**Expected behavior**
Translations should appear without error

**Screenshots / Videos**
![Screen Shot 2022-08-14 at 14 16 55](https://user-images.githubusercontent.com/19878639/184555276-52a6dcb3-6df6-4718-b47d-bed6d8f588dc.png)


**Desktop (please complete the following information; delete this section if the issue does not arise on desktop):**
 - OS: macOS
 - Browser: Firefox
 - Browser-version: 103.0.2


Discussion:
@sagangwee PTAL
This looks like the same issue that will be fixed in https://github.com/oppia/oppia/pull/15851.
Fixed in https://github.com/oppia/oppia/pull/15851.

Resolving patch:
diff --git a/core/domain/story_domain.py b/core/domain/story_domain.py
--- a/core/domain/story_domain.py
+++ b/core/domain/story_domain.py
@@ -664,6 +664,8 @@ def get_ordered_nodes(self) -> List[StoryNode]:
         Returns:
             list(StoryNode). The ordered list of nodes.
         """
+        if len(self.nodes) == 0:
+            return []
         # Ruling out the possibility of None for mypy type checking.
         assert self.initial_node_id is not None
         initial_index = self.get_node_index(self.initial_node_id)


Test patch:
diff --git a/core/domain/story_domain_test.py b/core/domain/story_domain_test.py
--- a/core/domain/story_domain_test.py
+++ b/core/domain/story_domain_test.py
@@ -789,7 +789,7 @@ def test_acquired_prerequisite_skill_intersection_validation(self) -> None:
             'Expected prerequisite skill ids and acquired skill ids '
             'to be mutually exclusive.')
 
-    def test_get_ordered_nodes(self) -> None:
+    def test_get_ordered_nodes_when_nodes_exist(self) -> None:
         self.story.story_contents.next_node_id = 'node_4'
         node_1: story_domain.StoryNodeDict = {
             'id': 'node_1',
@@ -853,6 +853,11 @@ def test_get_ordered_nodes(self) -> None:
         self.assertEqual(calculated_list[1].id, expected_list[1].id)
         self.assertEqual(calculated_list[2].id, expected_list[2].id)
 
+    def test_get_ordered_nodes_when_no_nodes_exist(self) -> None:
+        self.story.story_contents.nodes = []
+        calculated_list = self.story.story_contents.get_ordered_nodes()
+        self.assertEqual(calculated_list, [])
+
     def test_get_all_linked_exp_ids(self) -> None:
         self.story.story_contents.next_node_id = 'node_4'
         node_1: story_domain.StoryNodeDict = {