forked from openedx/edx-notes-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: meilisearch backend for notes search (openedx#444)
* feat: introduce "make compile-requirement" target This is convenient to compile dependencies without upgrading them. * chore: simplify tox/make test commands This makes it possible to run the make commands directly without going through tox (though tox targets keep working, of course). * chore: more convenient unit test running Previously, it was not possible to run unit tests locally without manually creating mysql & elasticsearch containers. Here, we create a `make pytest` target that automatically starts the required containers. * chore: refactor views for better mysql/es separation Instead of checking a boolean flag in multiple different places, we use class inheritance. This makes it possible to later override the view and implement our own using a different search backend, such as Meilisearch. * feat: meilisearch backend for notes search This is a very simple and basic backend. It is based on Django signals, just like the Elasticsearch backend. But it is much simpler, in the sense that there are just two signals: one for saving documents and one for deletion. This backend is limited, in the sense that it does not support highlighting -- but that's probably not such a big deal. To start using this backend, define the following settings: ES_DISABLED = True MEILISEARCH_ENABLED = True MEILISEARCH_URL = "http://meilisearch:7700" MEILISEARCH_API_KEY = "s3cr3t" MEILISEARCH_INDEX = "tutor_student_notes"
- Loading branch information
Showing
19 changed files
with
1,167 additions
and
660 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
from unittest.mock import Mock, patch | ||
|
||
from django.test import TestCase | ||
|
||
from notesapi.v1.models import Note | ||
from notesapi.v1.views import meilisearch | ||
|
||
|
||
class MeilisearchTest(TestCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
meilisearch.connect_signals() | ||
|
||
@classmethod | ||
def tearDownClass(cls): | ||
super().tearDownClass() | ||
meilisearch.disconnect_signals() | ||
|
||
def setUp(self): | ||
self.enterContext( | ||
patch.object(meilisearch.Client, "meilisearch_client", Mock()) | ||
) | ||
self.enterContext(patch.object(meilisearch.Client, "meilisearch_index", Mock())) | ||
|
||
@property | ||
def note_dict(self): | ||
return { | ||
"user": "test_user_id", | ||
"usage_id": "i4x://org/course/html/52aa9816425a4ce98a07625b8cb70811", | ||
"course_id": "org/course/run", | ||
"text": "test note text", | ||
"quote": "test note quote", | ||
"ranges": [ | ||
{ | ||
"start": "/p[1]", | ||
"end": "/p[1]", | ||
"startOffset": 0, | ||
"endOffset": 10, | ||
} | ||
], | ||
"tags": ["apple", "pear"], | ||
} | ||
|
||
def test_save_delete_note(self): | ||
note = Note.create(self.note_dict) | ||
note.save() | ||
note_id = note.id | ||
|
||
meilisearch.Client.meilisearch_index.add_documents.assert_called_with( | ||
[ | ||
{ | ||
"id": note_id, | ||
"user_id": "test_user_id", | ||
"course_id": "org/course/run", | ||
"text": "test note text", | ||
} | ||
] | ||
) | ||
|
||
note.delete() | ||
meilisearch.Client.meilisearch_index.delete_document.assert_called_with(note_id) | ||
|
||
def test_get_queryset_no_result(self): | ||
queryset = meilisearch.AnnotationSearchView().get_queryset() | ||
assert not queryset.all() | ||
|
||
def test_get_queryset_one_match(self): | ||
note1 = Note.create(self.note_dict) | ||
note2 = Note.create(self.note_dict) | ||
note1.save() | ||
note2.save() | ||
view = meilisearch.AnnotationSearchView() | ||
view.params = { | ||
"text": "dummy text", | ||
"user": "someuser", | ||
"course_id": "course/id", | ||
"page_size": 10, | ||
"page": 2, | ||
} | ||
with patch.object( | ||
meilisearch.Client.meilisearch_index, | ||
"search", | ||
Mock(return_value={"hits": [{"id": note2.id}]}), | ||
) as mock_search: | ||
queryset = view.get_queryset() | ||
mock_search.assert_called_once_with( | ||
"dummy text", | ||
{ | ||
"offset": 10, | ||
"limit": 10, | ||
"filter": ["user_id = 'someuser'", "course_id = 'course/id'"], | ||
}, | ||
) | ||
assert [note2.id] == [note.id for note in queryset] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.