Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add labels to User and Project metadata #4497

Merged
merged 14 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 30 additions & 18 deletions kobo/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,36 +274,48 @@
),
'USER_METADATA_FIELDS': (
json.dumps([
{'name': 'organization', 'required': False},
{'name': 'organization_website', 'required': False},
{'name': 'sector', 'required': False},
{'name': 'gender', 'required': False},
{'name': 'bio', 'required': False},
{'name': 'city', 'required': False},
{'name': 'country', 'required': False},
{'name': 'twitter', 'required': False},
{'name': 'linkedin', 'required': False},
{'name': 'instagram', 'required': False},
{'name': 'full_name', 'required': False,},
{'name': 'organization', 'required': False,},
{'name': 'organization_website', 'required': False,},
{'name': 'sector', 'required': False,},
{'name': 'gender', 'required': False,},
{'name': 'bio', 'required': False,},
{'name': 'city', 'required': False,},
{'name': 'country', 'required': False,},
{'name': 'twitter', 'required': False,},
{'name': 'linkedin', 'required': False,},
{'name': 'instagram', 'required': False,},
jnm marked this conversation as resolved.
Show resolved Hide resolved
]),
# The available fields are hard-coded in the front end
'Display (and optionally require) these metadata fields for users. '
"Possible fields are 'organization', 'organization_website', "
"Possible fields are 'full_name', 'organization', 'organization_website', "
"'sector', 'gender', 'bio', 'city', 'country', 'twitter', 'linkedin', "
"and 'instagram'",
"and 'instagram'.\n\r"
jnm marked this conversation as resolved.
Show resolved Hide resolved
"To add another language, use 'some-other-language' as an example.",
# Use custom field for schema validation
'metadata_fields_jsonschema'
),
'PROJECT_METADATA_FIELDS': (
json.dumps([
{'name': 'sector', 'required': False},
{'name': 'country', 'required': False},
# {'name': 'operational_purpose', 'required': False},
# {'name': 'collects_pii', 'required': False},
{'name': 'sector', 'required': False, 'label': {
'default': 'Sector',
jnm marked this conversation as resolved.
Show resolved Hide resolved
'some-other-language': (
'This is an example and will never display because some-other-language '
'is not a valid language code.'
),
},},
{'name': 'country', 'required': False, 'label': {'default': 'Country'},},
# {'name': 'description', 'required': False, 'label': {'default': 'Description'},},
jnm marked this conversation as resolved.
Show resolved Hide resolved
# {'name': 'operational_purpose', 'required': False, 'label':
# {'default': 'Operational Purpose'},
# },
# {'name': 'collects_pii', 'required': False, 'label': {'default': 'Collects PII'},},
]),
# The available fields are hard-coded in the front end
'Display (and optionally require) these metadata fields for projects. '
"Possible fields are 'sector', 'country', 'operational_purpose', and "
"'collects_pii'.",
"Possible fields are 'sector', 'country', 'operational_purpose', "
"'collects_pii', and 'description'\n\r"
jnm marked this conversation as resolved.
Show resolved Hide resolved
"To add another language, use 'some-other-language' as an example.",
# Use custom field for schema validation
'metadata_fields_jsonschema'
),
Expand Down
33 changes: 28 additions & 5 deletions kpi/fields/jsonschema_form_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,22 @@ class MetadataFieldsListField(JsonSchemaFormField):
Validates that the input is an array of objects with "name" and "required"
properties, e.g.
[
{"name": "important_field", "required": true},
{"name": "whatever_field", "required": false},
{
"name": "important_field",
"required": true,
"label": {
"default": "Important Field",
"fr": "Champ important"
}
},
{
"name": "whatever_field",
"required": false,
"label": {
"default": "Whatever Field",
"fr": "Champ whatever"
}
},
]
"""
Expand All @@ -66,11 +80,20 @@ def __init__(self, *args, **kwargs):
'uniqueItems': True,
'items': {
'type': 'object',
'required': ['name', 'required'],
'required': ['name', 'required',],
'additionalProperties': False,
'properties': {
'name': {'type': 'string'},
'required': {'type': 'boolean'},
'name': {'type': 'string',},
'required': {'type': 'boolean',},
'label': {
'type': 'object',
'uniqueItems': True,
'properties': {
'default': {'type': 'string',},
},
'required': ['default',],
'additionalProperties': True,
jnm marked this conversation as resolved.
Show resolved Hide resolved
}
},
},
}
Expand Down
18 changes: 18 additions & 0 deletions kpi/tests/api/test_api_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,24 @@ def test_template_context_processor(self):
result = template.render(context)
self.assertEqual(result, constance.config.TERMS_OF_SERVICE_URL)

def test_metadata_label_with_default_language(self):
"""
Test that the label field of the user and project metadata contains a default value
"""
def check_metadata_for_label(metadata):
for item in metadata:
if 'label' in item.keys():
assert 'default' in item['label'].keys()

self.client.logout()
response = self.client.get(self.url, format='json')
assert response.status_code == status.HTTP_200_OK
user_metadata = response.data['user_metadata_fields']
project_metadata = response.data['project_metadata_fields']
check_metadata_for_label(user_metadata)
check_metadata_for_label(project_metadata)
jnm marked this conversation as resolved.
Show resolved Hide resolved


@override_config(MFA_ENABLED=True)
def test_mfa_value_globally_enabled(self):
self.client.login(username='someuser', password='someuser')
Expand Down