Skip to content
Open
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
6 changes: 6 additions & 0 deletions backend/api/conferences/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from strawberry import ID
from api.cms.types import FAQ, Menu
from api.events.types import Event
from api.generic_forms.types import Form as GenericForm
from api.generic_forms.types import FormPurpose
from api.languages.types import Language
from api.pretix.query import get_conference_tickets, get_voucher
from api.pretix.types import TicketItem, Voucher
Expand Down Expand Up @@ -197,6 +199,10 @@ def is_voting_closed(self, info: Info) -> bool:
def deadline(self, info: Info, type: str) -> Deadline | None:
return self.deadlines.filter(type=type).first()

@strawberry.field
def form(self, info: Info, purpose: FormPurpose) -> GenericForm | None:
return self.forms.filter(purpose=purpose).first()

@strawberry.field
def audience_levels(self, info: Info) -> list[AudienceLevel]:
return self.audience_levels.all()
Expand Down
Empty file.
Empty file.
131 changes: 131 additions & 0 deletions backend/api/generic_forms/tests/test_form_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import pytest

from conferences.tests.factories import ConferenceFactory
from generic_forms.models import Form, FormQuestion
from generic_forms.tests.factories import FormFactory, FormQuestionFactory

pytestmark = pytest.mark.django_db


def _query_form(graphql_client, conference, purpose="GRANT"):
query = """query($code: String!, $purpose: FormPurpose!) {
conference(code: $code) {
form(purpose: $purpose) {
id
name
questions {
id
label
description
questionType
required
maxLength
options {
id
label
}
}
}
}
}"""

return graphql_client.query(
query, variables={"code": conference.code, "purpose": purpose}
)


def test_form_is_none_when_not_configured(graphql_client):
conference = ConferenceFactory()

result = _query_form(graphql_client, conference)

assert result["data"]["conference"]["form"] is None


def test_form_is_none_when_only_another_purpose_is_configured(graphql_client):
form = FormFactory(purpose=Form.Purpose.GENERIC)

result = _query_form(graphql_client, form.conference, purpose="GRANT")

assert result["data"]["conference"]["form"] is None


def test_form_belongs_to_the_requested_conference(graphql_client):
FormFactory(purpose=Form.Purpose.GRANT, name="Other conference form")
conference = ConferenceFactory()

result = _query_form(graphql_client, conference)

assert result["data"]["conference"]["form"] is None


def test_form_with_questions(graphql_client):
form = FormFactory(purpose=Form.Purpose.GRANT, name="Grant form")
question = FormQuestionFactory(
form=form,
label="Why do you want to attend?",
description="Tell us more",
question_type=FormQuestion.QuestionType.TEXTAREA,
required=True,
max_length=500,
order=0,
)

result = _query_form(graphql_client, form.conference)

data = result["data"]["conference"]["form"]
assert data["id"] == str(form.id)
assert data["name"] == "Grant form"
assert data["questions"] == [
{
"id": str(question.id),
"label": "Why do you want to attend?",
"description": "Tell us more",
"questionType": "TEXTAREA",
"required": True,
"maxLength": 500,
"options": [],
}
]


def test_select_question_options_are_exposed(graphql_client):
form = FormFactory(purpose=Form.Purpose.GRANT)
FormQuestionFactory(
form=form,
question_type=FormQuestion.QuestionType.SELECT,
options=[
{"id": "vegan", "label": "Vegan"},
{"id": "veggie", "label": "Veggie"},
],
)

result = _query_form(graphql_client, form.conference)

assert result["data"]["conference"]["form"]["questions"][0]["options"] == [
{"id": "vegan", "label": "Vegan"},
{"id": "veggie", "label": "Veggie"},
]


def test_questions_follow_the_configured_order(graphql_client):
form = FormFactory(purpose=Form.Purpose.GRANT)
second = FormQuestionFactory(form=form, order=1)
first = FormQuestionFactory(form=form, order=0)
third = FormQuestionFactory(form=form, order=2)

result = _query_form(graphql_client, form.conference)

ids = [q["id"] for q in result["data"]["conference"]["form"]["questions"]]
assert ids == [str(first.id), str(second.id), str(third.id)]


def test_inactive_questions_are_hidden(graphql_client):
form = FormFactory(purpose=Form.Purpose.GRANT)
active = FormQuestionFactory(form=form, active=True)
FormQuestionFactory(form=form, active=False)

result = _query_form(graphql_client, form.conference)

ids = [q["id"] for q in result["data"]["conference"]["form"]["questions"]]
assert ids == [str(active.id)]
43 changes: 43 additions & 0 deletions backend/api/generic_forms/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import strawberry

from api.context import Info
from generic_forms.models import Form as FormModel
from generic_forms.models import FormQuestion as FormQuestionModel

FormPurpose = strawberry.enum(FormModel.Purpose, name="FormPurpose")
FormQuestionType = strawberry.enum(
FormQuestionModel.QuestionType, name="FormQuestionType"
)


@strawberry.type
class FormQuestionOption:
id: str
label: str


@strawberry.type
class FormQuestion:
id: strawberry.ID
label: str
description: str
question_type: FormQuestionType
required: bool
max_length: int | None

@strawberry.field
def options(self, info: Info) -> list[FormQuestionOption]:
return [
FormQuestionOption(id=option["id"], label=option["label"])
for option in self.options
]


@strawberry.type
class Form:
id: strawberry.ID
name: str

@strawberry.field
def questions(self, info: Info) -> list[FormQuestion]:
return self.questions.filter(active=True)
Loading