Merge pull request #322 from KiwiTechLLC/qa

Qa
This commit is contained in:
Abu Talib
2023-09-11 13:52:52 +05:30
committed by GitHub
17 changed files with 6134 additions and 38 deletions

BIN
.coverage Normal file

Binary file not shown.

1
.gitignore vendored
View File

@ -6,7 +6,6 @@ media/
*.name *.name
*.iml *.iml
*.log *.log
*.xml
*.pyo *.pyo
.DS_Store .DS_Store
.idea .idea

View File

@ -1,5 +1,61 @@
"""Test cases file of account""" """
"""Django import""" test cases file of account
"""
# django imports
from django.test import TestCase from django.test import TestCase
from rest_framework.test import APIClient
from rest_framework import status
from django.contrib.auth.models import User
from django.urls import reverse
from rest_framework_simplejwt.tokens import RefreshToken
class UserLoginTestCase(TestCase):
"""
test cases for login
"""
def setUp(self):
"""
set up data
:return:
"""
self.client = APIClient()
self.user = User.objects.create_superuser(
username='admin@example.com',
email='admin@example.com',
password='admin@1234'
)
def test_admin_login_success(self):
"""
test admin login with valid credentials
:return:
"""
url = reverse('account:admin-login')
data = {
'email': 'admin@example.com',
'password': 'admin@1234',
}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIn('auth_token', response.data['data'])
self.assertIn('refresh_token', response.data['data'])
self.assertEqual(response.data['data']['username'], data['email'])
def test_admin_login_invalid_credentials(self):
"""
test admin login with invalid credentials
:return:
"""
url = reverse('account:admin-login')
data = {
'email': 'admin@example.com',
'password': 'admin@1235',
}
response = self.client.post(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertNotIn('auth_token', response.data)
self.assertNotIn('refresh_token', response.data)
# Add more test cases as needed
# Create your tests here.

View File

@ -103,9 +103,9 @@ ERROR_CODE = {
"2074": "You can not complete this task because you does not exist in the system", "2074": "You can not complete this task because you does not exist in the system",
# deactivate account # deactivate account
"2075": "Your account is deactivated. Please contact with admin", "2075": "Your account is deactivated. Please contact with admin",
"2076": "This junior already associate with you", "2076": "This junior already associated with you",
"2077": "You can not add guardian", "2077": "You can not add guardian",
"2078": "This junior is not associate with you", "2078": "This junior is not associated with you",
# force update # force update
"2079": "Please update your app version for enjoying uninterrupted services", "2079": "Please update your app version for enjoying uninterrupted services",
"2080": "Can not add App version", "2080": "Can not add App version",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.2 on 2023-09-08 10:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('guardian', '0021_guardian_is_deleted'),
]
operations = [
migrations.AlterField(
model_name='juniortask',
name='task_description',
field=models.CharField(blank=True, max_length=500, null=True),
),
]

View File

@ -97,7 +97,7 @@ class JuniorTask(models.Model):
"""task details""" """task details"""
task_name = models.CharField(max_length=100) task_name = models.CharField(max_length=100)
"""task description""" """task description"""
task_description = models.CharField(max_length=500) task_description = models.CharField(max_length=500, null=True, blank=True)
"""points of the task""" """points of the task"""
points = models.IntegerField(default=TASK_POINTS) points = models.IntegerField(default=TASK_POINTS)
"""last date of the task""" """last date of the task"""

View File

@ -208,14 +208,13 @@ class CreateTaskAPIView(viewsets.ModelViewSet):
junior_data = Junior.objects.filter(id__in=junior_ids, junior_data = Junior.objects.filter(id__in=junior_ids,
guardian_code__contains=[guardian.guardian_code] guardian_code__contains=[guardian.guardian_code]
).select_related('auth') ).select_related('auth')
if junior_data: if not junior_data:
return custom_error_response(ERROR_CODE['2047'], response_status=status.HTTP_400_BAD_REQUEST)
for junior in junior_data: for junior in junior_data:
index = junior.guardian_code.index(guardian.guardian_code) index = junior.guardian_code.index(guardian.guardian_code)
status_index = junior.guardian_code_status[index] status_index = junior.guardian_code_status[index]
if status_index == str(NUMBER['three']): if status_index == str(NUMBER['three']):
return custom_error_response(ERROR_CODE['2078'], response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(ERROR_CODE['2078'], response_status=status.HTTP_400_BAD_REQUEST)
else:
return custom_error_response(ERROR_CODE['2047'], response_status=status.HTTP_400_BAD_REQUEST)
# use TaskSerializer serializer # use TaskSerializer serializer
serializer = TaskSerializer(context={"guardian": guardian, "image": image_data, serializer = TaskSerializer(context={"guardian": guardian, "image": image_data,

View File

@ -6,7 +6,7 @@ from .views import (UpdateJuniorProfile, ValidateGuardianCode, JuniorListAPIView
CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode, CompleteJuniorTaskAPIView, JuniorPointsListAPIView, ValidateReferralCode,
InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView, StartArticleAPIView, InviteGuardianAPIView, StartTaskAPIView, ReAssignJuniorTaskAPIView, StartArticleAPIView,
StartAssessmentAPIView, CheckAnswerAPIView, CompleteArticleAPIView, ReadArticleCardAPIView, StartAssessmentAPIView, CheckAnswerAPIView, CompleteArticleAPIView, ReadArticleCardAPIView,
CreateArticleCardAPIView, RemoveGuardianCodeAPIView, FAQViewSet) CreateArticleCardAPIView, RemoveGuardianCodeAPIView, FAQViewSet, CheckJuniorApiViewSet)
"""Third party import""" """Third party import"""
from rest_framework import routers from rest_framework import routers
@ -29,6 +29,8 @@ router.register('create-junior-profile', UpdateJuniorProfile, basename='profile-
router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code') router.register('validate-guardian-code', ValidateGuardianCode, basename='validate-guardian-code')
# junior list API""" # junior list API"""
router.register('junior-list', JuniorListAPIView, basename='junior-list') router.register('junior-list', JuniorListAPIView, basename='junior-list')
router.register('check-junior', CheckJuniorApiViewSet, basename='check-junior')
# Add junior list API""" # Add junior list API"""
router.register('add-junior', AddJuniorAPIView, basename='add-junior') router.register('add-junior', AddJuniorAPIView, basename='add-junior')
# Invited junior list API""" # Invited junior list API"""

View File

@ -164,6 +164,29 @@ class JuniorListAPIView(viewsets.ModelViewSet):
return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST)
class CheckJuniorApiViewSet(viewsets.GenericViewSet):
"""
api to check whether given user exist or not
"""
serializer_class = None
permission_classes = [IsAuthenticated]
def get_queryset(self):
junior = Junior.objects.filter(auth__email=self.request.data.get('email')).first()
return junior
def create(self, request, *args, **kwargs):
"""
:param request:
:return:
"""
junior = self.get_queryset()
data = {
'junior_exist': True if junior else False
}
return custom_response(None, data)
class AddJuniorAPIView(viewsets.ModelViewSet): class AddJuniorAPIView(viewsets.ModelViewSet):
"""Add Junior by guardian""" """Add Junior by guardian"""
serializer_class = AddJuniorSerializer serializer_class = AddJuniorSerializer
@ -180,6 +203,16 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
"email":"abc@yopmail.com" "email":"abc@yopmail.com"
}""" }"""
try: try:
if user := User.objects.filter(username=request.data['email']).first():
data = self.associate_guardian(user)
if data == none:
return custom_error_response(ERROR_CODE['2077'], response_status=status.HTTP_400_BAD_REQUEST)
elif not data:
return custom_error_response(ERROR_CODE['2076'], response_status=status.HTTP_400_BAD_REQUEST)
elif data == "Max":
return custom_error_response(ERROR_CODE['2081'], response_status=status.HTTP_400_BAD_REQUEST)
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
info_data = {'user': request.user, 'relationship': str(request.data['relationship']), info_data = {'user': request.user, 'relationship': str(request.data['relationship']),
'email': request.data['email'], 'first_name': request.data['first_name'], 'email': request.data['email'], 'first_name': request.data['first_name'],
'last_name': request.data['last_name'], 'image':None} 'last_name': request.data['last_name'], 'image':None}
@ -193,15 +226,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet):
# upload image on ali baba # upload image on ali baba
image_url = upload_image_to_alibaba(profile_image, filename) image_url = upload_image_to_alibaba(profile_image, filename)
info_data.update({"image": image_url}) info_data.update({"image": image_url})
if user := User.objects.filter(username=request.data['email']).first():
data = self.associate_guardian(user)
if data == none:
return custom_error_response(ERROR_CODE['2077'], response_status=status.HTTP_400_BAD_REQUEST)
elif not data:
return custom_error_response(ERROR_CODE['2076'], response_status=status.HTTP_400_BAD_REQUEST)
elif data == "Max":
return custom_error_response(ERROR_CODE['2081'], response_status=status.HTTP_400_BAD_REQUEST)
return custom_response(SUCCESS_CODE['3021'], response_status=status.HTTP_200_OK)
# use AddJuniorSerializer serializer # use AddJuniorSerializer serializer
serializer = AddJuniorSerializer(data=request.data, context=info_data) serializer = AddJuniorSerializer(data=request.data, context=info_data)
if serializer.is_valid(): if serializer.is_valid():
@ -646,7 +671,7 @@ class CheckAnswerAPIView(viewsets.ModelViewSet):
submit_ans = SurveyOption.objects.filter(id=answer_id).last() submit_ans = SurveyOption.objects.filter(id=answer_id).last()
junior_article_points = JuniorArticlePoints.objects.filter(junior__auth=self.request.user, junior_article_points = JuniorArticlePoints.objects.filter(junior__auth=self.request.user,
question=queryset) question=queryset)
if submit_ans: if submit_ans.is_answer:
junior_article_points.update(submitted_answer=submit_ans, is_attempt=True, is_answer_correct=True) junior_article_points.update(submitted_answer=submit_ans, is_attempt=True, is_answer_correct=True)
JuniorPoints.objects.filter(junior__auth=self.request.user).update(total_points= JuniorPoints.objects.filter(junior__auth=self.request.user).update(total_points=
F('total_points') + queryset.points) F('total_points') + queryset.points)

View File

@ -104,7 +104,6 @@ def send_notification(notification_type, from_user_id, from_user_type, to_user_i
notification_data, push_data, from_user, to_user = get_notification_data(notification_type, from_user_id, notification_data, push_data, from_user, to_user = get_notification_data(notification_type, from_user_id,
from_user_type, to_user_id, extra_data) from_user_type, to_user_id, extra_data)
user_notification_type = UserNotification.objects.filter(user=to_user).first() user_notification_type = UserNotification.objects.filter(user=to_user).first()
notification_data.update({'badge': Notification.objects.filter(notification_to=to_user, is_read=False).count()})
Notification.objects.create(notification_type=notification_type, notification_from=from_user, Notification.objects.create(notification_type=notification_type, notification_from=from_user,
notification_to=to_user, data=notification_data) notification_to=to_user, data=notification_data)
if user_notification_type and user_notification_type.push_notification: if user_notification_type and user_notification_type.push_notification:
@ -139,13 +138,10 @@ def send_notification_multiple_user(notification_type, from_user_id, from_user_t
notification_list = [] notification_list = []
for user in to_user_list: for user in to_user_list:
notification_copy_data = notification_data.copy()
notification_copy_data.update(
{'badge': Notification.objects.filter(notification_to=user, is_read=False).count()})
notification_list.append(Notification(notification_type=notification_type, notification_list.append(Notification(notification_type=notification_type,
notification_to=user, notification_to=user,
notification_from=from_user, notification_from=from_user,
data=notification_copy_data)) data=notification_data))
Notification.objects.bulk_create(notification_list) Notification.objects.bulk_create(notification_list)
to_user_list = to_user_list.filter(user_notification__push_notification=True) to_user_list = to_user_list.filter(user_notification__push_notification=True)
send_multiple_push(to_user_list, push_data) send_multiple_push(to_user_list, push_data)

View File

@ -102,3 +102,4 @@ wcwidth==0.2.6
pandas==2.0.3 pandas==2.0.3
XlsxWriter==3.1.2 XlsxWriter==3.1.2
coverage==7.3.1

View File

@ -1,6 +0,0 @@
"""
web_admin test file
"""
from django.test import TestCase
# Create your tests here.

View File

View File

@ -0,0 +1,255 @@
"""
web_admin test article file
"""
# django imports
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase
from rest_framework.test import APIClient
from rest_framework import status
# local imports
from web_admin.models import Article, ArticleCard, ArticleSurvey, DefaultArticleCardImage
from web_admin.tests.test_set_up import ArticleTestSetUp
# user model
User = get_user_model()
class ArticleViewSetTestCase(ArticleTestSetUp):
"""
test cases for article create, update, list, retrieve, delete
"""
def setUp(self):
"""
inherit data here
:return:
"""
super(ArticleViewSetTestCase, self).setUp()
# admin user authentication
self.client.force_authenticate(user=self.admin_user)
def test_article_create_with_default_card_image(self):
"""
test article create with default card_image
:return:
"""
url = reverse('web_admin:article-list')
response = self.client.post(url, self.article_data_with_default_card_image, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Check that a new article was created
self.assertEqual(Article.objects.count(), 2)
def test_article_create_with_base64_card_image(self):
"""
test article create with base64 card image
:return:
"""
self.client.force_authenticate(user=self.admin_user)
url = reverse('web_admin:article-list')
response = self.client.post(url, self.article_data_with_base64_card_image, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Check that a new article was created
self.assertEqual(Article.objects.count(), 2)
def test_article_update(self):
"""
test article update
:return:
"""
self.client.force_authenticate(user=self.admin_user)
url = reverse('web_admin:article-detail', kwargs={'pk': self.article.id})
response = self.client.put(url, self.article_update_data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.article.refresh_from_db()
self.assertEqual(self.article.title, self.article_update_data['title'])
self.assertEqual(self.article.article_cards.count(), 1)
self.assertEqual(self.article.article_survey.count(), 5)
self.assertEqual(self.article.article_survey.first().options.count(), 3)
def test_articles_list(self):
"""
test articles list
:return:
"""
url = reverse('web_admin:article-list')
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Assuming only one article exists in the database
self.assertEqual(len(response.data['data']), 1)
def test_article_retrieve(self):
"""
test article retrieve
:return:
"""
url = reverse('web_admin:article-detail', kwargs={'pk': self.article.id})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_article_delete(self):
"""
test article delete
:return:
"""
url = reverse('web_admin:article-detail', kwargs={'pk': self.article.id})
response = self.client.delete(url)
self.article.refresh_from_db()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.article.is_deleted, True)
def test_article_create_with_invalid_data(self):
"""
test article create with invalid data
:return:
"""
url = reverse('web_admin:article-list')
# Missing article_cards
invalid_data = {
"title": "Invalid Article",
"article_survey": [{"question": "Invalid Survey Question"}]
}
response = self.client.post(url, invalid_data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_article_status_change(self):
"""
test article status change (publish/un-publish)
:return:
"""
url = reverse('web_admin:article-status-change', kwargs={'pk': self.article.id})
data = {
"is_published": False
}
response = self.client.patch(url, data, format='json')
self.article.refresh_from_db()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(self.article.is_published, False)
def test_article_card_remove(self):
"""
test article card remove
:return:
"""
url = reverse('web_admin:article-remove-card', kwargs={'pk': self.article_card.id})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(ArticleCard.objects.count(), 0)
def test_article_survey_remove(self):
"""
test article survey remove
:return:
"""
url = reverse('web_admin:article-remove-survey', kwargs={'pk': self.article_survey.id})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(ArticleSurvey.objects.count(), 0)
def test_article_card_create_with_default_card_image(self):
"""
test article card create with default card_image
:return:
"""
url = reverse('web_admin:article-test-add-card')
response = self.client.post(url, self.article_card_data_with_default_card_image, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Check that a new article card was created
self.assertEqual(ArticleCard.objects.count(), 2)
def test_article_cards_list(self):
"""
test article cards list
:return:
"""
url = reverse('web_admin:article-test-list-card')
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Assuming only one article exists in the database
self.assertEqual(len(response.data['data']), 1)
class DefaultArticleCardImagesViewSetTestCase(APITestCase):
"""
test case for default article card image
"""
def setUp(self):
"""
data setup
:return:
"""
self.client = APIClient()
self.admin_user = User.objects.create_user(username='admin@example.com', email='admin@example.com',
password='admin@1234', is_staff=True, is_superuser=True)
self.default_image = DefaultArticleCardImage.objects.create(
image_name="card1.jpg",
image_url="https://example.com/updated_card1.jpg")
def test_default_article_card_image_list(self):
"""
test default article card image list
:return:
"""
self.client.force_authenticate(user=self.admin_user)
url = reverse('web_admin:default-card-images-list')
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Assuming only one default article card image exists in the database
self.assertEqual(len(response.data['data']), 1)
class ArticleListViewSetTestCase(ArticleTestSetUp):
"""
test cases for article list for junior
"""
def setUp(self):
"""
data setup
:return:
"""
super(ArticleListViewSetTestCase, self).setUp()
self.client.force_authenticate(user=self.user)
def test_article_list(self):
"""
test article list
:return:
"""
url = reverse('web_admin:article-list-list')
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Assuming only one article exists in the database
self.assertEqual(len(response.data['data']), 1)
class ArticleCardListViewSetTestCase(ArticleTestSetUp):
"""
test cases for article card list for junior
"""
def setUp(self):
"""
data setup
:return:
"""
super(ArticleCardListViewSetTestCase, self).setUp()
self.client.force_authenticate(user=self.user)
def test_article_cards_list(self):
"""
test article cards list for junior
:return:
"""
url = reverse('web_admin:article-card-list-list')
query_params = {
'article_id': self.article.id,
}
response = self.client.get(url, query_params)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# Assuming only one article exists in the database
self.assertEqual(len(response.data['data']), 1)
# Add more test cases for edge cases, permissions, etc.

View File

@ -0,0 +1,301 @@
"""
web_admin test set up file
"""
# django imports
from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase
from rest_framework.test import APIClient
# local imports
from web_admin.models import Article, ArticleCard, ArticleSurvey, SurveyOption
# user model
User = get_user_model()
# image data in base 64 string
base64_image = ("data:image/jpeg;base64,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")
class ArticleTestSetUp(APITestCase):
"""
test cases data set up for article create, update
"""
def setUp(self):
"""
set up data for test
:return:
"""
self.client = APIClient()
self.user = User.objects.create_user(username='user@example.com', password='user@1234')
self.admin_user = User.objects.create_user(username='admin@example.com', email='admin@example.com',
password='admin@1234', is_staff=True, is_superuser=True)
self.article = Article.objects.create(title="Existing Article", description="Existing Description",
is_published=True)
self.article_card = ArticleCard.objects.create(article=self.article, title="Card 1",
description="Card 1 Description")
self.article_survey = ArticleSurvey.objects.create(article=self.article, points=5,
question="Survey Question 1")
SurveyOption.objects.create(survey=self.article_survey, option="Option 1", is_answer=True)
SurveyOption.objects.create(survey=self.article_survey, option="Option 2", is_answer=False)
# article data with default card image
self.article_data_with_default_card_image = {
"title": "Test Article",
"description": "Test Description",
"article_cards": [
{
"title": "Card 1",
"description": "Card 1 Description",
"image_name": "card1.jpg",
"image_url": "https://example.com/updated_card1.jpg"
}
],
# minimum 5 article survey needed
"article_survey": [
{
"question": "Survey Question 1",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 2",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 3",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 4",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 5",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
]
}
# article data with base64 card image
self.article_data_with_base64_card_image = {
"title": "Test Article",
"description": "Test Description",
"article_cards": [
{
"title": "Card 1",
"description": "Card 1 Description",
"image_name": "card1.jpg",
"image_url": base64_image
}
],
# minimum 5 article survey needed
"article_survey": [
{
"question": "Survey Question 1",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 2",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 3",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 4",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
{
"question": "Survey Question 5",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
}
]
}
# article update data
self.article_update_data = {
"title": "Updated Article",
"description": "Updated Description",
# updated article card
"article_cards": [
{
"id": self.article_card.id,
"title": "Updated Card 1",
"description": "Updated Card 1 Description",
"image_name": "updated_card1.jpg",
"image_url": "https://example.com/updated_card1.jpg"
}
],
# updated article survey
"article_survey": [
# updated article survey
{
"id": self.article_survey.id,
"question": "Updated Survey Question 1",
"options": [
{"id": self.article_survey.options.first().id,
"option": "Updated Option 1", "is_answer": False},
# New option
{"option": "Option 3", "is_answer": True}
]
},
# new article survey
{
"question": "Survey Question 2",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
# new article survey
{
"question": "Survey Question 3",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
# new article survey
{
"question": "Survey Question 4",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
},
# new article survey
{
"question": "Survey Question 5",
"options": [
{"option": "Option 1", "is_answer": True},
{"option": "Option 2", "is_answer": False}
]
}
]
}
# article card data with default card image
self.article_card_data_with_default_card_image = {
"title": "Card 1",
"description": "Card 1 Description",
"image_name": "card1.jpg",
"image_url": "https://example.com/card2.jpg"
}