Skip to content

Commit 182bfc4

Browse files
authored
feat: add publish status to library meilisearch index [FC-0076] (#36031)
Adds the publish status field to the libraries v2 meilisearch index in order to support filtering by component publish status: published, modified, never.
1 parent e1a8b52 commit 182bfc4

File tree

5 files changed

+42
-0
lines changed

5 files changed

+42
-0
lines changed

openedx/core/djangoapps/content/search/documents.py

+20
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ class Fields:
7777
# Structural XBlocks may use this one day to indicate how many child blocks they ocntain.
7878
num_children = "num_children"
7979

80+
# Publish status can be on of:
81+
# "published",
82+
# "modified" (for blocks that were published but have been modified since),
83+
# "never" (for never-published blocks).
84+
publish_status = "publish_status"
85+
8086
# Published data (dictionary) of this object
8187
published = "published"
8288
published_display_name = "display_name"
@@ -97,6 +103,15 @@ class DocType:
97103
collection = "collection"
98104

99105

106+
class PublishStatus:
107+
"""
108+
Values for the 'publish_status' field on each doc in the search index
109+
"""
110+
never = "never"
111+
published = "published"
112+
modified = "modified"
113+
114+
100115
def meili_id_from_opaque_key(usage_key: UsageKey) -> str:
101116
"""
102117
Meilisearch requires each document to have a primary key that's either an
@@ -380,11 +395,15 @@ def searchable_doc_for_library_block(xblock_metadata: lib_api.LibraryXBlockMetad
380395
library_name = lib_api.get_library(xblock_metadata.usage_key.context_key).title
381396
block = xblock_api.load_block(xblock_metadata.usage_key, user=None)
382397

398+
publish_status = PublishStatus.published
383399
try:
384400
block_published = xblock_api.load_block(xblock_metadata.usage_key, user=None, version=LatestVersion.PUBLISHED)
401+
if xblock_metadata.last_published and xblock_metadata.last_published < xblock_metadata.modified:
402+
publish_status = PublishStatus.modified
385403
except NotFound:
386404
# Never published
387405
block_published = None
406+
publish_status = PublishStatus.never
388407

389408
doc = searchable_doc_for_usage_key(xblock_metadata.usage_key)
390409
doc.update({
@@ -393,6 +412,7 @@ def searchable_doc_for_library_block(xblock_metadata: lib_api.LibraryXBlockMetad
393412
Fields.created: xblock_metadata.created.timestamp(),
394413
Fields.modified: xblock_metadata.modified.timestamp(),
395414
Fields.last_published: xblock_metadata.last_published.timestamp() if xblock_metadata.last_published else None,
415+
Fields.publish_status: publish_status,
396416
})
397417

398418
doc.update(_fields_from_block(block))

openedx/core/djangoapps/content/search/index_config.py

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
Fields.access_id,
2626
Fields.last_published,
2727
Fields.content + "." + Fields.problem_types,
28+
Fields.publish_status,
2829
]
2930

3031
# Mark which attributes are used for keyword search, in order of importance:

openedx/core/djangoapps/content/search/tests/test_api.py

+2
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def setUp(self):
148148
"last_published": None,
149149
"created": created_date.timestamp(),
150150
"modified": modified_date.timestamp(),
151+
"publish_status": "never",
151152
}
152153
self.doc_problem2 = {
153154
"id": "lborg1libproblemp2-b2f65e29",
@@ -164,6 +165,7 @@ def setUp(self):
164165
"last_published": None,
165166
"created": created_date.timestamp(),
166167
"modified": created_date.timestamp(),
168+
"publish_status": "never",
167169
}
168170

169171
# Create a couple of taxonomies with tags

openedx/core/djangoapps/content/search/tests/test_documents.py

+17
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ def test_html_library_block(self):
298298
"taxonomy": ["Difficulty"],
299299
"level0": ["Difficulty > Normal"],
300300
},
301+
"publish_status": "never",
301302
}
302303

303304
def test_html_published_library_block(self):
@@ -337,6 +338,7 @@ def test_html_published_library_block(self):
337338
"level0": ["Difficulty > Normal"],
338339
},
339340
'published': {'display_name': 'Text'},
341+
"publish_status": "published",
340342
}
341343

342344
# Update library block to create a draft
@@ -378,6 +380,7 @@ def test_html_published_library_block(self):
378380
"level0": ["Difficulty > Normal"],
379381
},
380382
"published": {"display_name": "Text"},
383+
"publish_status": "published",
381384
}
382385

383386
# Publish new changes
@@ -420,8 +423,22 @@ def test_html_published_library_block(self):
420423
"display_name": "Text 2",
421424
"description": "This is a Test",
422425
},
426+
"publish_status": "published",
423427
}
424428

429+
# Verify publish status is set to modified
430+
old_modified = self.library_block.modified
431+
old_published = self.library_block.last_published
432+
self.library_block.modified = datetime(2024, 4, 5, 6, 7, 8, tzinfo=timezone.utc)
433+
self.library_block.last_published = datetime(2023, 4, 5, 6, 7, 8, tzinfo=timezone.utc)
434+
doc = searchable_doc_for_library_block(self.library_block)
435+
doc.update(searchable_doc_tags(self.library_block.usage_key))
436+
doc.update(searchable_doc_collections(self.library_block.usage_key))
437+
assert doc["publish_status"] == "modified"
438+
439+
self.library_block.modified = old_modified
440+
self.library_block.last_published = old_published
441+
425442
def test_collection_with_library(self):
426443
doc = searchable_doc_for_collection(self.library.key, self.collection.key)
427444
doc.update(searchable_doc_tags_for_collection(self.library.key, self.collection.key))

openedx/core/djangoapps/content/search/tests/test_handlers.py

+2
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def test_create_delete_library_block(self, meilisearch_client):
153153
"last_published": None,
154154
"created": created_date.timestamp(),
155155
"modified": created_date.timestamp(),
156+
"publish_status": "never",
156157
}
157158

158159
meilisearch_client.return_value.index.return_value.update_documents.assert_called_with([doc_problem])
@@ -177,6 +178,7 @@ def test_create_delete_library_block(self, meilisearch_client):
177178
library_api.publish_changes(library.key)
178179
doc_problem["last_published"] = published_date.timestamp()
179180
doc_problem["published"] = {"display_name": "Blank Problem"}
181+
doc_problem["publish_status"] = "published"
180182
meilisearch_client.return_value.index.return_value.update_documents.assert_called_with([doc_problem])
181183

182184
# Delete the Library Block

0 commit comments

Comments
 (0)