mirror of
https://github.com/wger-project/wger.git
synced 2026-02-18 23:42:04 +01:00
Some more tweaks for the exercise submission serializer
This commit is contained in:
@@ -421,12 +421,11 @@ class ExerciseTranslationSubmissionSerializer(serializers.ModelSerializer):
|
||||
if detected_language_code != language.short_name.lower():
|
||||
raise serializers.ValidationError(
|
||||
{
|
||||
'language':
|
||||
f'The detected language of the description is "{detected_language.name.capitalize()}" '
|
||||
f'({detected_language_code}), which does not match your selected language: '
|
||||
f'"{language.full_name.capitalize()}" ({language.short_name}). If you believe '
|
||||
f'this is incorrect, try adding more content or rephrasing your text, as '
|
||||
f'language detection works better with longer or more complete sentences.'
|
||||
'language': f'The detected language of the description is "{detected_language.name.capitalize()}" '
|
||||
f'({detected_language_code}), which does not match your selected language: '
|
||||
f'"{language.full_name.capitalize()}" ({language.short_name}). If you believe '
|
||||
f'this is incorrect, try adding more content or rephrasing your text, as '
|
||||
f'language detection works better with longer or more complete sentences.'
|
||||
}
|
||||
)
|
||||
|
||||
@@ -585,7 +584,11 @@ class ExerciseSubmissionSerializer(serializers.ModelSerializer):
|
||||
muscles = serializers.PrimaryKeyRelatedField(queryset=Muscle.objects.all(), many=True)
|
||||
muscles_secondary = serializers.PrimaryKeyRelatedField(queryset=Muscle.objects.all(), many=True)
|
||||
equipment = serializers.PrimaryKeyRelatedField(queryset=Equipment.objects.all(), many=True)
|
||||
variation = serializers.PrimaryKeyRelatedField(queryset=Variation.objects.all(), required=False)
|
||||
variations = serializers.PrimaryKeyRelatedField(
|
||||
queryset=Variation.objects.all(),
|
||||
required=False,
|
||||
allow_null=True,
|
||||
)
|
||||
license = serializers.PrimaryKeyRelatedField(
|
||||
queryset=License.objects.all(),
|
||||
required=False,
|
||||
@@ -601,13 +604,29 @@ class ExerciseSubmissionSerializer(serializers.ModelSerializer):
|
||||
'muscles',
|
||||
'muscles_secondary',
|
||||
'equipment',
|
||||
'variation',
|
||||
'variations',
|
||||
'license',
|
||||
'license_author',
|
||||
'translations',
|
||||
]
|
||||
model = Exercise
|
||||
|
||||
def validate(self, data):
|
||||
# Ensure at least one translation is present
|
||||
translations = data.get('translations', [])
|
||||
if not data.get('translations', []):
|
||||
raise serializers.ValidationError(
|
||||
{'translations': 'You must provide at least one translation.'}
|
||||
)
|
||||
|
||||
# At least one translation in English
|
||||
if not any(t.get('language').short_name == 'en' for t in translations):
|
||||
raise serializers.ValidationError(
|
||||
{'translations': 'You must provide at least one translation in English.'}
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
@transaction.atomic
|
||||
def create(self, validated_data):
|
||||
# Create the Exercise object first
|
||||
@@ -615,7 +634,7 @@ class ExerciseSubmissionSerializer(serializers.ModelSerializer):
|
||||
category=validated_data.pop('category'),
|
||||
license=validated_data.pop('license'),
|
||||
license_author=validated_data.pop('license_author'),
|
||||
variations=validated_data.pop('variation', None),
|
||||
variations=validated_data.pop('variations', None),
|
||||
)
|
||||
exercise.muscles.set(validated_data.pop('muscles'))
|
||||
exercise.muscles_secondary.set(validated_data.pop('muscles_secondary'))
|
||||
|
||||
@@ -13,29 +13,36 @@
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Standard Library
|
||||
from collections import namedtuple
|
||||
|
||||
# Third Party
|
||||
from rest_framework import status
|
||||
|
||||
# wger
|
||||
from wger.core.tests.api_base_test import ApiBaseTestCase
|
||||
from wger.core.tests.base_testcase import BaseTestCase
|
||||
from wger.exercises.models import Exercise
|
||||
from wger.exercises.models import (
|
||||
Alias,
|
||||
Exercise,
|
||||
ExerciseComment,
|
||||
Translation,
|
||||
)
|
||||
|
||||
|
||||
class SearchSubmissionApiTestCase(BaseTestCase, ApiBaseTestCase):
|
||||
url = '/api/v2/exercise-submission/'
|
||||
|
||||
def test_successful_submission(self):
|
||||
self.authenticate('admin')
|
||||
|
||||
payload = {
|
||||
@staticmethod
|
||||
def get_payload():
|
||||
return {
|
||||
'category': 3,
|
||||
'license': 5,
|
||||
'muscles': [3, 4],
|
||||
'muscles_secondary': [1],
|
||||
'equipment': [3],
|
||||
'license_author': 'test man',
|
||||
'variation': 1,
|
||||
'variations': 1,
|
||||
'translations': [
|
||||
{
|
||||
'name': '1-Arm Half-Kneeling Lat Pulldown',
|
||||
@@ -44,11 +51,12 @@ class SearchSubmissionApiTestCase(BaseTestCase, ApiBaseTestCase):
|
||||
'license_author': 'tester',
|
||||
'aliases': [
|
||||
{'alias': 'This is another name'},
|
||||
{'alias': 'ashda dsads asa dssa'},
|
||||
{'alias': 'yet another name'},
|
||||
],
|
||||
'comments': [
|
||||
{'comment': 'This is a very important note'},
|
||||
{'comment': 'Do the exercise correctly'},
|
||||
{'comment': 'the third comment'},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -60,53 +68,109 @@ class SearchSubmissionApiTestCase(BaseTestCase, ApiBaseTestCase):
|
||||
],
|
||||
}
|
||||
|
||||
count_before = Exercise.objects.count()
|
||||
response = self.client.post(self.url, data=payload)
|
||||
count_after = Exercise.objects.count()
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.json().get('id'), 9)
|
||||
self.assertEqual(count_before + 1, count_after)
|
||||
@staticmethod
|
||||
def get_counts():
|
||||
Counts = namedtuple('Counts', ['exercise', 'translation', 'alias', 'comment'])
|
||||
|
||||
def test_unsuccessful_submission(self):
|
||||
return Counts(
|
||||
Exercise.objects.count(),
|
||||
Translation.objects.count(),
|
||||
Alias.objects.count(),
|
||||
ExerciseComment.objects.count(),
|
||||
)
|
||||
|
||||
def test_successful_submission_full(self):
|
||||
"""Test that all objects were correctly created."""
|
||||
|
||||
self.authenticate('admin')
|
||||
|
||||
before = self.get_counts()
|
||||
response = self.client.post(self.url, data=self.get_payload())
|
||||
after = self.get_counts()
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
exercise = Exercise.objects.get(pk=response.json().get('id'))
|
||||
|
||||
self.assertEqual(exercise.category_id, 3)
|
||||
self.assertEqual(list(exercise.muscles.values_list('id', flat=True)), [3, 4])
|
||||
self.assertEqual(list(exercise.muscles_secondary.values_list('id', flat=True)), [1])
|
||||
self.assertEqual(list(exercise.equipment.values_list('id', flat=True)), [3])
|
||||
self.assertEqual(exercise.license_author, 'test man')
|
||||
self.assertEqual(exercise.variations_id, 1)
|
||||
|
||||
self.assertEqual(before.exercise + 1, after.exercise)
|
||||
self.assertEqual(before.translation + 2, after.translation)
|
||||
self.assertEqual(before.alias + 2, after.alias)
|
||||
self.assertEqual(before.comment + 3, after.comment)
|
||||
|
||||
def test_successful_submission_not_all_fields(self):
|
||||
"""Test that all objects were correctly created even if not all fields are present."""
|
||||
|
||||
self.authenticate('admin')
|
||||
|
||||
payload = self.get_payload()
|
||||
payload['muscles_secondary'] = []
|
||||
payload['muscles'] = []
|
||||
payload['equipment'] = []
|
||||
payload['variations'] = None
|
||||
|
||||
before = self.get_counts()
|
||||
response_data = self.client.post(self.url, data=payload).json()
|
||||
after = self.get_counts()
|
||||
print(response_data)
|
||||
exercise = Exercise.objects.get(pk=response_data.get('id'))
|
||||
|
||||
self.assertEqual(exercise.category_id, 3)
|
||||
self.assertEqual(list(exercise.muscles.values_list('id', flat=True)), [])
|
||||
self.assertEqual(list(exercise.muscles_secondary.values_list('id', flat=True)), [])
|
||||
self.assertEqual(list(exercise.equipment.values_list('id', flat=True)), [])
|
||||
self.assertEqual(exercise.license_author, 'test man')
|
||||
self.assertEqual(exercise.variations_id, None)
|
||||
|
||||
self.assertEqual(before.exercise + 1, after.exercise)
|
||||
self.assertEqual(before.translation + 2, after.translation)
|
||||
self.assertEqual(before.alias + 2, after.alias)
|
||||
self.assertEqual(before.comment + 3, after.comment)
|
||||
|
||||
def test_unsuccessful_submission_no_translations(self):
|
||||
"""
|
||||
If any part of the exercise submission fails, no exercise is created.
|
||||
"""
|
||||
self.authenticate('admin')
|
||||
|
||||
payload = {
|
||||
'category': 100,
|
||||
'license': 5,
|
||||
'muscles': [3, 4],
|
||||
'muscles_secondary': [1],
|
||||
'equipment': [3],
|
||||
'license_author': 'test man',
|
||||
'variation': 1,
|
||||
'translations': [
|
||||
{
|
||||
'name': '1-Arm Half-Kneeling Lat Pulldown',
|
||||
'description': 'Attach a D-Handle to a high pully. And use your lat muscles to pull the weight single handedly.',
|
||||
'language': 2,
|
||||
'license_author': 'tester',
|
||||
'aliases': [
|
||||
{'alias': 'This is another name'},
|
||||
{'alias': 'ashda dsads asa dssa'},
|
||||
],
|
||||
'comments': [
|
||||
{'comment': 'This is a very important note'},
|
||||
{'comment': 'Do the exercise correctly'},
|
||||
],
|
||||
},
|
||||
{
|
||||
'name': '2 Handed Kettlebell Swing',
|
||||
'description': '<p>das ist die Beschreibung für die Übung</p>',
|
||||
'language': 1,
|
||||
'license_author': 'tester',
|
||||
},
|
||||
],
|
||||
}
|
||||
payload = self.get_payload()
|
||||
payload['translations'] = []
|
||||
|
||||
count_before = Exercise.objects.count()
|
||||
counts_before = self.get_counts()
|
||||
response = self.client.post(self.url, data=payload)
|
||||
count_after = Exercise.objects.count()
|
||||
response_data = response.json()
|
||||
counts_after = self.get_counts()
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(count_before, count_after)
|
||||
self.assertEqual(counts_before, counts_after)
|
||||
self.assertEqual(
|
||||
response_data.get('translations'), ['You must provide at least one translation.']
|
||||
)
|
||||
|
||||
def test_unsuccessful_submission_no_english_translations(self):
|
||||
"""
|
||||
If any part of the exercise submission fails, no exercise is created.
|
||||
|
||||
-> An exercise must have at least one English translation.
|
||||
"""
|
||||
self.authenticate('admin')
|
||||
|
||||
payload = self.get_payload()
|
||||
del payload['translations'][0]
|
||||
|
||||
counts_before = self.get_counts()
|
||||
response = self.client.post(self.url, data=payload)
|
||||
response_data = response.json()
|
||||
counts_after = self.get_counts()
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(counts_before, counts_after)
|
||||
self.assertEqual(
|
||||
response_data.get('translations'),
|
||||
['You must provide at least one translation in English.'],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user