Skip to content

Commit

Permalink
Adds Sync API tests for CaptionFile ViewSet
Browse files Browse the repository at this point in the history
  • Loading branch information
akash5100 committed Jun 27, 2023
1 parent d0aaf90 commit 8612976
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 64 deletions.
106 changes: 106 additions & 0 deletions contentcuration/contentcuration/constants/transcription_languages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# This file contains a list of transcription languages.
# The list is in the format of (language code, language name).
# For example, the first element in the list is ('en', 'english').


CAPTIONS_LANGUAGES = [
("en", "english"),
("zh", "chinese"),
("de", "german"),
("es", "spanish"),
("ru", "russian"),
("ko", "korean"),
("fr", "french"),
("ja", "japanese"),
("pt", "portuguese"),
("tr", "turkish"),
("pl", "polish"),
("ca", "catalan"),
("nl", "dutch"),
("ar", "arabic"),
("sv", "swedish"),
("it", "italian"),
("id", "indonesian"),
("hi", "hindi"),
("fi", "finnish"),
("vi", "vietnamese"),
("he", "hebrew"),
("uk", "ukrainian"),
("el", "greek"),
("ms", "malay"),
("cs", "czech"),
("ro", "romanian"),
("da", "danish"),
("hu", "hungarian"),
("ta", "tamil"),
("no", "norwegian"),
("th", "thai"),
("ur", "urdu"),
("hr", "croatian"),
("bg", "bulgarian"),
("lt", "lithuanian"),
("la", "latin"),
("mi", "maori"),
("ml", "malayalam"),
("cy", "welsh"),
("sk", "slovak"),
("te", "telugu"),
("fa", "persian"),
("lv", "latvian"),
("bn", "bengali"),
("sr", "serbian"),
("az", "azerbaijani"),
("sl", "slovenian"),
("kn", "kannada"),
("et", "estonian"),
("mk", "macedonian"),
("br", "breton"),
("eu", "basque"),
("is", "icelandic"),
("hy", "armenian"),
("ne", "nepali"),
("mn", "mongolian"),
("bs", "bosnian"),
("kk", "kazakh"),
("sq", "albanian"),
("sw", "swahili"),
("gl", "galician"),
("mr", "marathi"),
("pa", "punjabi"),
("si", "sinhala"),
("km", "khmer"),
("sn", "shona"),
("yo", "yoruba"),
("so", "somali"),
("af", "afrikaans"),
("oc", "occitan"),
("ka", "georgian"),
("be", "belarusian"),
("tg", "tajik"),
("sd", "sindhi"),
("gu", "gujarati"),
("am", "amharic"),
("yi", "yiddish"),
("lo", "lao"),
("uz", "uzbek"),
("fo", "faroese"),
("ht", "haitian creole"),
("ps", "pashto"),
("tk", "turkmen"),
("nn", "nynorsk"),
("mt", "maltese"),
("sa", "sanskrit"),
("lb", "luxembourgish"),
("my", "myanmar"),
("bo", "tibetan"),
("tl", "tagalog"),
("mg", "malagasy"),
("as", "assamese"),
("tt", "tatar"),
("haw", "hawaiian"),
("ln", "lingala"),
("ha", "hausa"),
("ba", "bashkir"),
("jw", "javanese"),
("su", "sundanese"),
]
23 changes: 0 additions & 23 deletions contentcuration/contentcuration/migrations/0143_caption.py

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 3.2.14 on 2023-06-26 17:33

import contentcuration.models
from django.db import migrations, models
import django.db.models.deletion
import uuid


class Migration(migrations.Migration):

dependencies = [
('contentcuration', '0142_add_task_signature'),
]

