Skip to content

Commit

Permalink
Merge pull request #8546 from Johnetordoff/jobs-and-schools-v2
Browse files Browse the repository at this point in the history
[PLAT-926] Add employment and institution information to user serializer
  • Loading branch information
sloria authored Jul 31, 2018
2 parents 4dafd7b + 633aa46 commit 92c8afb
Show file tree
Hide file tree
Showing 7 changed files with 405 additions and 7 deletions.
Empty file added api/users/schemas/__init__.py
Empty file.
62 changes: 62 additions & 0 deletions api/users/schemas/education-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"type": "array",
"items": {
"type": "object",
"properties": {
"degree": {
"type": "string"
},
"startYear": {
"type": "integer",
"minimum": 1900
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
},
"endMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
},
"endYear": {
"type": "integer",
"minimum": 1900
},
"ongoing": {
"oneOf": [{
"enum": [false],
"required": ["startYear", "endYear"]
},
{
"enum": [true],
"required": ["startYear"],
"not": {
"required": ["endYear"]
}
}
],
"type": "boolean"
},
"department": {
"type": "string"
},
"institution": {
"type": "string",
"minLength": 1
}
},
"required": [
"institution"
],
"additionalProperties": false,
"dependencies": {
"endMonth": ["endYear"],
"startMonth": ["startYear"],
"startYear": ["ongoing"],
"endYear": ["ongoing"],
"endYear": ["startYear"]
}
}
}
62 changes: 62 additions & 0 deletions api/users/schemas/employment-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"startYear": {
"type": "integer",
"minimum": 1900
},
"startMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
},
"endMonth": {
"type": "integer",
"minimum": 1,
"maximum": 12
},
"endYear": {
"type": "integer",
"minimum": 1900
},
"ongoing": {
"oneOf": [{
"enum": [false],
"required": ["startYear", "endYear"]
},
{
"enum": [true],
"required": ["startYear"],
"not": {
"required": ["endYear"]
}
}
],
"type": "boolean"
},
"department": {
"type": "string"
},
"institution": {
"type": "string",
"minLength": 1
}
},
"required": [
"institution"
],
"additionalProperties": false,
"dependencies": {
"endMonth": ["endYear"],
"startMonth": ["startYear"],
"startYear": ["ongoing"],
"endYear": ["ongoing"],
"endYear": ["startYear"]
}
}
}
40 changes: 40 additions & 0 deletions api/users/schemas/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os
import json
import datetime
import jsonschema

from api.base.exceptions import InvalidModelValueError

here = os.path.split(os.path.abspath(__file__))[0]

def from_json(fname):
with open(os.path.join(here, fname)) as f:
return json.load(f)


def validate_user_json(value, json_schema):
try:
jsonschema.validate(value, from_json(json_schema))
except jsonschema.ValidationError as e:
if len(e.path) > 1:
raise InvalidModelValueError("For '{}' the field value {}".format(e.path[-1], e.message))
raise InvalidModelValueError(e.message)
except jsonschema.SchemaError as e:
raise InvalidModelValueError(e.message)

validate_dates(value)


def validate_dates(info):
for history in info:

if history.get('startYear'):
startDate = datetime.date(history['startYear'], history.get('startMonth', 1), 1)

if not history['ongoing']:
if history.get('endYear'):
endDate = datetime.date(history['endYear'], history.get('endMonth', 1), 1)

if history.get('startYear') and history.get('endYear'):
if (endDate - startDate).days <= 0:
raise InvalidModelValueError(detail='End date must be greater than or equal to the start date.')
17 changes: 13 additions & 4 deletions api/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
from api.base.serializers import (
BaseAPISerializer, JSONAPISerializer, JSONAPIRelationshipSerializer,
VersionedDateTimeField, HideIfDisabled, IDField,
Link, LinksField, ListDictField, TypeField, RelationshipField,
WaterbutlerLink, ShowIfCurrentUser, DevOnly
Link, LinksField, ListDictField, TypeField, RelationshipField, JSONAPIListField,
WaterbutlerLink, ShowIfCurrentUser
)
from api.base.utils import absolute_reverse, get_user_auth, waterbutler_api_url_for
from api.files.serializers import QuickFilesSerializer
from osf.exceptions import ValidationValueError, ValidationError
from osf.models import OSFUser, QuickFilesNode
from api.users.schemas.utils import validate_user_json


class QuickFilesRelationshipField(RelationshipField):
Expand Down Expand Up @@ -57,8 +58,8 @@ class UserSerializer(JSONAPISerializer):
timezone = HideIfDisabled(ser.CharField(required=False, help_text="User's timezone, e.g. 'Etc/UTC"))
locale = HideIfDisabled(ser.CharField(required=False, help_text="User's locale, e.g. 'en_US'"))
social = ListDictField(required=False)
employment = DevOnly(ser.ListField(child=ser.DictField(), source='jobs', read_only=True))
education = DevOnly(ser.ListField(child=ser.DictField(), source='schools', read_only=True))
employment = JSONAPIListField(required=False, source='jobs')
education = JSONAPIListField(required=False, source='schools')
can_view_reviews = ShowIfCurrentUser(ser.SerializerMethodField(help_text='Whether the current user has the `view_submissions` permission to ANY reviews provider.'))
accepted_terms_of_service = ShowIfCurrentUser(ser.SerializerMethodField())

Expand Down Expand Up @@ -128,6 +129,14 @@ def profile_image_url(self, user):
size = self.context['request'].query_params.get('profile_image_size')
return user.profile_image_url(size=size)

def validate_employment(self, value):
validate_user_json(value, 'employment-schema.json')
return value

def validate_education(self, value):
validate_user_json(value, 'education-schema.json')
return value

def update(self, instance, validated_data):
assert isinstance(instance, OSFUser), 'instance must be a User'
for attr, value in validated_data.items():
Expand Down
Loading

0 comments on commit 92c8afb

Please sign in to comment.