Skip to content

Commit

Permalink
[GSoC'24] M1.2 (a): Update classroom storage model and functions (opp…
Browse files Browse the repository at this point in the history
…ia#20389)

* Update classroom storage model and backend

* create util function for creating a classroom

* fix classroom_test

* fix merge conflict

* create structure for classroom image

* Add ImageDict structure

* comment classroomPage and classroomPageFileUploadFeatures e2e test

* add e2e test

* fix test

* Create a single function for banner and thumbnail validation

* Change banner to banner_data

* fix create classroom frontend

* store image data separately

* Add test for invalid classroom id

* use image domain object instead of dict

* add test for image object

* Fix linter

* change Image to ImageData and dropped image_data

* add test for update or create classroom

* fix classroomPage test

* add function for saving a new default classroom
  • Loading branch information
AFZL210 authored Jun 11, 2024
1 parent 9cc8aab commit f7f41e5
Show file tree
Hide file tree
Showing 25 changed files with 1,002 additions and 277 deletions.
4 changes: 4 additions & 0 deletions assets/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ export default {

"ALLOWED_THUMBNAIL_BG_COLORS": {
"chapter": ["#F8BF74", "#D68F78", "#8EBBB6", "#B3D8F1"],
"classroom": ["transparent", "#C8F5CD", "#AED2E9"],
"topic": ["#C6DCDA"],
"subtopic": ["#FFFFFF"],
"story": ["#F8BF74", "#D68F78", "#8EBBB6", "#B3D8F1"]
Expand Down Expand Up @@ -6196,6 +6197,9 @@ export default {
// 'math' is the 'classroom URL fragment'.
"MAX_CHARS_IN_CLASSROOM_URL_FRAGMENT": 20,
"MAX_CHARS_IN_CLASSROOM_NAME": 39,
"MAX_CHARS_IN_CLASSROOM_TEASER_TEXT": 68,
"MAX_CHARS_IN_CLASSROOM_COURSE_DETAILS": 720,
"MAX_CHARS_IN_CLASSROOM_TOPIC_LIST_INTRO": 240,
"MAX_CHARS_IN_TOPIC_NAME": 39,
"MAX_CHARS_IN_ABBREV_TOPIC_NAME": 12,
// This represents the maximum number of characters in the URL fragment for
Expand Down
15 changes: 1 addition & 14 deletions core/controllers/access_validators_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

from core import feature_flag_list
from core import feconf
from core.domain import classroom_config_domain
from core.domain import classroom_config_services
from core.domain import learner_group_fetchers
from core.domain import learner_group_services
from core.domain import rights_manager
Expand Down Expand Up @@ -58,18 +56,7 @@ def setUp(self) -> None:
self.get_user_id_from_email(self.CURRICULUM_ADMIN_EMAIL))
self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
self.editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL)
math_classroom_dict: classroom_config_domain.ClassroomDict = {
'classroom_id': 'math_classroom_id',
'name': 'math',
'url_fragment': 'math',
'course_details': 'Course details for classroom.',
'topic_list_intro': 'Topics covered for classroom',
'topic_id_to_prerequisite_topic_ids': {}
}
math_classroom = classroom_config_domain.Classroom.from_dict(
math_classroom_dict)

classroom_config_services.create_new_classroom(math_classroom)
self.save_new_valid_classroom()

def test_validation_returns_true_if_classroom_is_available(self) -> None:
self.login(self.EDITOR_EMAIL)
Expand Down
15 changes: 1 addition & 14 deletions core/controllers/acl_decorators_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
from core.domain import blog_services
from core.domain import classifier_domain
from core.domain import classifier_services
from core.domain import classroom_config_domain
from core.domain import classroom_config_services
from core.domain import exp_domain
from core.domain import exp_services
from core.domain import feedback_services
Expand Down Expand Up @@ -979,18 +977,7 @@ def setUp(self) -> None:
self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
self.editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL)

math_classroom_dict: classroom_config_domain.ClassroomDict = {
'classroom_id': 'math_classroom_id',
'name': 'math',
'url_fragment': 'math',
'course_details': 'Course details for classroom.',
'topic_list_intro': 'Topics covered for classroom',
'topic_id_to_prerequisite_topic_ids': {}
}
math_classroom = classroom_config_domain.Classroom.from_dict(
math_classroom_dict)

classroom_config_services.create_new_classroom(math_classroom)
self.save_new_valid_classroom()

self.mock_testapp = webtest.TestApp(webapp2.WSGIApplication(
[webapp2.Route(
Expand Down
40 changes: 19 additions & 21 deletions core/controllers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1195,34 +1195,32 @@ def _generate_dummy_classroom(self) -> None:
self.user_id, question_id_15, skill_id_5, 0.5)

classroom_id_1 = classroom_config_services.get_new_classroom_id()

classroom_name_1 = 'Math'

classroom_url_fragment_1 = 'math'

topic_dependency_for_classroom_1: Dict[str, list[str]] = {
topic_id_1: [],
topic_id_2: [topic_id_1],
topic_id_3: [topic_id_1],
topic_id_4: [topic_id_2],
topic_id_5: [topic_id_2, topic_id_3]
}

classroom_dict_1: classroom_config_domain.ClassroomDict = {
'classroom_id': classroom_id_1,
'name': classroom_name_1,
'url_fragment': classroom_url_fragment_1,
'course_details': '',
'topic_list_intro': '',
'topic_id_to_prerequisite_topic_ids': (
topic_dependency_for_classroom_1)
}

classroom_1 = classroom_config_domain.Classroom.from_dict(
classroom_dict_1)

classroom_config_services.update_or_create_classroom_model(
classroom_1)
classroom_1 = classroom_config_domain.Classroom(
classroom_id=classroom_id_1,
name='math',
url_fragment='math',
course_details='Math course details',
teaser_text='Math teaser text',
topic_list_intro='Start with our first topic.',
topic_id_to_prerequisite_topic_ids=(
topic_dependency_for_classroom_1),
is_published=True,
thumbnail_data=classroom_config_domain.ImageData(
'thumbnail.svg', 'transparent', 1000
),
banner_data=classroom_config_domain.ImageData(
'banner.png', 'transparent', 1000
)
)

classroom_config_services.create_new_classroom(classroom_1)
else:
raise Exception('Cannot generate dummy classroom in production.')

Expand Down
33 changes: 6 additions & 27 deletions core/controllers/android_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from __future__ import annotations

from core.constants import constants
from core.domain import classroom_config_domain
from core.domain import classroom_config_services
from core.domain import exp_domain
from core.domain import exp_fetchers
Expand Down Expand Up @@ -350,19 +349,9 @@ def test_get_subtopic_returns_correct_json(self) -> None:
def test_get_classroom_returns_correct_json(self) -> None:
classroom_id = classroom_config_services.get_new_classroom_id()

classroom_dict: classroom_config_domain.ClassroomDict = {
'classroom_id': classroom_id,
'name': 'Math',
'url_fragment': 'math',
'course_details': '',
'topic_list_intro': '',
'topic_id_to_prerequisite_topic_ids': {}
}

classroom = classroom_config_domain.Classroom.from_dict(
classroom_dict)

classroom_config_services.update_or_create_classroom_model(classroom)
classroom = self.save_new_valid_classroom(
classroom_id=classroom_id, name='math'
)
with self.secrets_swap:
self.assertEqual(
self.get_json(
Expand All @@ -380,19 +369,9 @@ def test_get_classroom_returns_correct_json(self) -> None:
def test_get_classroom_with_version_returns_error(self) -> None:
classroom_id = classroom_config_services.get_new_classroom_id()

classroom_dict: classroom_config_domain.ClassroomDict = {
'classroom_id': classroom_id,
'name': 'Math',
'url_fragment': 'math',
'course_details': '',
'topic_list_intro': '',
'topic_id_to_prerequisite_topic_ids': {}
}

classroom = classroom_config_domain.Classroom.from_dict(
classroom_dict)

classroom_config_services.update_or_create_classroom_model(classroom)
self.save_new_valid_classroom(
classroom_id=classroom_id, name='math'
)
with self.secrets_swap:
self.assertEqual(
self.get_json(
Expand Down
60 changes: 36 additions & 24 deletions core/controllers/classroom_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@
from core.tests import test_utils


dummy_thumbnail_data = classroom_config_domain.ImageData(
'thumbnail.svg', 'transparent', 1000
)
dummy_banner_data = classroom_config_domain.ImageData(
'banner.png', 'transparent', 1000
)


class BaseClassroomControllerTests(test_utils.GenericTestBase):

def setUp(self) -> None:
Expand Down Expand Up @@ -82,23 +90,15 @@ def test_get(self) -> None:
public_topic.skill_ids_for_diagnostic_test = ['skill_id_1']
topic_services.save_new_topic(admin_id, public_topic)
topic_services.publish_topic(topic_id_2, admin_id)

math_classroom_dict: classroom_config_domain.ClassroomDict = {
'classroom_id': 'math_classroom_id',
'name': 'math',
'url_fragment': 'math',
'course_details': 'Course details for classroom.',
'topic_list_intro': 'Topics covered for classroom',
'topic_id_to_prerequisite_topic_ids': {
topic_id_1: [],
topic_id_2: [],
topic_id_3: []
}
}
math_classroom = classroom_config_domain.Classroom.from_dict(
math_classroom_dict)

classroom_config_services.create_new_classroom(math_classroom)
self.save_new_valid_classroom(
topic_id_to_prerequisite_topic_ids={
topic_id_1: [],
topic_id_2: [],
topic_id_3: []
},
course_details='Course details for classroom.',
topic_list_intro='Topics covered for classroom'
)
self.logout()

json_response = self.get_json(
Expand Down Expand Up @@ -200,16 +200,20 @@ def setUp(self) -> None:
'name': 'physics',
'url_fragment': 'physics',
'course_details': 'Curated physics foundations course.',
'teaser_text': 'Teaser test for physics classroom',
'topic_list_intro': 'Start from the basics with our first topic.',
'topic_id_to_prerequisite_topic_ids': {
'topic_id_1': ['topic_id_2', 'topic_id_3'],
'topic_id_2': [],
'topic_id_3': []
}
},
'is_published': True,
'thumbnail_data': dummy_thumbnail_data.to_dict(),
'banner_data': dummy_banner_data.to_dict()
}
self.physics_classroom = classroom_config_domain.Classroom.from_dict(
self.physics_classroom_dict)
classroom_config_services.update_or_create_classroom_model(
classroom_config_services.create_new_classroom(
self.physics_classroom)

self.math_classroom_id = (
Expand All @@ -219,16 +223,20 @@ def setUp(self) -> None:
'name': 'math',
'url_fragment': 'math',
'course_details': 'Curated math foundations course.',
'teaser_text': 'Teaser test for physics classroom',
'topic_list_intro': 'Start from the basics with our first topic.',
'topic_id_to_prerequisite_topic_ids': {
'topic_id_1': ['topic_id_2', 'topic_id_3'],
'topic_id_2': [],
'topic_id_3': []
}
},
'is_published': True,
'thumbnail_data': dummy_thumbnail_data.to_dict(),
'banner_data': dummy_banner_data.to_dict()
}
self.math_classroom = classroom_config_domain.Classroom.from_dict(
self.math_classroom_dict)
classroom_config_services.update_or_create_classroom_model(
classroom_config_services.create_new_classroom(
self.math_classroom)

def test_get_classroom_id_to_classroom_name(self) -> None:
Expand Down Expand Up @@ -378,17 +386,21 @@ def setUp(self) -> None:
'name': 'physics',
'url_fragment': 'physics',
'course_details': 'Curated physics foundations course.',
'teaser_text': 'Teaser test for physics classroom',
'topic_list_intro': 'Start from the basics with our first topic.',
'topic_id_to_prerequisite_topic_ids': {
'topic_id_1': ['topic_id_2', 'topic_id_3'],
'topic_id_2': [],
'topic_id_3': [],
'used_topic_1': []
}
},
'is_published': True,
'thumbnail_data': dummy_thumbnail_data.to_dict(),
'banner_data': dummy_banner_data.to_dict()
}
self.physics_classroom = classroom_config_domain.Classroom.from_dict(
self.physics_classroom_dict)
classroom_config_services.update_or_create_classroom_model(
classroom_config_services.create_new_classroom(
self.physics_classroom)

def test_returns_newly_added_unused_topics(self) -> None:
Expand Down Expand Up @@ -459,7 +471,7 @@ def test_returns_topic_if_unused_in_classroom(self) -> None:
self.physics_classroom.topic_id_to_prerequisite_topic_ids.pop(
self.used_topic1.id
)
classroom_config_services.update_or_create_classroom_model(
classroom_config_services.update_classroom(
self.physics_classroom)
json_response = self.get_json(feconf.UNUSED_TOPICS_HANDLER_URL)
self.assertEqual(
Expand Down
23 changes: 8 additions & 15 deletions core/controllers/contributor_dashboard_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

from core import feconf
from core.constants import constants
from core.domain import classroom_config_domain
from core.domain import classroom_config_services
from core.domain import exp_domain
from core.domain import exp_fetchers
Expand Down Expand Up @@ -116,15 +115,12 @@ def setUp(self) -> None:

# Add skill opportunity topic to a classroom.
self.classroom_id = classroom_config_services.get_new_classroom_id()
classroom = classroom_config_domain.Classroom(
self.save_new_valid_classroom(
classroom_id=self.classroom_id,
name='math',
url_fragment='math-one',
course_details='',
topic_list_intro='',
topic_id_to_prerequisite_topic_ids={self.topic_id: []}
topic_id_to_prerequisite_topic_ids={
self.topic_id: []
}
)
classroom_config_services.update_or_create_classroom_model(classroom)

self.expected_skill_opportunity_dict_0 = {
'id': self.skill_id_0,
Expand Down Expand Up @@ -284,15 +280,12 @@ def test_get_skill_opportunity_data_pagination_multiple_fetches(
topic, [skill_id_3, skill_id_4, skill_id_5])

# Add new topic to a classroom.
classroom = classroom_config_domain.Classroom(
self.save_new_valid_classroom(
classroom_id=self.classroom_id,
name='math',
url_fragment='math-one',
course_details='',
topic_list_intro='',
topic_id_to_prerequisite_topic_ids={topic_id: []}
topic_id_to_prerequisite_topic_ids={
topic_id: []
}
)
classroom_config_services.update_or_create_classroom_model(classroom)

# Opportunities with IDs skill_id_0, skill_id_1, skill_id_2 will be
# fetched first. Since skill_id_0, skill_id_1, skill_id_2 are not linked
Expand Down
Loading

0 comments on commit f7f41e5

Please sign in to comment.