operations = [
migrations.CreateModel(
name='CaptionFile',
fields=[
('id', contentcuration.models.UUIDField(default=uuid.uuid4, max_length=32, primary_key=True, serialize=False)),
('file_id', contentcuration.models.UUIDField(default=uuid.uuid4, max_length=32)),
('language', models.CharField(choices=[('en', 'english'), ('zh', 'chinese'), ('de', 'german'), ('es', 'spanish'), ('ru', 'russian'), ('ko', 'korean'), ('fr', 'french'), ('ja', 'japanese'), ('pt', 'portuguese'), ('tr', 'turkish'), ('pl', 'polish'), ('ca', 'catalan'), ('nl', 'dutch'), ('ar', 'arabic'), ('sv', 'swedish'), ('it', 'italian'), ('id', 'indonesian'), ('hi', 'hindi'), ('fi', 'finnish'), ('vi', 'vietnamese'), ('he', 'hebrew'), ('uk', 'ukrainian'), ('el', 'greek'), ('ms', 'malay'), ('cs', 'czech'), ('ro', 'romanian'), ('da', 'danish'), ('hu', 'hungarian'), ('ta', 'tamil'), ('no', 'norwegian'), ('th', 'thai'), ('ur', 'urdu'), ('hr', 'croatian'), ('bg', 'bulgarian'), ('lt', 'lithuanian'), ('la', 'latin'), ('mi', 'maori'), ('ml', 'malayalam'), ('cy', 'welsh'), ('sk', 'slovak'), ('te', 'telugu'), ('fa', 'persian'), ('lv', 'latvian'), ('bn', 'bengali'), ('sr', 'serbian'), ('az', 'azerbaijani'), ('sl', 'slovenian'), ('kn', 'kannada'), ('et', 'estonian'), ('mk', 'macedonian'), ('br', 'breton'), ('eu', 'basque'), ('is', 'icelandic'), ('hy', 'armenian'), ('ne', 'nepali'), ('mn', 'mongolian'), ('bs', 'bosnian'), ('kk', 'kazakh'), ('sq', 'albanian'), ('sw', 'swahili'), ('gl', 'galician'), ('mr', 'marathi'), ('pa', 'punjabi'), ('si', 'sinhala'), ('km', 'khmer'), ('sn', 'shona'), ('yo', 'yoruba'), ('so', 'somali'), ('af', 'afrikaans'), ('oc', 'occitan'), ('ka', 'georgian'), ('be', 'belarusian'), ('tg', 'tajik'), ('sd', 'sindhi'), ('gu', 'gujarati'), ('am', 'amharic'), ('yi', 'yiddish'), ('lo', 'lao'), ('uz', 'uzbek'), ('fo', 'faroese'), ('ht', 'haitian creole'), ('ps', 'pashto'), ('tk', 'turkmen'), ('nn', 'nynorsk'), ('mt', 'maltese'), ('sa', 'sanskrit'), ('lb', 'luxembourgish'), ('my', 'myanmar'), ('bo', 'tibetan'), ('tl', 'tagalog'), ('mg', 'malagasy'), ('as', 'assamese'), ('tt', 'tatar'), ('haw', 'hawaiian'), ('ln', 'lingala'), ('ha', 'hausa'), ('ba', 'bashkir'), ('jw', 'javanese'), ('su', 'sundanese')], max_length=3)),
],
options={
'unique_together': {('file_id', 'language')},
},
),
migrations.CreateModel(
name='CaptionCue',
fields=[
('id', contentcuration.models.UUIDField(default=uuid.uuid4, max_length=32, primary_key=True, serialize=False)),
('text', models.TextField()),
('starttime', models.FloatField()),
('endtime', models.FloatField()),
('caption_file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='caption_cue', to='contentcuration.captionfile')),
],
),
]
41 changes: 35 additions & 6 deletions contentcuration/contentcuration/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import logging
import os
from typing import Any
import urllib.parse
import uuid
from datetime import datetime
Expand Down Expand Up @@ -68,6 +69,7 @@
from contentcuration.constants import channel_history
from contentcuration.constants import completion_criteria
from contentcuration.constants import user_history
from contentcuration.constants.transcription_languages import CAPTIONS_LANGUAGES
from contentcuration.constants.contentnode import kind_activity_map
from contentcuration.db.models.expressions import Array
from contentcuration.db.models.functions import ArrayRemove
Expand Down Expand Up @@ -2057,15 +2059,42 @@ def __str__(self):
return self.ietf_name()


class Caption(models.Model):
class CaptionFile(models.Model):
"""
Model to store captions and support intermediary changes
Represents a caption file record.
- file_id: The identifier of related file in Google Cloud Storage.
- language: The language of the caption file.
"""
id = UUIDField(primary_key=True, default=uuid.uuid4)
file_id = UUIDField(default=uuid.uuid4, max_length=36)
language = models.CharField(choices=CAPTIONS_LANGUAGES, max_length=3)

class Meta:
unique_together = ['file_id', 'language']

def __str__(self):
return "{file_id} -> {language}".format(file_id=self.file_id, language=self.language)


class CaptionCue(models.Model):
"""
Represents a caption cue in a VTT file.
- text: The caption text.
- starttime: The start time of the cue in seconds.
- endtime: The end time of the cue in seconds.
- caption_file (Foreign Key): The related caption file.
"""
id = UUIDField(primary_key=True, default=uuid.uuid4)
caption = models.JSONField()
language = models.CharField(max_length=10)
# file_id = models.CharField(unique=True, max_length=32)

text = models.TextField(null=False)
starttime = models.FloatField(null=False)
endtime = models.FloatField(null=False)
caption_file = models.ForeignKey(CaptionFile, related_name="caption_cue", on_delete=models.CASCADE)

def __str__(self):
return "text: {text}, start_time: {starttime}, end_time: {endtime}".format(text=self.text, starttime=self.starttime, endtime=self.endtime)


ASSESSMENT_ID_INDEX_NAME = "assessment_id_idx"

Expand Down
147 changes: 147 additions & 0 deletions contentcuration/contentcuration/tests/viewsets/test_caption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
from __future__ import absolute_import

import uuid

from django.urls import reverse

from contentcuration.models import CaptionCue, CaptionFile
from contentcuration.tests.base import StudioAPITestCase
from contentcuration.tests import testdata
from contentcuration.tests.viewsets.base import SyncTestMixin
from contentcuration.tests.viewsets.base import generate_create_event
from contentcuration.tests.viewsets.base import generate_update_event
from contentcuration.tests.viewsets.base import generate_delete_event
from contentcuration.viewsets.sync.constants import CAPTION_FILE

# class CRUDTestCase(StudioAPITestCase):

class SyncTestCase(SyncTestMixin, StudioAPITestCase):

@property
def caption_file_metadata(self):
return {
"file_id": uuid.uuid4().hex,
"language": "en",
}

@property
def same_file_different_language_metadata(self):
id = uuid.uuid4().hex
return [
{
"file_id": id,
"language": "en",
},
{
"file_id": id,
"language": "ru",
}
]

@property
def caption_file_db_metadata(self):
return {
"file_id": uuid.uuid4().hex,
"language": "en",
}


def setUp(self):
super(SyncTestCase, self).setUp()
self.channel = testdata.channel()
self.user = testdata.user()
self.channel.editors.add(self.user)


def test_create_caption(self):
self.client.force_authenticate(user=self.user)
caption_file = self.caption_file_metadata

response = self.sync_changes(
[
generate_create_event(
uuid.uuid4().hex,
CAPTION_FILE,
caption_file,
channel_id=self.channel.id,
)
],
)
self.assertEqual(response.status_code, 200, response.content)

try:
caption_file_db = CaptionFile.objects.get(
file_id=caption_file["file_id"],
language=caption_file["language"],
)
except CaptionFile.DoesNotExist:
self.fail("caption file was not created")

# Check the values of the object in the PostgreSQL
self.assertEqual(caption_file_db.file_id, caption_file["file_id"])
self.assertEqual(caption_file_db.language, caption_file["language"])

def test_delete_caption_file(self):
self.client.force_authenticate(user=self.user)
caption_file = self.caption_file_metadata
pk = uuid.uuid4().hex
response = self.sync_changes(
[
generate_create_event(
pk,
CAPTION_FILE,
caption_file,
channel_id=self.channel.id
)
]
)
self.assertEqual(response.status_code, 200, response.content)

# Delete the caption file
response = self.sync_changes(
[
generate_delete_event(
pk,
CAPTION_FILE,
channel_id=self.channel.id
)
]
)

self.assertEqual(response.status_code, 200, response.content)

with self.assertRaises(CaptionFile.DoesNotExist):
caption_file_db = CaptionFile.objects.get(
file_id=caption_file['file_id'],
language=caption_file['language']
)


def test_delete_file_with_same_file_id_different_language(self):
self.client.force_authenticate(user=self.user)
obj = self.same_file_different_language_metadata

caption_file_1 = CaptionFile.objects.create(
**obj[0]
)
caption_file_2 = CaptionFile.objects.create(
**obj[1]
)

response = self.sync_changes(
[
generate_delete_event(
caption_file_2.pk,
CAPTION_FILE,
channel_id=self.channel.id,
)
]
)

self.assertEqual(response.status_code, 200, response.content)

with self.assertRaises(CaptionFile.DoesNotExist):
caption_file_db = CaptionFile.objects.get(
file_id=caption_file_2.file_id,
language=caption_file_2.language
)
Loading

0 comments on commit 8612976

Please sign in to comment.