Repository: learningequality/kolibri

Issue:
500 error after clicking recommended content

### Observed behavior

reported by @cpauya during a bug bash:

> As Guest, I got this error when I click on the Recommended video, play it, then click on a Recommended video below it:
> 
> ![image](https://user-images.githubusercontent.com/2367265/41803533-b5e8aab8-763e-11e8-82ea-17710228ddcf.png)

### Expected behavior

no error

### User-facing consequences

broken UX

### Errors and logs
<!--
Relevant logs from:
 * the command line
 * ~/.kolibri/kolibri.log
 * the browser console

Please wrap errors in triple backticks for clean formatting like this:
```
01:10 info: something happened
01:12 error: something bad happened
```
-->

…

### Steps to reproduce

> It’s not consistent reproducing it but here’s a sample link to it http://kolibribeta.learningequality.org/learn/#/recommended/77627658998e512faf269843883ec4af

### Context

Platform: macOS 10.13.5 - Chrome version 67.0.3396.87 (Official Build) (64-bit)

0.10.0



Discussion:
Thanks for posting this @indirectlylit - was out and about yesterday.

As mentioned, it's not consistent but one way to reproduce it was:

1. Click on the `Recommended` tab as a `Guest` user at http://kolibribeta.learningequality.org/learn/#/recommended
1. Click on any of the `Featured...` sections.  E.g. `Featured in Khan Academy (English)`.
1. Then click on an item, after the page has loaded, the video should start playing.
1. Then scroll down on the `Recommended` section below the video (or scratchpad?) and click on an item.
1. When the page refreshes, the error message most likely will be shown, like the one below.  Or you can click on this URL http://kolibribeta.learningequality.org/learn/#/recommended/572fab3eccfb50d0b4cfa2f95a2c3918 

<img width="1202" alt="screenshot 2018-06-24 05 07 30" src="https://user-images.githubusercontent.com/175580/41813695-54ce21ce-776d-11e8-916d-d4f088d71073.png">
thanks for the details!
I have tried to reproduce it in my local machine, using v0.10.0-beta7.
The error does not exist (Previously I have downloaded from studio exactly the same exercises that are causing problems:
http://kolibribeta.learningequality.org/learn/#/recommended/b6dba89558b252f2bfb64f61542458e0
http://kolibribeta.learningequality.org/learn/#/recommended/572fab3eccfb50d0b4cfa2f95a2c3918
http://kolibribeta.learningequality.org/learn/#/recommended/2ff83001970f5948844f9e4af8691667
)

The error for these resources is always the same:
`Detail:Not found`
for the contentnode requests.

The error happens always in kolibribeta.learningequality.org: no matter if the user is a logged user or a guest. It seems like the resources haven't been properly imported from Studio. I think we should: remove those resources from kolibribeta and importing them again (Khan Academy (English) -> Math -> Early Math -> Counting )
However I don't have the needed credentials to do this test. @indirectlylit can you do it?

@jredrejo: @rtibbles has been working on this yesterday and he is aware of the source of the problem.

Resolving patch:
diff --git a/kolibri/content/api.py b/kolibri/content/api.py
--- a/kolibri/content/api.py
+++ b/kolibri/content/api.py
@@ -164,8 +164,9 @@ def filter_recommendations_for(self, queryset, name, value):
         """
         Recommend items that are similar to this piece of content.
         """
-        return queryset.get(pk=value).get_siblings(
-            include_self=False).order_by("lft").exclude(kind=content_kinds.TOPIC)
+        recommendations = models.ContentNode.objects.get(pk=value).get_siblings(
+            include_self=False).exclude(kind=content_kinds.TOPIC)
+        return queryset & recommendations
 
     def filter_next_steps(self, queryset, name, value):
         """
@@ -291,6 +292,7 @@ def node_only_has_coach_content(contentnode):
                 return not contentnode.get_descendants() \
                     .exclude(kind=content_kinds.TOPIC) \
                     .exclude(coach_content=True) \
+                    .exclude(available=False) \
                     .exists()
             else:
                 return contentnode.coach_content


Test patch:
diff --git a/kolibri/content/test/test_content_app.py b/kolibri/content/test/test_content_app.py
--- a/kolibri/content/test/test_content_app.py
+++ b/kolibri/content/test/test_content_app.py
@@ -351,6 +351,14 @@ def test_contentnode_recommendations(self):
         response = self.client.get(self._reverse_channel_url("contentnode-list"), data={"recommendations_for": id})
         self.assertEqual(len(response.data), 2)
 
+    def test_contentnode_recommendations_does_not_error_for_unavailable_node(self):
+        node = content.ContentNode.objects.get(title="c2c2")
+        node.available = False
+        node.save()
+        id = node.id
+        response = self.client.get(self._reverse_channel_url("contentnode-list"), data={"recommendations_for": id})
+        self.assertEqual(len(response.data), 2)
+
     def test_contentnode_allcontent(self):
         nodes = content.ContentNode.objects.exclude(kind=content_kinds.TOPIC).count()
         response = self.client.get(self._reverse_channel_url("contentnode-all-content"))