Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 70 additions & 7 deletions contentcuration/contentcuration/tests/test_exportchannel.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,14 +692,77 @@ def test_nonexistent_prerequisites(self):


class ChannelExportPublishedData(StudioTestCase):
def test_fill_published_fields(self):
def setUp(self):
super().setUpBase()

self.license1 = cc.License.objects.create(
id=100,
license_name="License 1",
license_description="Description 1",
license_url="http://example.com/license1",
)
self.license2 = cc.License.objects.create(
id=101,
license_name="License 2",
license_description="Description 2",
license_url="http://example.com/license2",
)

self.category1 = "Category 1"
self.category2 = "Category 2"

self.node1 = self.channel.main_tree.get_root()
self.node2 = self.channel.main_tree.get_children().first()
self.node3 = self.node2.get_children().first()
self.node4 = self.node3.get_next_sibling()

self.node1.license = self.license1
self.node1.categories = {self.category1: True}
self.node1.published = True
self.node1.save()

self.node2.license = self.license2
self.node2.categories = {self.category2: True}
self.node2.published = True
self.node2.save()

self.node3.license = self.license1
self.node3.categories = {self.category1: True}
self.node3.published = True
self.node3.save()

self.node4.license = None
self.node4.categories = None
self.node4.published = True
self.node4.save()

def test_fill_published_fields__version_notes(self):
version_notes = description()
channel = cc.Channel.objects.create(actor_id=self.admin_user.id)
channel.last_published
fill_published_fields(channel, version_notes)
self.assertTrue(channel.published_data)
self.assertIsNotNone(channel.published_data.get(0))
self.assertEqual(channel.published_data[0]["version_notes"], version_notes)
self.channel.last_published
fill_published_fields(self.channel, version_notes)
self.assertTrue(self.channel.published_data)
self.assertIsNotNone(self.channel.published_data.get(0))
self.assertEqual(self.channel.published_data[0]["version_notes"], version_notes)

def test_fill_published_fields__included_licenses(self):
version_notes = description()
fill_published_fields(self.channel, version_notes)

returned_license_ids = self.channel.published_data[0]["included_licenses"]
expected_license_ids = [self.license1.id, self.license2.id]

self.assertEqual(len(returned_license_ids), len(expected_license_ids))
self.assertSetEqual(set(returned_license_ids), set(expected_license_ids))

def test_fill_published_fields__included_categories(self):
version_notes = description()
fill_published_fields(self.channel, version_notes)

expected_categories = [self.category1, self.category2]
returned_categories = self.channel.published_data[0]["included_categories"]

self.assertEqual(len(returned_categories), len(expected_categories))
self.assertSetEqual(set(returned_categories), set(expected_categories))


class PublishFailCleansUpTaskObjects(StudioTestCase):
Expand Down
46 changes: 46 additions & 0 deletions contentcuration/contentcuration/tests/viewsets/test_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -940,3 +940,49 @@ def _perform_action(self, url_path, channel_id):
reverse(url_path, kwargs={"pk": channel_id}), format="json"
)
return response


class GetPublishedDataTestCase(StudioAPITestCase):
def setUp(self):
super().setUp()

self.editor_user = testdata.user(email="editor@user.com")
self.forbidden_user = testdata.user(email="forbidden@user.com")

self.channel = testdata.channel()
self.channel.editors.add(self.editor_user)

self.channel.published_data = {
"key1": "value1",
"key2": "value2",
}
self.channel.save()

def test_get_published_data__is_editor(self):
self.client.force_authenticate(user=self.editor_user)

response = self.client.get(
reverse("channel-published-data", kwargs={"pk": self.channel.id}),
format="json",
)
self.assertEqual(response.status_code, 200, response.content)
self.assertEqual(response.json(), self.channel.published_data)

def test_get_published_data__is_admin(self):
self.client.force_authenticate(user=self.admin_user)

response = self.client.get(
reverse("channel-published-data", kwargs={"pk": self.channel.id}),
format="json",
)
self.assertEqual(response.status_code, 200, response.content)
self.assertEqual(response.json(), self.channel.published_data)

def test_get_published_data__is_forbidden_user(self):
self.client.force_authenticate(user=self.forbidden_user)

response = self.client.get(
reverse("channel-published-data", kwargs={"pk": self.channel.id}),
format="json",
)
self.assertEqual(response.status_code, 404, response.content)
21 changes: 21 additions & 0 deletions contentcuration/contentcuration/utils/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,25 @@ def fill_published_fields(channel, version_notes):
if lang:
channel.included_languages.add(lang)

included_licenses = published_nodes.exclude(license=None).values_list(
"license", flat=True
)
license_list = sorted(set(included_licenses))

included_categories_dicts = published_nodes.exclude(categories=None).values_list(
"categories", flat=True
)
category_list = sorted(
set(
chain.from_iterable(
(
node_categories_dict.keys()
for node_categories_dict in included_categories_dicts
)
)
)
)

# TODO: Eventually, consolidate above operations to just use this field for storing historical data
channel.published_data.update(
{
Expand All @@ -1196,6 +1215,8 @@ def fill_published_fields(channel, version_notes):
),
"version_notes": version_notes,
"included_languages": language_list,
"included_licenses": license_list,
"included_categories": category_list,
}
}
)
Expand Down
21 changes: 21 additions & 0 deletions contentcuration/contentcuration/viewsets/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,27 @@ def get_languages_in_channel(
langs_in_content = self._get_channel_content_languages(pk, main_tree_id)
return JsonResponse({"languages": langs_in_content})

@action(
detail=True,
methods=["get"],
url_path="published_data",
url_name="published-data",
)
def get_published_data(self, request, pk=None) -> Response:
"""
Get the published data for a channel.

:param request: The request object
:param pk: The ID of the channel
:return: Response with the published data of the channel
:rtype: Response
"""
# Allow exactly users with permission to edit the channel to
# access the published data.
channel = self.get_edit_object()

return Response(channel.published_data)

def _channel_exists(self, channel_id) -> bool:
"""
Check if a channel exists.
Expand Down