diff --git a/openlobby/core/api/mutations.py b/openlobby/core/api/mutations.py index a0e10121aacde0e9cdbbf958d8a6d90b5465a758..4c92f8ec6cdba1dfc792a5935ff0c2af279f7726 100644 --- a/openlobby/core/api/mutations.py +++ b/openlobby/core/api/mutations.py @@ -20,7 +20,6 @@ STATE_LENGTH = 48 class Login(relay.ClientIDMutation): - class Input: openid_uid = graphene.String(required=True) redirect_uri = graphene.String(required=True) @@ -29,8 +28,8 @@ class Login(relay.ClientIDMutation): @classmethod def mutate_and_get_payload(cls, root, info, **input): - openid_uid = input['openid_uid'] - app_redirect_uri = input['redirect_uri'] + openid_uid = input["openid_uid"] + app_redirect_uri = input["redirect_uri"] # prepare OpenID client issuer = discover_issuer(openid_uid) @@ -50,8 +49,12 @@ class Login(relay.ClientIDMutation): state = rndstr(STATE_LENGTH) # save login attempt - LoginAttempt.objects.create(state=state, openid_client=openid_client_obj, - app_redirect_uri=app_redirect_uri, openid_uid=openid_uid) + LoginAttempt.objects.create( + state=state, + openid_client=openid_client_obj, + app_redirect_uri=app_redirect_uri, + openid_uid=openid_uid, + ) # get OpenID authorization url authorization_url = get_authorization_url(client, state) @@ -60,7 +63,6 @@ class Login(relay.ClientIDMutation): class LoginByShortcut(relay.ClientIDMutation): - class Input: shortcut_id = relay.GlobalID(required=True) redirect_uri = graphene.String(required=True) @@ -69,8 +71,8 @@ class LoginByShortcut(relay.ClientIDMutation): @classmethod def mutate_and_get_payload(cls, root, info, **input): - shortcut_id = input['shortcut_id'] - app_redirect_uri = input['redirect_uri'] + shortcut_id = input["shortcut_id"] + app_redirect_uri = input["redirect_uri"] # prepare OpenID client type, id = from_global_id(shortcut_id) @@ -81,8 +83,11 @@ class LoginByShortcut(relay.ClientIDMutation): state = rndstr(STATE_LENGTH) # save login attempt - LoginAttempt.objects.create(state=state, openid_client=openid_client_obj, - app_redirect_uri=app_redirect_uri) + LoginAttempt.objects.create( + state=state, + openid_client=openid_client_obj, + app_redirect_uri=app_redirect_uri, + ) # get OpenID authorization url authorization_url = get_authorization_url(client, state) @@ -100,7 +105,6 @@ class Logout(relay.ClientIDMutation): class CreateReport(relay.ClientIDMutation): - class Input: title = graphene.String(required=True) body = graphene.String(required=True) @@ -116,27 +120,26 @@ class CreateReport(relay.ClientIDMutation): @classmethod def mutate_and_get_payload(cls, root, info, **input): if not info.context.user.is_authenticated: - raise Exception('User must be logged in to perform this mutation.') + raise Exception("User must be logged in to perform this mutation.") author = info.context.user report = Report.objects.create( author=author, - date=input.get('date'), - title=strip_all_tags(input.get('title', '')), - body=strip_all_tags(input.get('body', '')), - received_benefit=strip_all_tags(input.get('received_benefit', '')), - provided_benefit=strip_all_tags(input.get('provided_benefit', '')), - our_participants=strip_all_tags(input.get('our_participants', '')), - other_participants=strip_all_tags(input.get('other_participants', '')), - is_draft=input.get('is_draft'), + date=input.get("date"), + title=strip_all_tags(input.get("title", "")), + body=strip_all_tags(input.get("body", "")), + received_benefit=strip_all_tags(input.get("received_benefit", "")), + provided_benefit=strip_all_tags(input.get("provided_benefit", "")), + our_participants=strip_all_tags(input.get("our_participants", "")), + other_participants=strip_all_tags(input.get("other_participants", "")), + is_draft=input.get("is_draft"), ) return CreateReport(report=types.Report.from_db(report)) class UpdateReport(relay.ClientIDMutation): - class Input: id = graphene.ID(required=True) title = graphene.String(required=True) @@ -153,32 +156,36 @@ class UpdateReport(relay.ClientIDMutation): @classmethod def mutate_and_get_payload(cls, root, info, **input): if not info.context.user.is_authenticated: - raise Exception('User must be logged in to perform this mutation.') + raise Exception("User must be logged in to perform this mutation.") author = info.context.user - type, id = from_global_id(input.get('id')) + type, id = from_global_id(input.get("id")) try: - report = Report.objects.select_related('author').get(id=id, author_id=author.id) + report = Report.objects.select_related("author").get( + id=id, author_id=author.id + ) except Report.DoesNotExist: - raise Exception('Viewer is not the Author of this Report or Report does not exist.') + raise Exception( + "Viewer is not the Author of this Report or Report does not exist." + ) - is_draft = input.get('is_draft') + is_draft = input.get("is_draft") if is_draft and not report.is_draft: - raise Exception('You cannot update published Report with draft.') + raise Exception("You cannot update published Report with draft.") # TODO updating published report older than like a hour should create # new revision in history of report report.published = arrow.utcnow().datetime - report.date = input.get('date') - report.title = strip_all_tags(input.get('title', '')) - report.body = strip_all_tags(input.get('body', '')) - report.received_benefit = strip_all_tags(input.get('received_benefit', '')) - report.provided_benefit = strip_all_tags(input.get('provided_benefit', '')) - report.our_participants = strip_all_tags(input.get('our_participants', '')) - report.other_participants = strip_all_tags(input.get('other_participants', '')) + report.date = input.get("date") + report.title = strip_all_tags(input.get("title", "")) + report.body = strip_all_tags(input.get("body", "")) + report.received_benefit = strip_all_tags(input.get("received_benefit", "")) + report.provided_benefit = strip_all_tags(input.get("provided_benefit", "")) + report.our_participants = strip_all_tags(input.get("our_participants", "")) + report.other_participants = strip_all_tags(input.get("other_participants", "")) report.is_draft = is_draft report.save() diff --git a/openlobby/core/api/paginator.py b/openlobby/core/api/paginator.py index ea7b05ae39935f072045bd4cb1ae31bbd8a12eff..9e0db12c12d9a5f054e8189053c98e29ccf493f1 100644 --- a/openlobby/core/api/paginator.py +++ b/openlobby/core/api/paginator.py @@ -10,16 +10,24 @@ class MissingBeforeValueError(Exception): def encode_cursor(num): - return base64.b64encode(str(num).encode('utf-8')).decode('utf-8') + return base64.b64encode(str(num).encode("utf-8")).decode("utf-8") def decode_cursor(cursor): - return int(base64.b64decode(cursor).decode('utf-8')) + return int(base64.b64decode(cursor).decode("utf-8")) class Paginator: - - def __init__(self, *, first=None, after=None, last=None, before=None, per_page=PER_PAGE, **kwargs): + def __init__( + self, + *, + first=None, + after=None, + last=None, + before=None, + per_page=PER_PAGE, + **kwargs + ): self.per_page = per_page slice_from = 0 @@ -32,7 +40,9 @@ class Paginator: elif last is not None: if before is None: - raise MissingBeforeValueError('Pagination "last" works only in combination with "before" argument.') + raise MissingBeforeValueError( + 'Pagination "last" works only in combination with "before" argument.' + ) slice_to = decode_cursor(before) - 1 slice_from = slice_to - last @@ -62,8 +72,12 @@ class Paginator: if self.slice_to < total: has_next_page = True - return PageInfo(has_previous_page=has_previous_page, has_next_page=has_next_page, - start_cursor=start_cursor, end_cursor=end_cursor) + return PageInfo( + has_previous_page=has_previous_page, + has_next_page=has_next_page, + start_cursor=start_cursor, + end_cursor=end_cursor, + ) def get_edge_cursor(self, num): return encode_cursor(self.slice_from + num) diff --git a/openlobby/core/api/sanitizers.py b/openlobby/core/api/sanitizers.py index 02245afc937c2a32e86fc70fa91e6f1dd01e80e4..9b741a5c9cdab2638a23657f4dda1e1a1dfec07c 100644 --- a/openlobby/core/api/sanitizers.py +++ b/openlobby/core/api/sanitizers.py @@ -8,4 +8,4 @@ def strip_all_tags(value): def extract_text(value): value = strip_all_tags(value) - return ' '.join(re.findall(r'(\b\w+)', value)) + return " ".join(re.findall(r"(\b\w+)", value)) diff --git a/openlobby/core/api/schema.py b/openlobby/core/api/schema.py index 9060e6ca465f24f7a8757dd0247cac4707374a2f..c2c79abf9e9b1e5355c750b08412067b37f70a37 100644 --- a/openlobby/core/api/schema.py +++ b/openlobby/core/api/schema.py @@ -12,12 +12,14 @@ from ..models import User, Report AUTHOR_SORT_LAST_NAME_ID = 1 AUTHOR_SORT_TOTAL_REPORTS_ID = 2 + class AuthorSortEnum(graphene.Enum): LAST_NAME = AUTHOR_SORT_LAST_NAME_ID TOTAL_REPORTS = AUTHOR_SORT_TOTAL_REPORTS_ID class Meta: - description = 'Sort by field.' + description = "Sort by field." + class AuthorsConnection(relay.Connection): total_count = graphene.Int() @@ -34,36 +36,39 @@ class SearchReportsConnection(relay.Connection): def _get_authors_cache(ids): - authors = User.objects.filter(id__in=ids)\ - .annotate(total_reports=Count('report', filter=Q(report__is_draft=False))) + authors = User.objects.filter(id__in=ids).annotate( + total_reports=Count("report", filter=Q(report__is_draft=False)) + ) return {a.id: types.Author.from_db(a) for a in authors} class Query: - highlight_help = ('Whether search matches should be marked with tag <mark>.' - ' Default: false') + highlight_help = ( + "Whether search matches should be marked with tag <mark>." " Default: false" + ) node = relay.Node.Field() authors = relay.ConnectionField( AuthorsConnection, - description='List of Authors. Returns first 10 nodes if pagination is not specified.', + description="List of Authors. Returns first 10 nodes if pagination is not specified.", sort=AuthorSortEnum(), - reversed=graphene.Boolean(default_value=False, description="Reverse order of sort") + reversed=graphene.Boolean( + default_value=False, description="Reverse order of sort" + ), ) search_reports = relay.ConnectionField( SearchReportsConnection, - description='Fulltext search in Reports. Returns first 10 nodes if pagination is not specified.', - query=graphene.String(description='Text to search for.'), + description="Fulltext search in Reports. Returns first 10 nodes if pagination is not specified.", + query=graphene.String(description="Text to search for."), highlight=graphene.Boolean(default_value=False, description=highlight_help), ) - viewer = graphene.Field(types.User, description='Active user viewing API.') + viewer = graphene.Field(types.User, description="Active user viewing API.") login_shortcuts = graphene.List( types.LoginShortcut, - description='Shortcuts for login. Use with LoginByShortcut mutation.', + description="Shortcuts for login. Use with LoginByShortcut mutation.", ) report_drafts = graphene.List( - types.Report, - description='Saved drafts of reports for Viewer.', + types.Report, description="Saved drafts of reports for Viewer." ) def resolve_authors(self, info, **kwargs): @@ -71,9 +76,9 @@ class Query: total = User.objects.filter(is_author=True).count() - authors = User.objects\ - .sorted(**kwargs)\ - .filter(is_author=True)[paginator.slice_from:paginator.slice_to] + authors = User.objects.sorted(**kwargs).filter(is_author=True)[ + paginator.slice_from : paginator.slice_to + ] page_info = paginator.get_page_info(total) @@ -87,11 +92,9 @@ class Query: def resolve_search_reports(self, info, **kwargs): paginator = Paginator(**kwargs) - query = kwargs.get('query', '') + query = kwargs.get("query", "") query = extract_text(query) - params = { - 'highlight': kwargs.get('highlight'), - } + params = {"highlight": kwargs.get("highlight")} response = search.query_reports(query, paginator, **params) total = response.hits.total page_info = paginator.get_page_info(total) @@ -104,7 +107,9 @@ class Query: node = types.Report.from_es(report, author=authors[report.author_id]) edges.append(SearchReportsConnection.Edge(node=node, cursor=cursor)) - return SearchReportsConnection(page_info=page_info, edges=edges, total_count=total) + return SearchReportsConnection( + page_info=page_info, edges=edges, total_count=total + ) def resolve_viewer(self, info, **kwargs): if info.context.user.is_authenticated: @@ -113,7 +118,7 @@ class Query: return None def resolve_login_shortcuts(self, info, **kwargs): - clients = OpenIdClient.objects.filter(is_shortcut=True).order_by('name') + clients = OpenIdClient.objects.filter(is_shortcut=True).order_by("name") return [types.LoginShortcut.from_db(c) for c in clients] def resolve_report_drafts(self, info, **kwargs): diff --git a/openlobby/core/api/types.py b/openlobby/core/api/types.py index d552d370efe4c416bdd131363a719e72c35d0083..8d56829470f32fb7acc8eb75d898bdc9e18e029e 100644 --- a/openlobby/core/api/types.py +++ b/openlobby/core/api/types.py @@ -12,9 +12,9 @@ from .. import search def get_higlighted(hit, field): """Returns higlighted text of field if search is higlighted.""" - if hasattr(hit.meta, 'highlight') and field in hit.meta.highlight: + if hasattr(hit.meta, "highlight") and field in hit.meta.highlight: return hit.meta.highlight[field][0] - return hit[field] if field in hit else '' + return hit[field] if field in hit else "" class Report(graphene.ObjectType): @@ -31,7 +31,7 @@ class Report(graphene.ObjectType): extra = JSONString() class Meta: - interfaces = (relay.Node, ) + interfaces = (relay.Node,) @classmethod def from_es(cls, report, author=None): @@ -40,12 +40,12 @@ class Report(graphene.ObjectType): author=author, date=report.date, published=report.published, - title=get_higlighted(report, 'title'), - body=get_higlighted(report, 'body'), - received_benefit=get_higlighted(report, 'received_benefit'), - provided_benefit=get_higlighted(report, 'provided_benefit'), - our_participants=get_higlighted(report, 'our_participants'), - other_participants=get_higlighted(report, 'other_participants'), + title=get_higlighted(report, "title"), + body=get_higlighted(report, "body"), + received_benefit=get_higlighted(report, "received_benefit"), + provided_benefit=get_higlighted(report, "provided_benefit"), + our_participants=get_higlighted(report, "our_participants"), + other_participants=get_higlighted(report, "other_participants"), is_draft=report.is_draft, extra=report.extra, ) @@ -80,7 +80,7 @@ class Report(graphene.ObjectType): if report.author_id != info.context.user.id: return None - author_type = cls._meta.fields['author'].type + author_type = cls._meta.fields["author"].type author = author_type.get_node(info, report.author_id) return cls.from_es(report, author) @@ -102,7 +102,7 @@ class User(graphene.ObjectType): extra = JSONString() class Meta: - interfaces = (relay.Node, ) + interfaces = (relay.Node,) @classmethod def from_db(cls, user): @@ -135,7 +135,7 @@ class Author(graphene.ObjectType): reports = relay.ConnectionField(ReportConnection) class Meta: - interfaces = (relay.Node, ) + interfaces = (relay.Node,) @classmethod def from_db(cls, user): @@ -151,9 +151,9 @@ class Author(graphene.ObjectType): @classmethod def get_node(cls, info, id): try: - author = models.User.objects\ - .annotate(total_reports=Count('report', filter=Q(report__is_draft=False)))\ - .get(id=id, is_author=True) + author = models.User.objects.annotate( + total_reports=Count("report", filter=Q(report__is_draft=False)) + ).get(id=id, is_author=True) return cls.from_db(author) except models.User.DoesNotExist: return None @@ -180,7 +180,7 @@ class LoginShortcut(graphene.ObjectType): name = graphene.String() class Meta: - interfaces = (relay.Node, ) + interfaces = (relay.Node,) @classmethod def from_db(cls, openid_client): diff --git a/openlobby/core/api/utils.py b/openlobby/core/api/utils.py index e2503c6f2b511527b797c270d6c758ecfbe2d7c7..8d6d7324fa8a0f9d03d8b181d9549b8e4eee3829 100644 --- a/openlobby/core/api/utils.py +++ b/openlobby/core/api/utils.py @@ -2,5 +2,5 @@ from django.http import JsonResponse def graphql_error_response(message, status_code=400): - error = {'message': message} - return JsonResponse({'errors': [error]}, status=status_code) + error = {"message": message} + return JsonResponse({"errors": [error]}, status=status_code) diff --git a/openlobby/core/apps.py b/openlobby/core/apps.py index 26f78a8e673340121f68a92930e2830bc58d269d..5ef1d600da3500626bfb855e8d489c82aeb6670f 100644 --- a/openlobby/core/apps.py +++ b/openlobby/core/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class CoreConfig(AppConfig): - name = 'core' + name = "core" diff --git a/openlobby/core/auth.py b/openlobby/core/auth.py index b49b3a94ef675e132f8df1e008812b8a6ba7b714..4508690585c4871ee48b8f5cf333f07dfe7968f3 100644 --- a/openlobby/core/auth.py +++ b/openlobby/core/auth.py @@ -6,14 +6,13 @@ import time def create_access_token(username, expiration=None): if expiration is None: expiration = int(time.time() + settings.SESSION_EXPIRATION) - payload = { - 'sub': username, - 'exp': expiration, - } + payload = {"sub": username, "exp": expiration} token = jwt.encode(payload, settings.SECRET_KEY, algorithm=settings.JWT_ALGORITHM) - return token.decode('utf-8') + return token.decode("utf-8") def parse_access_token(token): - payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.JWT_ALGORITHM]) - return payload['sub'] + payload = jwt.decode( + token, settings.SECRET_KEY, algorithms=[settings.JWT_ALGORITHM] + ) + return payload["sub"] diff --git a/openlobby/core/documents.py b/openlobby/core/documents.py index 69504a988e15884cf7774c618cc16cd41a597fe5..3923f6eada3d24fa47846899c2f07f7a2b665ba9 100644 --- a/openlobby/core/documents.py +++ b/openlobby/core/documents.py @@ -5,7 +5,7 @@ import json from .models import Report -report = Index('{}-reports'.format(settings.ES_INDEX)) +report = Index("{}-reports".format(settings.ES_INDEX)) @report.doc_type @@ -30,8 +30,4 @@ class ReportDoc(DocType): class Meta: model = Report - fields = [ - 'date', - 'published', - 'is_draft', - ] + fields = ["date", "published", "is_draft"] diff --git a/openlobby/core/middleware.py b/openlobby/core/middleware.py index a6c1083c595d7ae6f7b7e0cba48a9561b455c8aa..a46c12324adb59364cf9dee35c19eb4a70ab3287 100644 --- a/openlobby/core/middleware.py +++ b/openlobby/core/middleware.py @@ -12,18 +12,20 @@ class TokenAuthMiddleware: self.get_response = get_response def __call__(self, request): - auth_header = request.META.get('HTTP_AUTHORIZATION') + auth_header = request.META.get("HTTP_AUTHORIZATION") if auth_header is not None: - m = re.match(r'Bearer (?P<token>.+)', auth_header) + m = re.match(r"Bearer (?P<token>.+)", auth_header) if m: - token = m.group('token') + token = m.group("token") else: - return graphql_error_response('Wrong Authorization header. Expected: "Bearer <token>"') + return graphql_error_response( + 'Wrong Authorization header. Expected: "Bearer <token>"' + ) try: username = parse_access_token(token) except Exception: - return graphql_error_response('Invalid Token.', 401) + return graphql_error_response("Invalid Token.", 401) try: request.user = User.objects.get(username=username) diff --git a/openlobby/core/migrations/0001_initial.py b/openlobby/core/migrations/0001_initial.py index 6e16fd07305e7a325fdbe10617b20365eed5f2b3..530b306eec1c9186744c9e73b402ce6301d7ed4b 100644 --- a/openlobby/core/migrations/0001_initial.py +++ b/openlobby/core/migrations/0001_initial.py @@ -13,81 +13,203 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('auth', '0009_alter_user_last_name_max_length'), - ] + dependencies = [("auth", "0009_alter_user_last_name_max_length")] operations = [ migrations.CreateModel( - name='User', + name="User", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('openid_uid', models.CharField(db_index=True, max_length=255, unique=True)), - ('extras', django.contrib.postgres.fields.jsonb.JSONField()), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name="username", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=30, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "email", + models.EmailField( + blank=True, max_length=254, verbose_name="email address" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "openid_uid", + models.CharField(db_index=True, max_length=255, unique=True), + ), + ("extras", django.contrib.postgres.fields.jsonb.JSONField()), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.Group", + verbose_name="groups", + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.Permission", + verbose_name="user permissions", + ), + ), ], options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, }, - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], + managers=[("objects", django.contrib.auth.models.UserManager())], ), migrations.CreateModel( - name='LoginAttempt', + name="LoginAttempt", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('state', models.CharField(db_index=True, max_length=50, unique=True)), - ('redirect_uri', models.CharField(max_length=255)), - ('expiration', models.IntegerField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("state", models.CharField(db_index=True, max_length=50, unique=True)), + ("redirect_uri", models.CharField(max_length=255)), + ("expiration", models.IntegerField()), ], ), migrations.CreateModel( - name='OpenIdClient', + name="OpenIdClient", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('is_shortcut', models.BooleanField(default=False)), - ('client_id', models.CharField(max_length=255)), - ('client_secret', models.CharField(max_length=255)), - ('issuer', models.CharField(db_index=True, max_length=255, unique=True)), - ('authorization_endpoint', models.CharField(max_length=255)), - ('token_endpoint', models.CharField(max_length=255)), - ('userinfo_endpoint', models.CharField(max_length=255)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("is_shortcut", models.BooleanField(default=False)), + ("client_id", models.CharField(max_length=255)), + ("client_secret", models.CharField(max_length=255)), + ( + "issuer", + models.CharField(db_index=True, max_length=255, unique=True), + ), + ("authorization_endpoint", models.CharField(max_length=255)), + ("token_endpoint", models.CharField(max_length=255)), + ("userinfo_endpoint", models.CharField(max_length=255)), ], ), migrations.CreateModel( - name='Report', + name="Report", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateTimeField()), - ('published', models.DateTimeField()), - ('title', models.TextField()), - ('body', models.TextField()), - ('received_benefit', models.TextField()), - ('provided_benefit', models.TextField()), - ('our_participants', models.TextField()), - ('other_participants', models.TextField()), - ('extra', django.contrib.postgres.fields.jsonb.JSONField()), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date", models.DateTimeField()), + ("published", models.DateTimeField()), + ("title", models.TextField()), + ("body", models.TextField()), + ("received_benefit", models.TextField()), + ("provided_benefit", models.TextField()), + ("our_participants", models.TextField()), + ("other_participants", models.TextField()), + ("extra", django.contrib.postgres.fields.jsonb.JSONField()), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.AddField( - model_name='loginattempt', - name='openid_client', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.OpenIdClient'), + model_name="loginattempt", + name="openid_client", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="core.OpenIdClient" + ), ), ] diff --git a/openlobby/core/migrations/0002_auto_20180116_2349.py b/openlobby/core/migrations/0002_auto_20180116_2349.py index db82fcff43eea3210500cb4d4da010f13834d3fd..b3785e0270c3268c9937199e6cbe1707b163e3e3 100644 --- a/openlobby/core/migrations/0002_auto_20180116_2349.py +++ b/openlobby/core/migrations/0002_auto_20180116_2349.py @@ -6,44 +6,42 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0001_initial'), - ] + dependencies = [("core", "0001_initial")] operations = [ migrations.AlterField( - model_name='report', - name='extra', + model_name="report", + name="extra", field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), ), migrations.AlterField( - model_name='report', - name='other_participants', + model_name="report", + name="other_participants", field=models.TextField(blank=True, null=True), ), migrations.AlterField( - model_name='report', - name='our_participants', + model_name="report", + name="our_participants", field=models.TextField(blank=True, null=True), ), migrations.AlterField( - model_name='report', - name='provided_benefit', + model_name="report", + name="provided_benefit", field=models.TextField(blank=True, null=True), ), migrations.AlterField( - model_name='report', - name='received_benefit', + model_name="report", + name="received_benefit", field=models.TextField(blank=True, null=True), ), migrations.AlterField( - model_name='report', - name='title', + model_name="report", + name="title", field=models.TextField(blank=True, null=True), ), migrations.AlterField( - model_name='user', - name='extras', + model_name="user", + name="extras", field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), ), ] diff --git a/openlobby/core/migrations/0003_auto_20180117_0030.py b/openlobby/core/migrations/0003_auto_20180117_0030.py index b48c6ca7f0f47d8d7aabdf806ea40175902868fc..c0f55a23358cd58ff329451b09a03f777cb038d9 100644 --- a/openlobby/core/migrations/0003_auto_20180117_0030.py +++ b/openlobby/core/migrations/0003_auto_20180117_0030.py @@ -5,14 +5,8 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('core', '0002_auto_20180116_2349'), - ] + dependencies = [("core", "0002_auto_20180116_2349")] operations = [ - migrations.RenameField( - model_name='user', - old_name='extras', - new_name='extra', - ), + migrations.RenameField(model_name="user", old_name="extras", new_name="extra") ] diff --git a/openlobby/core/migrations/0004_user_is_author.py b/openlobby/core/migrations/0004_user_is_author.py index 9a8e43e40003605a4240ef6fb5313ea118c8936d..0ba417286561e5f68f706eeb93953bb7bb21846e 100644 --- a/openlobby/core/migrations/0004_user_is_author.py +++ b/openlobby/core/migrations/0004_user_is_author.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0003_auto_20180117_0030'), - ] + dependencies = [("core", "0003_auto_20180117_0030")] operations = [ migrations.AddField( - model_name='user', - name='is_author', + model_name="user", + name="is_author", field=models.BooleanField(default=False), - ), + ) ] diff --git a/openlobby/core/migrations/0005_auto_20180208_1210.py b/openlobby/core/migrations/0005_auto_20180208_1210.py index ce3b8ec06ee7c9a645d3b12b0eec675870fbef0c..0b17bde07adc0033415235b8e20559ba3931d6e9 100644 --- a/openlobby/core/migrations/0005_auto_20180208_1210.py +++ b/openlobby/core/migrations/0005_auto_20180208_1210.py @@ -6,19 +6,17 @@ import django.utils.timezone class Migration(migrations.Migration): - dependencies = [ - ('core', '0004_user_is_author'), - ] + dependencies = [("core", "0004_user_is_author")] operations = [ migrations.RenameField( - model_name='loginattempt', - old_name='redirect_uri', - new_name='app_redirect_uri', + model_name="loginattempt", + old_name="redirect_uri", + new_name="app_redirect_uri", ), migrations.AlterField( - model_name='report', - name='published', + model_name="report", + name="published", field=models.DateTimeField(default=django.utils.timezone.now), ), ] diff --git a/openlobby/core/migrations/0006_auto_20180208_1544.py b/openlobby/core/migrations/0006_auto_20180208_1544.py index 90eb680791f7ec9859bce5fa141cc5c4d00b9387..b7298bb6ac55c93fd61dd7fde7b6af0787af7748 100644 --- a/openlobby/core/migrations/0006_auto_20180208_1544.py +++ b/openlobby/core/migrations/0006_auto_20180208_1544.py @@ -6,14 +6,14 @@ import openlobby.core.models class Migration(migrations.Migration): - dependencies = [ - ('core', '0005_auto_20180208_1210'), - ] + dependencies = [("core", "0005_auto_20180208_1210")] operations = [ migrations.AlterField( - model_name='loginattempt', - name='expiration', - field=models.IntegerField(default=openlobby.core.models.get_login_attempt_expiration), - ), + model_name="loginattempt", + name="expiration", + field=models.IntegerField( + default=openlobby.core.models.get_login_attempt_expiration + ), + ) ] diff --git a/openlobby/core/migrations/0007_auto_20180209_1809.py b/openlobby/core/migrations/0007_auto_20180209_1809.py index 898503bc22fcf9ae91e8e1198bcd8cdca320b1e3..ad0f2bb01e92071375ae0815f462df2d0b5fe115 100644 --- a/openlobby/core/migrations/0007_auto_20180209_1809.py +++ b/openlobby/core/migrations/0007_auto_20180209_1809.py @@ -5,21 +5,12 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('core', '0006_auto_20180208_1544'), - ] + dependencies = [("core", "0006_auto_20180208_1544")] operations = [ migrations.RemoveField( - model_name='openidclient', - name='authorization_endpoint', - ), - migrations.RemoveField( - model_name='openidclient', - name='token_endpoint', - ), - migrations.RemoveField( - model_name='openidclient', - name='userinfo_endpoint', + model_name="openidclient", name="authorization_endpoint" ), + migrations.RemoveField(model_name="openidclient", name="token_endpoint"), + migrations.RemoveField(model_name="openidclient", name="userinfo_endpoint"), ] diff --git a/openlobby/core/migrations/0008_loginattempt_openid_uid.py b/openlobby/core/migrations/0008_loginattempt_openid_uid.py index 7243cf4b4e815bbdfe72527bc2c56de8a9abb51e..986697dbe940ad544311a8e79646752d2853ac1d 100644 --- a/openlobby/core/migrations/0008_loginattempt_openid_uid.py +++ b/openlobby/core/migrations/0008_loginattempt_openid_uid.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0007_auto_20180209_1809'), - ] + dependencies = [("core", "0007_auto_20180209_1809")] operations = [ migrations.AddField( - model_name='loginattempt', - name='openid_uid', + model_name="loginattempt", + name="openid_uid", field=models.CharField(max_length=255, null=True), - ), + ) ] diff --git a/openlobby/core/migrations/0009_auto_20180217_1850.py b/openlobby/core/migrations/0009_auto_20180217_1850.py index 88afb4af1cd95ba957cdc1d231bbe994378c5fce..716785d2471d150c92fd6c1a059259de097bdc06 100644 --- a/openlobby/core/migrations/0009_auto_20180217_1850.py +++ b/openlobby/core/migrations/0009_auto_20180217_1850.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0008_loginattempt_openid_uid'), - ] + dependencies = [("core", "0008_loginattempt_openid_uid")] operations = [ migrations.AlterField( - model_name='user', - name='openid_uid', + model_name="user", + name="openid_uid", field=models.CharField(max_length=255, null=True), - ), + ) ] diff --git a/openlobby/core/migrations/0010_user_has_colliding_name.py b/openlobby/core/migrations/0010_user_has_colliding_name.py index 5eae315ff2b9d87c1231b044675ca91c7611794d..220e2b3f6328b33d1ff0a70063e1d1845785fa62 100644 --- a/openlobby/core/migrations/0010_user_has_colliding_name.py +++ b/openlobby/core/migrations/0010_user_has_colliding_name.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0009_auto_20180217_1850'), - ] + dependencies = [("core", "0009_auto_20180217_1850")] operations = [ migrations.AddField( - model_name='user', - name='has_colliding_name', + model_name="user", + name="has_colliding_name", field=models.BooleanField(default=False), - ), + ) ] diff --git a/openlobby/core/migrations/0011_report_is_draft.py b/openlobby/core/migrations/0011_report_is_draft.py index f5a7d1865998efdb4c5a051196217a7b6acd6aed..a7ef9d9fb8bbbfa7ef4c1b2f81a04b9822ff27df 100644 --- a/openlobby/core/migrations/0011_report_is_draft.py +++ b/openlobby/core/migrations/0011_report_is_draft.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('core', '0010_user_has_colliding_name'), - ] + dependencies = [("core", "0010_user_has_colliding_name")] operations = [ migrations.AddField( - model_name='report', - name='is_draft', + model_name="report", + name="is_draft", field=models.BooleanField(default=False), - ), + ) ] diff --git a/openlobby/core/models.py b/openlobby/core/models.py index 8c46ec0e6455123c6318a998e037bd34e0888686..adb32d601b1d36628d2414d6d7fa465e180fecbf 100644 --- a/openlobby/core/models.py +++ b/openlobby/core/models.py @@ -13,13 +13,25 @@ from django.utils import timezone class UserManager(BaseUserManager): def sorted(self, **kwargs): # inline import intentionally - from openlobby.core.api.schema import AUTHOR_SORT_LAST_NAME_ID, AUTHOR_SORT_TOTAL_REPORTS_ID - qs = self.get_queryset().annotate(total_reports=Count('report', filter=Q(report__is_draft=False))) - sort_field = kwargs.get('sort', AUTHOR_SORT_LAST_NAME_ID) + from openlobby.core.api.schema import ( + AUTHOR_SORT_LAST_NAME_ID, + AUTHOR_SORT_TOTAL_REPORTS_ID, + ) + + qs = self.get_queryset().annotate( + total_reports=Count("report", filter=Q(report__is_draft=False)) + ) + sort_field = kwargs.get("sort", AUTHOR_SORT_LAST_NAME_ID) if sort_field == AUTHOR_SORT_LAST_NAME_ID: - return qs.order_by('{}last_name'.format('-' if kwargs.get('reversed', False) else ''), 'first_name') + return qs.order_by( + "{}last_name".format("-" if kwargs.get("reversed", False) else ""), + "first_name", + ) elif sort_field == AUTHOR_SORT_TOTAL_REPORTS_ID: - return qs.order_by('{}total_reports'.format('' if kwargs.get('reversed', False) else '-'), 'last_name') + return qs.order_by( + "{}total_reports".format("" if kwargs.get("reversed", False) else "-"), + "last_name", + ) raise NotImplemented("Other sort types are not implemented") @@ -27,6 +39,7 @@ class User(AbstractUser): """Custom user model. For simplicity we store OpenID 'sub' identifier in username field. """ + openid_uid = models.CharField(max_length=255, null=True) extra = JSONField(null=True, blank=True) is_author = models.BooleanField(default=False) @@ -36,8 +49,9 @@ class User(AbstractUser): def save(self, *args, **kwargs): # deal with first name and last name collisions if self.is_author: - collisions = User.objects.filter(first_name=self.first_name, last_name=self.last_name, - is_author=True).exclude(id=self.id) + collisions = User.objects.filter( + first_name=self.first_name, last_name=self.last_name, is_author=True + ).exclude(id=self.id) if collisions.count() > 0: self.has_colliding_name = True collisions.update(has_colliding_name=True) @@ -48,6 +62,7 @@ class OpenIdClient(models.Model): """Stores connection parameters for OpenID Clients. Some may be used as login shortcuts. """ + name = models.CharField(max_length=255) is_shortcut = models.BooleanField(default=False) client_id = models.CharField(max_length=255) @@ -64,6 +79,7 @@ def get_login_attempt_expiration(): class LoginAttempt(models.Model): """Temporary login attempt details which persists redirects.""" + openid_client = models.ForeignKey(OpenIdClient, on_delete=models.CASCADE) state = models.CharField(max_length=50, unique=True, db_index=True) app_redirect_uri = models.CharField(max_length=255) diff --git a/openlobby/core/openid.py b/openlobby/core/openid.py index 0ce9422a7cf012cd702d9178fd95cd7114d8a2aa..88b8d28e81d3bcc2432cf9f4fba2778ef95c55d5 100644 --- a/openlobby/core/openid.py +++ b/openlobby/core/openid.py @@ -17,9 +17,9 @@ def discover_issuer(openid_uid): def init_client_for_shortcut(openid_client_obj): client = Client(client_authn_method=CLIENT_AUTHN_METHOD) reg_info = { - 'client_id': openid_client_obj.client_id, - 'client_secret': openid_client_obj.client_secret, - 'redirect_uris': [settings.REDIRECT_URI], + "client_id": openid_client_obj.client_id, + "client_secret": openid_client_obj.client_secret, + "redirect_uris": [settings.REDIRECT_URI], } client_reg = RegistrationResponse(**reg_info) client.store_registration_info(client_reg) @@ -31,37 +31,40 @@ def register_client(issuer): client = Client(client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(issuer) params = { - 'redirect_uris': [settings.REDIRECT_URI], - 'client_name': settings.SITE_NAME, + "redirect_uris": [settings.REDIRECT_URI], + "client_name": settings.SITE_NAME, } - client.register(client.provider_info['registration_endpoint'], **params) + client.register(client.provider_info["registration_endpoint"], **params) return client def get_authorization_url(client, state): args = { - 'client_id': client.client_id, - 'response_type': 'code', - 'scope': 'openid', - 'state': state, - 'redirect_uri': client.registration_response['redirect_uris'][0], - 'claims': ClaimsRequest(userinfo=Claims( - given_name={'essential': True}, - family_name={'essential': True}, - email={'essential': True}, - )), + "client_id": client.client_id, + "response_type": "code", + "scope": "openid", + "state": state, + "redirect_uri": client.registration_response["redirect_uris"][0], + "claims": ClaimsRequest( + userinfo=Claims( + given_name={"essential": True}, + family_name={"essential": True}, + email={"essential": True}, + ) + ), } auth_req = client.construct_AuthorizationRequest(request_args=args) - return auth_req.request(client.provider_info['authorization_endpoint']) + return auth_req.request(client.provider_info["authorization_endpoint"]) def get_user_info(client, query_string): """Processes query string from OpenID redirect and returns user info.""" - aresp = client.parse_response(AuthorizationResponse, info=query_string, - sformat='urlencoded') + aresp = client.parse_response( + AuthorizationResponse, info=query_string, sformat="urlencoded" + ) - args = {'code': aresp['code'], 'redirect_uri': settings.REDIRECT_URI} - client.do_access_token_request(state=aresp['state'], request_args=args) + args = {"code": aresp["code"], "redirect_uri": settings.REDIRECT_URI} + client.do_access_token_request(state=aresp["state"], request_args=args) - return client.do_user_info_request(state=aresp['state']) + return client.do_user_info_request(state=aresp["state"]) diff --git a/openlobby/core/search.py b/openlobby/core/search.py index a87e167207b887f227aa4f175ac67ed5b163f7fe..fcf4bd2d7d0f5b2b862941d13625a1774779819b 100644 --- a/openlobby/core/search.py +++ b/openlobby/core/search.py @@ -2,30 +2,36 @@ from .documents import ReportDoc HIGHLIGHT_PARAMS = { - 'number_of_fragments': 0, - 'pre_tags': ['<mark>'], - 'post_tags': ['</mark>'], + "number_of_fragments": 0, + "pre_tags": ["<mark>"], + "post_tags": ["</mark>"], } def query_reports(query, paginator, *, highlight=False): - fields = ['title', 'body', 'received_benefit', 'provided_benefit', - 'our_participants', 'other_participants'] + fields = [ + "title", + "body", + "received_benefit", + "provided_benefit", + "our_participants", + "other_participants", + ] s = ReportDoc.search() - s = s.exclude('term', is_draft=True) - if query != '': - s = s.query('multi_match', query=query, fields=fields) + s = s.exclude("term", is_draft=True) + if query != "": + s = s.query("multi_match", query=query, fields=fields) if highlight: s = s.highlight(*fields, **HIGHLIGHT_PARAMS) - s = s.sort('-date') - s = s[paginator.slice_from:paginator.slice_to] + s = s.sort("-date") + s = s[paginator.slice_from : paginator.slice_to] return s.execute() def reports_by_author(author_id, paginator): s = ReportDoc.search() - s = s.exclude('term', is_draft=True) - s = s.filter('term', author_id=author_id) - s = s.sort('-date') - s = s[paginator.slice_from:paginator.slice_to] + s = s.exclude("term", is_draft=True) + s = s.filter("term", author_id=author_id) + s = s.sort("-date") + s = s[paginator.slice_from : paginator.slice_to] return s.execute() diff --git a/openlobby/core/views.py b/openlobby/core/views.py index e3780e971f20d6352f5229a46d89196a2e840360..0a2b79e4768cfdd1f7396c7f5cfd5c926c6fcafc 100644 --- a/openlobby/core/views.py +++ b/openlobby/core/views.py @@ -6,25 +6,22 @@ import urllib.parse from .auth import create_access_token from .models import LoginAttempt, User -from .openid import ( - init_client_for_shortcut, - get_user_info, -) +from .openid import init_client_for_shortcut, get_user_info class IndexView(TemplateView): - template_name = 'core/index.html' + template_name = "core/index.html" class LoginRedirectView(View): # TODO redirect to app_redirect_uri on fail def get(self, request, **kwargs): - query_string = request.META['QUERY_STRING'] + query_string = request.META["QUERY_STRING"] # get login attempt - state = request.GET.get('state') - la = LoginAttempt.objects.select_related('openid_client').get(state=state) + state = request.GET.get("state") + la = LoginAttempt.objects.select_related("openid_client").get(state=state) app_redirect_uri = la.app_redirect_uri if la.expiration < time.time(): @@ -38,14 +35,17 @@ class LoginRedirectView(View): client = init_client_for_shortcut(la.openid_client) user_info = get_user_info(client, query_string) - user, created = User.objects.get_or_create(username=user_info['sub'], defaults={ - 'username': user_info['sub'], - 'first_name': user_info['given_name'], - 'last_name': user_info['family_name'], - 'email': user_info['email'], - 'openid_uid': la.openid_uid, - }) + user, created = User.objects.get_or_create( + username=user_info["sub"], + defaults={ + "username": user_info["sub"], + "first_name": user_info["given_name"], + "last_name": user_info["family_name"], + "email": user_info["email"], + "openid_uid": la.openid_uid, + }, + ) token = create_access_token(user.username) - token_qs = urllib.parse.urlencode({'token': token}) - return redirect('{}?{}'.format(app_redirect_uri, token_qs)) + token_qs = urllib.parse.urlencode({"token": token}) + return redirect("{}?{}".format(app_redirect_uri, token_qs)) diff --git a/openlobby/schema.py b/openlobby/schema.py index 5772e2fd8a448384edf4b427c50b69aaa3c3ca41..4e5a6359cfacbb4fa085fef77e9af0ec8408afa8 100644 --- a/openlobby/schema.py +++ b/openlobby/schema.py @@ -13,5 +13,6 @@ class Mutation(CoreMutation, graphene.ObjectType): pass -schema = graphene.Schema(query=Query, mutation=Mutation, - types=[Author, User, Report, LoginShortcut]) +schema = graphene.Schema( + query=Query, mutation=Mutation, types=[Author, User, Report, LoginShortcut] +) diff --git a/openlobby/settings.py b/openlobby/settings.py index 034304d16162f9f4521bef39f031da6570ebc8dc..7fcb0b24cda95d0b4ba11212bb99a8676bf2d729 100644 --- a/openlobby/settings.py +++ b/openlobby/settings.py @@ -5,107 +5,106 @@ import dsnparse BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = 'DEBUG' in os.environ +DEBUG = "DEBUG" in os.environ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = os.environ.get('SECRET_KEY') +SECRET_KEY = os.environ.get("SECRET_KEY") if not SECRET_KEY: if DEBUG: - SECRET_KEY = 'not-secret-at-all' + SECRET_KEY = "not-secret-at-all" else: - raise RuntimeError('Missing SECRET_KEY environment variable.') + raise RuntimeError("Missing SECRET_KEY environment variable.") -ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.staticfiles', - 'django_extensions', - 'graphene_django', - 'django_elasticsearch_dsl', - 'openlobby.core', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.staticfiles", + "django_extensions", + "graphene_django", + "django_elasticsearch_dsl", + "openlobby.core", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'openlobby.core.middleware.TokenAuthMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "openlobby.core.middleware.TokenAuthMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", ] -ROOT_URLCONF = 'openlobby.urls' +ROOT_URLCONF = "openlobby.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ] }, - }, + } ] -WSGI_APPLICATION = 'openlobby.wsgi.application' +WSGI_APPLICATION = "openlobby.wsgi.application" -AUTH_USER_MODEL = 'core.User' +AUTH_USER_MODEL = "core.User" -DATABASE_DSN = os.environ.get('DATABASE_DSN', 'postgresql://db:db@localhost:5432/openlobby') +DATABASE_DSN = os.environ.get( + "DATABASE_DSN", "postgresql://db:db@localhost:5432/openlobby" +) db = dsnparse.parse(DATABASE_DSN) -assert db.scheme == 'postgresql' +assert db.scheme == "postgresql" DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': db.paths[0], - 'USER': db.username, - 'PASSWORD': db.password, - 'HOST': db.host, - 'PORT': db.port, + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": db.paths[0], + "USER": db.username, + "PASSWORD": db.password, + "HOST": db.host, + "PORT": db.port, } } ELASTICSEARCH_DSL = { - 'default': { - 'hosts': os.environ.get('ELASTICSEARCH_DSN', 'http://localhost:9200'), - }, + "default": {"hosts": os.environ.get("ELASTICSEARCH_DSN", "http://localhost:9200")} } -ELASTICSEARCH_DSL_INDEX_SETTINGS = { - 'number_of_shards': 1, - 'number_of_replicas': 0, -} +ELASTICSEARCH_DSL_INDEX_SETTINGS = {"number_of_shards": 1, "number_of_replicas": 0} # Password validation AUTH_PASSWORD_VALIDATORS = [ - {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, - {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, - {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, - {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, ] # Internationalization -LANGUAGE_CODE = 'cs' +LANGUAGE_CODE = "cs" -TIME_ZONE = 'Europe/Prague' +TIME_ZONE = "Europe/Prague" USE_I18N = True @@ -114,40 +113,31 @@ USE_L10N = True USE_TZ = True -STATIC_ROOT = os.path.join(BASE_DIR, 'static') -STATIC_URL = '/static/' +STATIC_ROOT = os.path.join(BASE_DIR, "static") +STATIC_URL = "/static/" LOGGING = { - 'version': 1, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - }, - }, - 'loggers': { - 'django': { - 'handlers': ['console'], - 'level': 'INFO' if DEBUG else 'WARNING', - }, + "version": 1, + "handlers": {"console": {"class": "logging.StreamHandler"}}, + "loggers": { + "django": {"handlers": ["console"], "level": "INFO" if DEBUG else "WARNING"} }, } -GRAPHENE = { - 'SCHEMA': 'openlobby.schema.schema' -} +GRAPHENE = {"SCHEMA": "openlobby.schema.schema"} ############################################################################### # Custom settings # Elasticsearch index with reports -ES_INDEX = os.environ.get('ES_INDEX', 'openlobby') +ES_INDEX = os.environ.get("ES_INDEX", "openlobby") # default analyzer for text fields -ES_TEXT_ANALYZER = os.environ.get('ES_TEXT_ANALYZER', 'czech') +ES_TEXT_ANALYZER = os.environ.get("ES_TEXT_ANALYZER", "czech") # signature algorithm JSON Web Tokens -JWT_ALGORITHM = 'HS512' +JWT_ALGORITHM = "HS512" # expiration time (seconds) of login attempt LOGIN_ATTEMPT_EXPIRATION = 300 @@ -156,7 +146,7 @@ LOGIN_ATTEMPT_EXPIRATION = 300 SESSION_EXPIRATION = 60 * 60 * 24 * 14 # name of the site used in OpenID authentication -SITE_NAME = os.environ.get('SITE_NAME', 'Open Lobby') +SITE_NAME = os.environ.get("SITE_NAME", "Open Lobby") # redirect URI used in OpenID authentication -REDIRECT_URI = os.environ.get('REDIRECT_URI', 'http://localhost:8010/login-redirect') +REDIRECT_URI = os.environ.get("REDIRECT_URI", "http://localhost:8010/login-redirect") diff --git a/openlobby/urls.py b/openlobby/urls.py index f9f5fed53ee512e7cc1ad4eeb090775ac5d0f9e3..76c329216daebcda53b4f34724550fda823c528f 100644 --- a/openlobby/urls.py +++ b/openlobby/urls.py @@ -6,8 +6,8 @@ from graphene_django.views import GraphQLView from openlobby.core.views import IndexView, LoginRedirectView urlpatterns = [ - path('', IndexView.as_view(), name='index'), - path('login-redirect', LoginRedirectView.as_view(), name='login-redirect'), - path('admin/', admin.site.urls), - path('graphql', csrf_exempt(GraphQLView.as_view(graphiql=True))), + path("", IndexView.as_view(), name="index"), + path("login-redirect", LoginRedirectView.as_view(), name="login-redirect"), + path("admin/", admin.site.urls), + path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))), ] diff --git a/setup.py b/setup.py index 3477bf9b938c9110a1cb28c3a4470906c24c1e28..e367ab68bdc967db1a78ff81a4197ed1b8a0478c 100644 --- a/setup.py +++ b/setup.py @@ -6,37 +6,32 @@ from os import path here = path.abspath(path.dirname(__file__)) # Get the long description from the README file -with open(path.join(here, 'README.md'), encoding='utf-8') as f: +with open(path.join(here, "README.md"), encoding="utf-8") as f: long_description = f.read() setup( - name='openlobby', - version='0.1.0', - url='https://github.com/openlobby/openlobby-server', - - author='Jan Bednarik', - author_email='jan.bednarik@gmail.com', - - description='Open Lobby Server', + name="openlobby", + version="0.1.0", + url="https://github.com/openlobby/openlobby-server", + author="Jan Bednarik", + author_email="jan.bednarik@gmail.com", + description="Open Lobby Server", long_description=long_description, - - packages=find_packages(exclude=['tests']), - + packages=find_packages(exclude=["tests"]), # TODO # install_requires=[], # extras_require={ # 'dev': [], # 'test': [], # }, - - license='MIT', + license="MIT", classifiers=[ - 'Development Status :: 4 - Beta', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', + "Development Status :: 4 - Beta", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", ], ) diff --git a/tests/conftest.py b/tests/conftest.py index 6d9cc6b844b8a82264ff793dfe73c4f31c7593b7..9b345233e1b1a2feb570ce62dff7951625706bbd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -24,14 +24,17 @@ def django_es(): def pytest_addoption(parser): - parser.addoption('--issuer', action='store', - help='OpenID Provider (server) issuer URL. Provider must allow client registration.') + parser.addoption( + "--issuer", + action="store", + help="OpenID Provider (server) issuer URL. Provider must allow client registration.", + ) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def issuer(request): """OpenID Provider issuer URL.""" - url = request.config.getoption('--issuer') + url = request.config.getoption("--issuer") if url is None: - pytest.skip('Missing OpenID Provider URL.') + pytest.skip("Missing OpenID Provider URL.") return url diff --git a/tests/dummy.py b/tests/dummy.py index 5e99de33667e8857523805e188bb7749fa0960c7..3cbe43ddf384bafd6b6d0608e3643decc34c6b0a 100644 --- a/tests/dummy.py +++ b/tests/dummy.py @@ -5,87 +5,87 @@ from openlobby.core.models import Report, User authors = [ { - 'id': 1, - 'username': 'wolf', - 'first_name': 'Winston', - 'last_name': 'Wolfe', - 'is_author': True, - 'extra': {'movies': 1}, + "id": 1, + "username": "wolf", + "first_name": "Winston", + "last_name": "Wolfe", + "is_author": True, + "extra": {"movies": 1}, }, { - 'id': 2, - 'username': 'sponge', - 'first_name': 'Spongebob', - 'last_name': 'Squarepants', - 'is_author': True, + "id": 2, + "username": "sponge", + "first_name": "Spongebob", + "last_name": "Squarepants", + "is_author": True, }, { - 'id': 3, - 'username': 'shaun', - 'first_name': 'Shaun', - 'last_name': 'Sheep', - 'is_author': True, + "id": 3, + "username": "shaun", + "first_name": "Shaun", + "last_name": "Sheep", + "is_author": True, }, ] reports = [ { - 'id': 1, - 'date': arrow.get(2018, 1, 1).datetime, - 'published': arrow.get(2018, 1, 2).datetime, - 'title': 'The Fellowship of the Ring', - 'body': 'Long story short: we got the Ring!', - 'received_benefit': 'The Ring', - 'provided_benefit': '', - 'our_participants': 'Frodo, Gandalf', - 'other_participants': 'Saruman', + "id": 1, + "date": arrow.get(2018, 1, 1).datetime, + "published": arrow.get(2018, 1, 2).datetime, + "title": "The Fellowship of the Ring", + "body": "Long story short: we got the Ring!", + "received_benefit": "The Ring", + "provided_benefit": "", + "our_participants": "Frodo, Gandalf", + "other_participants": "Saruman", }, { - 'id': 2, - 'date': arrow.get(2018, 1, 3).datetime, - 'published': arrow.get(2018, 1, 4).datetime, - 'title': 'The Two Towers', - 'body': 'Another long story.', - 'received_benefit': 'Mithrill Jacket', - 'provided_benefit': '', - 'our_participants': 'Frodo, Gimli, Legolas', - 'other_participants': 'Saruman, Sauron', - 'extra': {'rings': 1}, + "id": 2, + "date": arrow.get(2018, 1, 3).datetime, + "published": arrow.get(2018, 1, 4).datetime, + "title": "The Two Towers", + "body": "Another long story.", + "received_benefit": "Mithrill Jacket", + "provided_benefit": "", + "our_participants": "Frodo, Gimli, Legolas", + "other_participants": "Saruman, Sauron", + "extra": {"rings": 1}, }, { - 'id': 3, - 'date': arrow.get(2018, 1, 5).datetime, - 'published': arrow.get(2018, 1, 6).datetime, - 'title': 'The Return of the King', - 'body': 'Aragorn is the King. And we have lost the Ring.', - 'received_benefit': '', - 'provided_benefit': 'The Ring', - 'our_participants': 'Aragorn', - 'other_participants': 'Sauron', + "id": 3, + "date": arrow.get(2018, 1, 5).datetime, + "published": arrow.get(2018, 1, 6).datetime, + "title": "The Return of the King", + "body": "Aragorn is the King. And we have lost the Ring.", + "received_benefit": "", + "provided_benefit": "The Ring", + "our_participants": "Aragorn", + "other_participants": "Sauron", }, { - 'id': 4, - 'date': arrow.get(2018, 1, 7).datetime, - 'published': arrow.get(2018, 1, 8).datetime, - 'title': 'The Silmarillion', - 'body': 'Not finished yet.', - 'received_benefit': '', - 'provided_benefit': '', - 'our_participants': '', - 'other_participants': '', - 'is_draft': True, + "id": 4, + "date": arrow.get(2018, 1, 7).datetime, + "published": arrow.get(2018, 1, 8).datetime, + "title": "The Silmarillion", + "body": "Not finished yet.", + "received_benefit": "", + "provided_benefit": "", + "our_participants": "", + "other_participants": "", + "is_draft": True, }, { - 'id': 5, - 'date': arrow.get(2018, 1, 9).datetime, - 'published': arrow.get(2018, 1, 10).datetime, - 'title': 'The Hobbit', - 'body': 'Work in progress...', - 'received_benefit': '', - 'provided_benefit': '', - 'our_participants': '', - 'other_participants': '', - 'is_draft': True, + "id": 5, + "date": arrow.get(2018, 1, 9).datetime, + "published": arrow.get(2018, 1, 10).datetime, + "title": "The Hobbit", + "body": "Work in progress...", + "received_benefit": "", + "provided_benefit": "", + "our_participants": "", + "other_participants": "", + "is_draft": True, }, ] diff --git a/tests/mutations/snapshots/snap_test_create_report.py b/tests/mutations/snapshots/snap_test_create_report.py index 4b33904c5e744101dc6a1f08549d614de449d9fa..b4abeb0b329c49c5aa6161b549a8f8a18179e392 100644 --- a/tests/mutations/snapshots/snap_test_create_report.py +++ b/tests/mutations/snapshots/snap_test_create_report.py @@ -7,72 +7,65 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_unauthorized 1'] = { - 'data': { - 'createReport': None - }, - 'errors': [ +snapshots["test_unauthorized 1"] = { + "data": {"createReport": None}, + "errors": [ { - 'locations': [ - { - 'column': 5, - 'line': 3 - } - ], - 'message': 'User must be logged in to perform this mutation.' + "locations": [{"column": 5, "line": 3}], + "message": "User must be logged in to perform this mutation.", } - ] + ], } -snapshots['test_full_report 1'] = { - 'data': { - 'createReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 1 +snapshots["test_full_report 1"] = { + "data": { + "createReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 1, }, - 'body': 'I visited Tesla factory and talked with Elon Musk.', - 'date': '2018-01-01 00:00:00+00:00', - 'extra': None, - 'id': '__STRIPPED__', - 'isDraft': False, - 'otherParticipants': 'Elon Musk', - 'ourParticipants': 'me', - 'providedBenefit': 'nothing', - 'published': '__STRIPPED__', - 'receivedBenefit': 'Tesla Model S', - 'title': 'Free Tesla' + "body": "I visited Tesla factory and talked with Elon Musk.", + "date": "2018-01-01 00:00:00+00:00", + "extra": None, + "id": "__STRIPPED__", + "isDraft": False, + "otherParticipants": "Elon Musk", + "ourParticipants": "me", + "providedBenefit": "nothing", + "published": "__STRIPPED__", + "receivedBenefit": "Tesla Model S", + "title": "Free Tesla", } } } } -snapshots['test_is_draft 1'] = { - 'data': { - 'createReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 0 +snapshots["test_is_draft 1"] = { + "data": { + "createReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 0, }, - 'body': 'Niel deGrasse Tyson just visited me...', - 'date': '2018-01-03 00:00:00+00:00', - 'extra': None, - 'id': '__STRIPPED__', - 'isDraft': True, - 'otherParticipants': 'Neil deGrasse Tyson', - 'ourParticipants': 'myself', - 'providedBenefit': 'coffee', - 'published': '__STRIPPED__', - 'receivedBenefit': 'touch of the God', - 'title': 'Visited by old friend' + "body": "Niel deGrasse Tyson just visited me...", + "date": "2018-01-03 00:00:00+00:00", + "extra": None, + "id": "__STRIPPED__", + "isDraft": True, + "otherParticipants": "Neil deGrasse Tyson", + "ourParticipants": "myself", + "providedBenefit": "coffee", + "published": "__STRIPPED__", + "receivedBenefit": "touch of the God", + "title": "Visited by old friend", } } } diff --git a/tests/mutations/snapshots/snap_test_login.py b/tests/mutations/snapshots/snap_test_login.py index 8a36af706ac9e7d00be5361a9589e8636245927c..8d93fa0e325843ede1fc3b87d874152fad9c6bfc 100644 --- a/tests/mutations/snapshots/snap_test_login.py +++ b/tests/mutations/snapshots/snap_test_login.py @@ -7,30 +7,18 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_login__known_openid_client 1'] = { - 'userinfo': { - 'email': { - 'essential': True - }, - 'family_name': { - 'essential': True - }, - 'given_name': { - 'essential': True - } +snapshots["test_login__known_openid_client 1"] = { + "userinfo": { + "email": {"essential": True}, + "family_name": {"essential": True}, + "given_name": {"essential": True}, } } -snapshots['test_login__new_openid_client 1'] = { - 'userinfo': { - 'email': { - 'essential': True - }, - 'family_name': { - 'essential': True - }, - 'given_name': { - 'essential': True - } +snapshots["test_login__new_openid_client 1"] = { + "userinfo": { + "email": {"essential": True}, + "family_name": {"essential": True}, + "given_name": {"essential": True}, } } diff --git a/tests/mutations/snapshots/snap_test_login_by_shortcut.py b/tests/mutations/snapshots/snap_test_login_by_shortcut.py index 6fe834f111a4cd7b14863c5eb635217f3b69679a..4e57bd374cfcfff52edf05b4c4ec984b306a6d6f 100644 --- a/tests/mutations/snapshots/snap_test_login_by_shortcut.py +++ b/tests/mutations/snapshots/snap_test_login_by_shortcut.py @@ -7,16 +7,10 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_login_by_shortcut 1'] = { - 'userinfo': { - 'email': { - 'essential': True - }, - 'family_name': { - 'essential': True - }, - 'given_name': { - 'essential': True - } +snapshots["test_login_by_shortcut 1"] = { + "userinfo": { + "email": {"essential": True}, + "family_name": {"essential": True}, + "given_name": {"essential": True}, } } diff --git a/tests/mutations/snapshots/snap_test_update_report.py b/tests/mutations/snapshots/snap_test_update_report.py index b2c4902c0e51f1abea3494e1ca8fd970ab63baad..64eab571f7052579e2372e3e9451e2602149124e 100644 --- a/tests/mutations/snapshots/snap_test_update_report.py +++ b/tests/mutations/snapshots/snap_test_update_report.py @@ -7,177 +7,149 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_unauthorized 1'] = { - 'data': { - 'updateReport': None - }, - 'errors': [ +snapshots["test_unauthorized 1"] = { + "data": {"updateReport": None}, + "errors": [ { - 'locations': [ - { - 'column': 5, - 'line': 3 - } - ], - 'message': 'User must be logged in to perform this mutation.' + "locations": [{"column": 5, "line": 3}], + "message": "User must be logged in to perform this mutation.", } - ] + ], } -snapshots['test_not_author 1'] = { - 'data': { - 'updateReport': None - }, - 'errors': [ +snapshots["test_not_author 1"] = { + "data": {"updateReport": None}, + "errors": [ { - 'locations': [ - { - 'column': 5, - 'line': 3 - } - ], - 'message': 'Viewer is not the Author of this Report or Report does not exist.' + "locations": [{"column": 5, "line": 3}], + "message": "Viewer is not the Author of this Report or Report does not exist.", } - ] + ], } -snapshots['test_report_does_not_exist 1'] = { - 'data': { - 'updateReport': None - }, - 'errors': [ +snapshots["test_report_does_not_exist 1"] = { + "data": {"updateReport": None}, + "errors": [ { - 'locations': [ - { - 'column': 5, - 'line': 3 - } - ], - 'message': 'Viewer is not the Author of this Report or Report does not exist.' + "locations": [{"column": 5, "line": 3}], + "message": "Viewer is not the Author of this Report or Report does not exist.", } - ] + ], } -snapshots['test_update_published_with_draft 1'] = { - 'data': { - 'updateReport': None - }, - 'errors': [ +snapshots["test_update_published_with_draft 1"] = { + "data": {"updateReport": None}, + "errors": [ { - 'locations': [ - { - 'column': 5, - 'line': 3 - } - ], - 'message': 'You cannot update published Report with draft.' + "locations": [{"column": 5, "line": 3}], + "message": "You cannot update published Report with draft.", } - ] + ], } -snapshots['test_update_draft_with_draft 1'] = { - 'data': { - 'updateReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 0 +snapshots["test_update_draft_with_draft 1"] = { + "data": { + "updateReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 0, }, - 'body': 'I visited Tesla factory and talked with Elon Musk.', - 'date': '2018-03-03 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': True, - 'otherParticipants': 'Elon Musk', - 'ourParticipants': 'me', - 'providedBenefit': 'nothing', - 'published': '2018-03-08 00:00:00+00:00', - 'receivedBenefit': 'Tesla Model S', - 'title': 'Free Tesla' + "body": "I visited Tesla factory and talked with Elon Musk.", + "date": "2018-03-03 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": True, + "otherParticipants": "Elon Musk", + "ourParticipants": "me", + "providedBenefit": "nothing", + "published": "2018-03-08 00:00:00+00:00", + "receivedBenefit": "Tesla Model S", + "title": "Free Tesla", } } } } -snapshots['test_update_draft_with_published 1'] = { - 'data': { - 'updateReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 1 +snapshots["test_update_draft_with_published 1"] = { + "data": { + "updateReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 1, }, - 'body': 'I visited Tesla factory and talked with Elon Musk.', - 'date': '2018-03-03 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Elon Musk', - 'ourParticipants': 'me', - 'providedBenefit': 'nothing', - 'published': '2018-03-08 00:00:00+00:00', - 'receivedBenefit': 'Tesla Model S', - 'title': 'Free Tesla' + "body": "I visited Tesla factory and talked with Elon Musk.", + "date": "2018-03-03 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Elon Musk", + "ourParticipants": "me", + "providedBenefit": "nothing", + "published": "2018-03-08 00:00:00+00:00", + "receivedBenefit": "Tesla Model S", + "title": "Free Tesla", } } } } -snapshots['test_update_published_with_published 1'] = { - 'data': { - 'updateReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 1 +snapshots["test_update_published_with_published 1"] = { + "data": { + "updateReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 1, }, - 'body': 'I visited Tesla factory and talked with Elon Musk.', - 'date': '2018-03-03 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Elon Musk', - 'ourParticipants': 'me', - 'providedBenefit': 'nothing', - 'published': '2018-03-08 00:00:00+00:00', - 'receivedBenefit': 'Tesla Model S', - 'title': 'Free Tesla' + "body": "I visited Tesla factory and talked with Elon Musk.", + "date": "2018-03-03 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Elon Musk", + "ourParticipants": "me", + "providedBenefit": "nothing", + "published": "2018-03-08 00:00:00+00:00", + "receivedBenefit": "Tesla Model S", + "title": "Free Tesla", } } } } -snapshots['test_input_sanitization 1'] = { - 'data': { - 'updateReport': { - 'report': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 1 +snapshots["test_input_sanitization 1"] = { + "data": { + "updateReport": { + "report": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 1, }, - 'body': 'some link in body', - 'date': '2018-03-03 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'you!', - 'ourParticipants': 'me, myself', - 'providedBenefit': 'tea', - 'published': '2018-03-08 00:00:00+00:00', - 'receivedBenefit': 'coffee', - 'title': 'No tags' + "body": "some link in body", + "date": "2018-03-03 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "you!", + "ourParticipants": "me, myself", + "providedBenefit": "tea", + "published": "2018-03-08 00:00:00+00:00", + "receivedBenefit": "coffee", + "title": "No tags", } } } diff --git a/tests/mutations/test_create_report.py b/tests/mutations/test_create_report.py index df1837c42062434088bd8cd6c250b9b6c8122d11..32ccbf90394a1c05e66806d422645a046dd2b13e 100644 --- a/tests/mutations/test_create_report.py +++ b/tests/mutations/test_create_report.py @@ -8,7 +8,7 @@ from ..dummy import prepare_author from ..utils import call_api, strip_value -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] query = """ @@ -46,9 +46,9 @@ def setup(): def test_unauthorized(client, snapshot): input = { - 'title': 'Short Story', - 'body': 'I told you!', - 'date': arrow.utcnow().isoformat(), + "title": "Short Story", + "body": "I told you!", + "date": arrow.utcnow().isoformat(), } response = call_api(client, query, input) snapshot.assert_match(response) @@ -56,28 +56,28 @@ def test_unauthorized(client, snapshot): def test_full_report(client, snapshot): date = arrow.get(2018, 1, 1) - title = 'Free Tesla' - body = 'I visited Tesla factory and talked with Elon Musk.' - received_benefit = 'Tesla Model S' - provided_benefit = 'nothing' - our_participants = 'me' - other_participants = 'Elon Musk' + title = "Free Tesla" + body = "I visited Tesla factory and talked with Elon Musk." + received_benefit = "Tesla Model S" + provided_benefit = "nothing" + our_participants = "me" + other_participants = "Elon Musk" input = { - 'title': title, - 'body': body, - 'receivedBenefit': received_benefit, - 'providedBenefit': provided_benefit, - 'ourParticipants': our_participants, - 'otherParticipants': other_participants, - 'date': date.isoformat(), + "title": title, + "body": body, + "receivedBenefit": received_benefit, + "providedBenefit": provided_benefit, + "ourParticipants": our_participants, + "otherParticipants": other_participants, + "date": date.isoformat(), } - response = call_api(client, query, input, 'wolf') + response = call_api(client, query, input, "wolf") - published = strip_value(response, 'data', 'createReport', 'report', 'published') + published = strip_value(response, "data", "createReport", "report", "published") - id = strip_value(response, 'data', 'createReport', 'report', 'id') - assert re.match(r'\w+', id) + id = strip_value(response, "data", "createReport", "report", "id") + assert re.match(r"\w+", id) snapshot.assert_match(response) @@ -97,51 +97,51 @@ def test_full_report(client, snapshot): def test_input_sanitization(client): input = { - 'title': '<s>No</s> tags', - 'body': 'some <a href="http://foo">link</a> <br>in body', - 'receivedBenefit': '<b>coffee</b>', - 'providedBenefit': '<li>tea', - 'ourParticipants': 'me, <u>myself</u>', - 'otherParticipants': '<strong>you!</strong>', - 'date': arrow.utcnow().isoformat(), + "title": "<s>No</s> tags", + "body": 'some <a href="http://foo">link</a> <br>in body', + "receivedBenefit": "<b>coffee</b>", + "providedBenefit": "<li>tea", + "ourParticipants": "me, <u>myself</u>", + "otherParticipants": "<strong>you!</strong>", + "date": arrow.utcnow().isoformat(), } - call_api(client, query, input, 'wolf') + call_api(client, query, input, "wolf") report = Report.objects.get() - assert report.title == 'No tags' - assert report.body == 'some link in body' - assert report.received_benefit == 'coffee' - assert report.provided_benefit == 'tea' - assert report.our_participants == 'me, myself' - assert report.other_participants == 'you!' + assert report.title == "No tags" + assert report.body == "some link in body" + assert report.received_benefit == "coffee" + assert report.provided_benefit == "tea" + assert report.our_participants == "me, myself" + assert report.other_participants == "you!" def test_is_draft(client, snapshot): date = arrow.get(2018, 1, 3) - title = 'Visited by old friend' - body = 'Niel deGrasse Tyson just visited me...' - received_benefit = 'touch of the God' - provided_benefit = 'coffee' - our_participants = 'myself' - other_participants = 'Neil deGrasse Tyson' + title = "Visited by old friend" + body = "Niel deGrasse Tyson just visited me..." + received_benefit = "touch of the God" + provided_benefit = "coffee" + our_participants = "myself" + other_participants = "Neil deGrasse Tyson" input = { - 'title': title, - 'body': body, - 'receivedBenefit': received_benefit, - 'providedBenefit': provided_benefit, - 'ourParticipants': our_participants, - 'otherParticipants': other_participants, - 'date': date.isoformat(), - 'isDraft': True, + "title": title, + "body": body, + "receivedBenefit": received_benefit, + "providedBenefit": provided_benefit, + "ourParticipants": our_participants, + "otherParticipants": other_participants, + "date": date.isoformat(), + "isDraft": True, } - response = call_api(client, query, input, 'wolf') + response = call_api(client, query, input, "wolf") - published = strip_value(response, 'data', 'createReport', 'report', 'published') + published = strip_value(response, "data", "createReport", "report", "published") - id = strip_value(response, 'data', 'createReport', 'report', 'id') - assert re.match(r'\w+', id) + id = strip_value(response, "data", "createReport", "report", "id") + assert re.match(r"\w+", id) snapshot.assert_match(response) diff --git a/tests/mutations/test_login.py b/tests/mutations/test_login.py index 4ea608c5ec2b6808a4b5365d86fba6c81902bd88..fb6f6bc300d91890115daf237c57bdd1436ac503 100644 --- a/tests/mutations/test_login.py +++ b/tests/mutations/test_login.py @@ -15,39 +15,49 @@ pytestmark = pytest.mark.django_db def check_authorization_url(authorization_url, oid_client, state, snapshot): url = urlparse(authorization_url) - url_without_query = urlunparse((url.scheme, url.netloc, url.path, '', '', '')) - assert url_without_query == '{}/protocol/openid-connect/auth'.format(oid_client.issuer) + url_without_query = urlunparse((url.scheme, url.netloc, url.path, "", "", "")) + assert url_without_query == "{}/protocol/openid-connect/auth".format( + oid_client.issuer + ) qs = parse_qs(url.query) - assert qs['client_id'][0] == oid_client.client_id - assert qs['response_type'][0] == 'code' - assert qs['scope'][0] == 'openid' - assert qs['redirect_uri'][0] == 'http://localhost:8010/login-redirect' - assert qs['state'][0] == state - snapshot.assert_match(json.loads(qs['claims'][0])) + assert qs["client_id"][0] == oid_client.client_id + assert qs["response_type"][0] == "code" + assert qs["scope"][0] == "openid" + assert qs["redirect_uri"][0] == "http://localhost:8010/login-redirect" + assert qs["state"][0] == state + snapshot.assert_match(json.loads(qs["claims"][0])) def test_login__known_openid_client(issuer, client, snapshot): oc = register_client(issuer) - oid_client = OpenIdClient.objects.create(name='Test', issuer=issuer, - client_id=oc.client_id, client_secret=oc.client_secret) - - app_redirect_uri = 'http://i.am.pirate' - openid_uid = 'wolf@openid.provider' + oid_client = OpenIdClient.objects.create( + name="Test", + issuer=issuer, + client_id=oc.client_id, + client_secret=oc.client_secret, + ) + + app_redirect_uri = "http://i.am.pirate" + openid_uid = "wolf@openid.provider" query = """ mutation {{ login (input: {{ openidUid: "{uid}", redirectUri: "{uri}" }}) {{ authorizationUrl }} }} - """.format(uid=openid_uid, uri=app_redirect_uri) + """.format( + uid=openid_uid, uri=app_redirect_uri + ) # Keycloak server used for tests does not support issuer discovery by UID, so we mock it - with patch('openlobby.core.api.mutations.discover_issuer', return_value=issuer) as mock: + with patch( + "openlobby.core.api.mutations.discover_issuer", return_value=issuer + ) as mock: response = call_api(client, query) mock.assert_called_once_with(openid_uid) - assert 'errors' not in response - authorization_url = response['data']['login']['authorizationUrl'] + assert "errors" not in response + authorization_url = response["data"]["login"]["authorizationUrl"] la = LoginAttempt.objects.get(openid_client__id=oid_client.id) assert la.app_redirect_uri == app_redirect_uri @@ -57,28 +67,32 @@ def test_login__known_openid_client(issuer, client, snapshot): def test_login__new_openid_client(issuer, client, snapshot): - app_redirect_uri = 'http://i.am.pirate' - openid_uid = 'wolf@openid.provider' + app_redirect_uri = "http://i.am.pirate" + openid_uid = "wolf@openid.provider" query = """ mutation {{ login (input: {{ openidUid: "{uid}", redirectUri: "{uri}" }}) {{ authorizationUrl }} }} - """.format(uid=openid_uid, uri=app_redirect_uri) + """.format( + uid=openid_uid, uri=app_redirect_uri + ) # Keycloak server used for tests does not support issuer discovery by UID, so we mock it - with patch('openlobby.core.api.mutations.discover_issuer', return_value=issuer) as mock: + with patch( + "openlobby.core.api.mutations.discover_issuer", return_value=issuer + ) as mock: response = call_api(client, query) mock.assert_called_once_with(openid_uid) - assert 'errors' not in response - authorization_url = response['data']['login']['authorizationUrl'] + assert "errors" not in response + authorization_url = response["data"]["login"]["authorizationUrl"] oid_client = OpenIdClient.objects.get() assert oid_client.name == issuer assert oid_client.issuer == issuer - assert re.match(r'\w+', oid_client.client_id) - assert re.match(r'\w+', oid_client.client_secret) + assert re.match(r"\w+", oid_client.client_id) + assert re.match(r"\w+", oid_client.client_secret) la = LoginAttempt.objects.get(openid_client__id=oid_client.id) assert la.app_redirect_uri == app_redirect_uri diff --git a/tests/mutations/test_login_by_shortcut.py b/tests/mutations/test_login_by_shortcut.py index 8e9dee4acf9df7481b36fc01e5f4871478db5519..6238aa2952fa5e85cf4bc43c0d290a5e8f29d356 100644 --- a/tests/mutations/test_login_by_shortcut.py +++ b/tests/mutations/test_login_by_shortcut.py @@ -12,21 +12,28 @@ pytestmark = pytest.mark.django_db def test_login_by_shortcut(issuer, client, snapshot): oc = register_client(issuer) - oid_client = OpenIdClient.objects.create(name='Test', is_shortcut=True, - issuer=issuer, client_id=oc.client_id, client_secret=oc.client_secret) - - app_redirect_uri = 'http://i.am.pirate' + oid_client = OpenIdClient.objects.create( + name="Test", + is_shortcut=True, + issuer=issuer, + client_id=oc.client_id, + client_secret=oc.client_secret, + ) + + app_redirect_uri = "http://i.am.pirate" query = """ mutation {{ loginByShortcut (input: {{ shortcutId: "{id}", redirectUri: "{uri}" }}) {{ authorizationUrl }} }} - """.format(id=to_global_id('LoginShortcut', oid_client.id), uri=app_redirect_uri) + """.format( + id=to_global_id("LoginShortcut", oid_client.id), uri=app_redirect_uri + ) response = call_api(client, query) - assert 'errors' not in response - authorization_url = response['data']['loginByShortcut']['authorizationUrl'] + assert "errors" not in response + authorization_url = response["data"]["loginByShortcut"]["authorizationUrl"] la = LoginAttempt.objects.get(openid_client__id=oid_client.id) assert la.app_redirect_uri == app_redirect_uri diff --git a/tests/mutations/test_update_report.py b/tests/mutations/test_update_report.py index 94e9267b0e9f6942d4e9cc8a0898afa3644216d7..3486c5ba59aed8df1d666ed701447342870a09fc 100644 --- a/tests/mutations/test_update_report.py +++ b/tests/mutations/test_update_report.py @@ -9,7 +9,7 @@ from ..dummy import prepare_report from ..utils import call_api -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] query = """ @@ -42,25 +42,25 @@ mutation updateReport ($input: UpdateReportInput!) { published = arrow.get(2018, 3, 8) date = arrow.get(2018, 3, 3) -title = 'Free Tesla' -body = 'I visited Tesla factory and talked with Elon Musk.' -received_benefit = 'Tesla Model S' -provided_benefit = 'nothing' -our_participants = 'me' -other_participants = 'Elon Musk' +title = "Free Tesla" +body = "I visited Tesla factory and talked with Elon Musk." +received_benefit = "Tesla Model S" +provided_benefit = "nothing" +our_participants = "me" +other_participants = "Elon Musk" def get_input(is_draft=False, id=1): return { - 'id': to_global_id('Report', id), - 'title': title, - 'body': body, - 'receivedBenefit': received_benefit, - 'providedBenefit': provided_benefit, - 'ourParticipants': our_participants, - 'otherParticipants': other_participants, - 'date': date.isoformat(), - 'isDraft': is_draft, + "id": to_global_id("Report", id), + "title": title, + "body": body, + "receivedBenefit": received_benefit, + "providedBenefit": provided_benefit, + "ourParticipants": our_participants, + "otherParticipants": other_participants, + "date": date.isoformat(), + "isDraft": is_draft, } @@ -88,31 +88,31 @@ def test_unauthorized(client, snapshot): def test_not_author(client, snapshot): prepare_report() - User.objects.create(id=2, username='hacker') + User.objects.create(id=2, username="hacker") input = get_input() - response = call_api(client, query, input, 'hacker') + response = call_api(client, query, input, "hacker") snapshot.assert_match(response) def test_report_does_not_exist(client, snapshot): prepare_report() input = get_input(id=666) - response = call_api(client, query, input, 'wolf') + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) def test_update_published_with_draft(client, snapshot): prepare_report() input = get_input(is_draft=True) - response = call_api(client, query, input, 'wolf') + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) def test_update_draft_with_draft(client, snapshot): prepare_report(is_draft=True) input = get_input(is_draft=True) - with patch('openlobby.core.api.mutations.arrow.utcnow', return_value=published): - response = call_api(client, query, input, 'wolf') + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) assert_report(is_draft=True) @@ -120,8 +120,8 @@ def test_update_draft_with_draft(client, snapshot): def test_update_draft_with_published(client, snapshot): prepare_report(is_draft=True) input = get_input() - with patch('openlobby.core.api.mutations.arrow.utcnow', return_value=published): - response = call_api(client, query, input, 'wolf') + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) assert_report() @@ -129,8 +129,8 @@ def test_update_draft_with_published(client, snapshot): def test_update_published_with_published(client, snapshot): prepare_report() input = get_input() - with patch('openlobby.core.api.mutations.arrow.utcnow', return_value=published): - response = call_api(client, query, input, 'wolf') + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) assert_report() @@ -138,25 +138,25 @@ def test_update_published_with_published(client, snapshot): def test_input_sanitization(client, snapshot): prepare_report() input = { - 'id': to_global_id('Report', 1), - 'title': '<s>No</s> tags', - 'body': 'some <a href="http://foo">link</a> <br>in body', - 'receivedBenefit': '<b>coffee</b>', - 'providedBenefit': '<li>tea', - 'ourParticipants': 'me, <u>myself</u>', - 'otherParticipants': '<strong>you!</strong>', - 'date': date.isoformat(), + "id": to_global_id("Report", 1), + "title": "<s>No</s> tags", + "body": 'some <a href="http://foo">link</a> <br>in body', + "receivedBenefit": "<b>coffee</b>", + "providedBenefit": "<li>tea", + "ourParticipants": "me, <u>myself</u>", + "otherParticipants": "<strong>you!</strong>", + "date": date.isoformat(), } - with patch('openlobby.core.api.mutations.arrow.utcnow', return_value=published): - response = call_api(client, query, input, 'wolf') + with patch("openlobby.core.api.mutations.arrow.utcnow", return_value=published): + response = call_api(client, query, input, "wolf") snapshot.assert_match(response) report = Report.objects.get() - assert report.title == 'No tags' - assert report.body == 'some link in body' - assert report.received_benefit == 'coffee' - assert report.provided_benefit == 'tea' - assert report.our_participants == 'me, myself' - assert report.other_participants == 'you!' + assert report.title == "No tags" + assert report.body == "some link in body" + assert report.received_benefit == "coffee" + assert report.provided_benefit == "tea" + assert report.our_participants == "me, myself" + assert report.other_participants == "you!" diff --git a/tests/schema/snapshots/snap_test_authors.py b/tests/schema/snapshots/snap_test_authors.py index cf9fba0e09487210dbca4670b052d2d65f9c3fd3..fee760ed81195b6f8e693ca922b91ef1eb1a7e38 100644 --- a/tests/schema/snapshots/snap_test_authors.py +++ b/tests/schema/snapshots/snap_test_authors.py @@ -7,507 +7,496 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_all 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_all 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } + "cursor": "MQ==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } - } + "cursor": "Mw==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_first 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_first 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } + "cursor": "MQ==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mg==', - 'hasNextPage': True, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mg==", + "hasNextPage": True, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_first_after 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_first_after 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, } ], - 'pageInfo': { - 'endCursor': 'Mg==', - 'hasNextPage': True, - 'hasPreviousPage': True, - 'startCursor': 'Mg==' + "pageInfo": { + "endCursor": "Mg==", + "hasNextPage": True, + "hasPreviousPage": True, + "startCursor": "Mg==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_last 1'] = { - 'data': { - 'authors': None - }, - 'errors': [ +snapshots["test_last 1"] = { + "data": {"authors": None}, + "errors": [ { - 'locations': [ - { - 'column': 9, - 'line': 3 - } - ], - 'message': 'Pagination "last" works only in combination with "before" argument.' + "locations": [{"column": 9, "line": 3}], + "message": 'Pagination "last" works only in combination with "before" argument.', } - ] + ], } -snapshots['test_last_before 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_last_before 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, } ], - 'pageInfo': { - 'endCursor': 'Mg==', - 'hasNextPage': True, - 'hasPreviousPage': True, - 'startCursor': 'Mg==' + "pageInfo": { + "endCursor": "Mg==", + "hasNextPage": True, + "hasPreviousPage": True, + "startCursor": "Mg==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_with_reports 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_with_reports 1"] = { + "data": { + "authors": { + "edges": [ { - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'reports': { - 'edges': [ - ], - 'totalCount': 0 - }, - 'totalReports': 0 + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "reports": {"edges": [], "totalCount": 0}, + "totalReports": 0, } }, { - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'reports': { - 'edges': [ + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "reports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'body': 'Another long story.', - 'date': '2018-01-03 00:00:00+00:00', - 'extra': '{"rings": 1}', - 'id': 'UmVwb3J0OjI=', - 'isDraft': False, - 'otherParticipants': 'Saruman, Sauron', - 'ourParticipants': 'Frodo, Gimli, Legolas', - 'providedBenefit': '', - 'published': '2018-01-04 00:00:00+00:00', - 'receivedBenefit': 'Mithrill Jacket', - 'title': 'The Two Towers' - } + "cursor": "MQ==", + "node": { + "body": "Another long story.", + "date": "2018-01-03 00:00:00+00:00", + "extra": '{"rings": 1}', + "id": "UmVwb3J0OjI=", + "isDraft": False, + "otherParticipants": "Saruman, Sauron", + "ourParticipants": "Frodo, Gimli, Legolas", + "providedBenefit": "", + "published": "2018-01-04 00:00:00+00:00", + "receivedBenefit": "Mithrill Jacket", + "title": "The Two Towers", + }, } ], - 'totalCount': 1 + "totalCount": 1, }, - 'totalReports': 1 + "totalReports": 1, } }, { - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'reports': { - 'edges': [ + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "reports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'body': 'Aragorn is the King. And we have lost the Ring.', - 'date': '2018-01-05 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjM=', - 'isDraft': False, - 'otherParticipants': 'Sauron', - 'ourParticipants': 'Aragorn', - 'providedBenefit': 'The Ring', - 'published': '2018-01-06 00:00:00+00:00', - 'receivedBenefit': '', - 'title': 'The Return of the King' - } + "cursor": "MQ==", + "node": { + "body": "Aragorn is the King. And we have lost the Ring.", + "date": "2018-01-05 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjM=", + "isDraft": False, + "otherParticipants": "Sauron", + "ourParticipants": "Aragorn", + "providedBenefit": "The Ring", + "published": "2018-01-06 00:00:00+00:00", + "receivedBenefit": "", + "title": "The Return of the King", + }, }, { - 'cursor': 'Mg==', - 'node': { - 'body': 'Long story short: we got the Ring!', - 'date': '2018-01-01 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Saruman', - 'ourParticipants': 'Frodo, Gandalf', - 'providedBenefit': '', - 'published': '2018-01-02 00:00:00+00:00', - 'receivedBenefit': 'The Ring', - 'title': 'The Fellowship of the Ring' - } - } + "cursor": "Mg==", + "node": { + "body": "Long story short: we got the Ring!", + "date": "2018-01-01 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Saruman", + "ourParticipants": "Frodo, Gandalf", + "providedBenefit": "", + "published": "2018-01-02 00:00:00+00:00", + "receivedBenefit": "The Ring", + "title": "The Fellowship of the Ring", + }, + }, ], - 'totalCount': 2 + "totalCount": 2, }, - 'totalReports': 2 + "totalReports": 2, } - } + }, ] } } } -snapshots['test_sort_by_last_name 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_sort_by_last_name 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } + "cursor": "MQ==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } - } + "cursor": "Mw==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_sort_by_last_name_reversed 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_sort_by_last_name_reversed 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } + "cursor": "MQ==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } - } + "cursor": "Mw==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_sort_by_total_reports 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_sort_by_total_reports 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } + "cursor": "MQ==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } - } + "cursor": "Mw==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_sort_by_total_reports_reversed 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_sort_by_total_reports_reversed 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } + "cursor": "MQ==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } - } + "cursor": "Mw==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_sort_by_default_reversed 1'] = { - 'data': { - 'authors': { - 'edges': [ +snapshots["test_sort_by_default_reversed 1"] = { + "data": { + "authors": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 - } + "cursor": "MQ==", + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, + }, }, { - 'cursor': 'Mg==', - 'node': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 - } + "cursor": "Mg==", + "node": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, + }, }, { - 'cursor': 'Mw==', - 'node': { - 'extra': None, - 'firstName': 'Shaun', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjM=', - 'lastName': 'Sheep', - 'totalReports': 0 - } - } + "cursor": "Mw==", + "node": { + "extra": None, + "firstName": "Shaun", + "hasCollidingName": False, + "id": "QXV0aG9yOjM=", + "lastName": "Sheep", + "totalReports": 0, + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } diff --git a/tests/schema/snapshots/snap_test_login_shortcuts.py b/tests/schema/snapshots/snap_test_login_shortcuts.py index 45cc81f6b986dea6fce412ac8a51a807bc57c7ad..252a4f8a88c43f42909ff3e1aa71db12435dd698 100644 --- a/tests/schema/snapshots/snap_test_login_shortcuts.py +++ b/tests/schema/snapshots/snap_test_login_shortcuts.py @@ -7,20 +7,8 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_returns_only_shortcuts 1'] = { - 'data': { - 'loginShortcuts': [ - { - 'id': 'TG9naW5TaG9ydGN1dDoyMA==', - 'name': 'bar' - } - ] - } +snapshots["test_returns_only_shortcuts 1"] = { + "data": {"loginShortcuts": [{"id": "TG9naW5TaG9ydGN1dDoyMA==", "name": "bar"}]} } -snapshots['test_none 1'] = { - 'data': { - 'loginShortcuts': [ - ] - } -} +snapshots["test_none 1"] = {"data": {"loginShortcuts": []}} diff --git a/tests/schema/snapshots/snap_test_node.py b/tests/schema/snapshots/snap_test_node.py index 018addc9a0cdf7554650be7d7cd9d1e52f746809..91a0da5bbcb43c6c9b611b80b25dc02691ee9c63 100644 --- a/tests/schema/snapshots/snap_test_node.py +++ b/tests/schema/snapshots/snap_test_node.py @@ -7,104 +7,75 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_login_shortcut 1'] = { - 'data': { - 'node': { - 'id': 'TG9naW5TaG9ydGN1dDoxMA==', - 'name': 'foo' - } - } +snapshots["test_login_shortcut 1"] = { + "data": {"node": {"id": "TG9naW5TaG9ydGN1dDoxMA==", "name": "foo"}} } -snapshots['test_author 1'] = { - 'data': { - 'node': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 +snapshots["test_author 1"] = { + "data": { + "node": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, } } } -snapshots['test_author__returns_only_if_is_author 1'] = { - 'data': { - 'node': None - } -} +snapshots["test_author__returns_only_if_is_author 1"] = {"data": {"node": None}} -snapshots['test_report 1'] = { - 'data': { - 'node': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 +snapshots["test_report 1"] = { + "data": { + "node": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, }, - 'body': 'Long story short: we got the Ring!', - 'date': '2018-01-01 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Saruman', - 'ourParticipants': 'Frodo, Gandalf', - 'providedBenefit': '', - 'published': '2018-01-02 00:00:00+00:00', - 'receivedBenefit': 'The Ring', - 'title': 'The Fellowship of the Ring' + "body": "Long story short: we got the Ring!", + "date": "2018-01-01 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Saruman", + "ourParticipants": "Frodo, Gandalf", + "providedBenefit": "", + "published": "2018-01-02 00:00:00+00:00", + "receivedBenefit": "The Ring", + "title": "The Fellowship of the Ring", } } } -snapshots['test_user__unauthorized 1'] = { - 'data': { - 'node': None - } -} +snapshots["test_user__unauthorized 1"] = {"data": {"node": None}} -snapshots['test_user__not_a_viewer 1'] = { - 'data': { - 'node': None - } -} +snapshots["test_user__not_a_viewer 1"] = {"data": {"node": None}} -snapshots['test_user 1'] = { - 'data': { - 'node': { - 'extra': '{"e": "mc2"}', - 'firstName': 'Albert', - 'hasCollidingName': False, - 'id': 'VXNlcjo4', - 'isAuthor': False, - 'lastName': 'Einstein', - 'openidUid': 'albert@einstein.id' +snapshots["test_user 1"] = { + "data": { + "node": { + "extra": '{"e": "mc2"}', + "firstName": "Albert", + "hasCollidingName": False, + "id": "VXNlcjo4", + "isAuthor": False, + "lastName": "Einstein", + "openidUid": "albert@einstein.id", } } } -snapshots['test_report__is_draft__unauthorized_viewer 1'] = { - 'data': { - 'node': None - } -} +snapshots["test_report__is_draft__unauthorized_viewer 1"] = {"data": {"node": None}} -snapshots['test_report__is_draft__viewer_is_not_author 1'] = { - 'data': { - 'node': None - } -} +snapshots["test_report__is_draft__viewer_is_not_author 1"] = {"data": {"node": None}} -snapshots['test_report__is_draft 1'] = { - 'data': { - 'node': { - 'id': 'UmVwb3J0OjQ=', - 'isDraft': True, - 'title': 'The Silmarillion' - } +snapshots["test_report__is_draft 1"] = { + "data": { + "node": {"id": "UmVwb3J0OjQ=", "isDraft": True, "title": "The Silmarillion"} } } diff --git a/tests/schema/snapshots/snap_test_report_drafts.py b/tests/schema/snapshots/snap_test_report_drafts.py index a589b1b002c61b060e475fe6502660e652c2835c..1106c70e57b89e78676c395306c2effbae3912a3 100644 --- a/tests/schema/snapshots/snap_test_report_drafts.py +++ b/tests/schema/snapshots/snap_test_report_drafts.py @@ -7,27 +7,22 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_unauthenticated 1'] = { - 'data': { - 'reportDrafts': [ - ] - } -} +snapshots["test_unauthenticated 1"] = {"data": {"reportDrafts": []}} -snapshots['test_authenticated 1'] = { - 'data': { - 'reportDrafts': [ +snapshots["test_authenticated 1"] = { + "data": { + "reportDrafts": [ { - 'body': 'Not finished yet.', - 'date': '2018-01-07 00:00:00+00:00', - 'id': 'UmVwb3J0OjQ=', - 'isDraft': True, - 'otherParticipants': '', - 'ourParticipants': '', - 'providedBenefit': '', - 'published': '2018-01-08 00:00:00+00:00', - 'receivedBenefit': '', - 'title': 'The Silmarillion' + "body": "Not finished yet.", + "date": "2018-01-07 00:00:00+00:00", + "id": "UmVwb3J0OjQ=", + "isDraft": True, + "otherParticipants": "", + "ourParticipants": "", + "providedBenefit": "", + "published": "2018-01-08 00:00:00+00:00", + "receivedBenefit": "", + "title": "The Silmarillion", } ] } diff --git a/tests/schema/snapshots/snap_test_search_reports.py b/tests/schema/snapshots/snap_test_search_reports.py index ef7aaa956987b600455a896fc2e37defeb17a700..b0c0e30482c93afca389f9729aa922f341454aaa 100644 --- a/tests/schema/snapshots/snap_test_search_reports.py +++ b/tests/schema/snapshots/snap_test_search_reports.py @@ -7,268 +7,252 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_all 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_all 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 + "cursor": "MQ==", + "node": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, }, - 'body': 'Aragorn is the King. And we have lost the Ring.', - 'date': '2018-01-05 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjM=', - 'isDraft': False, - 'otherParticipants': 'Sauron', - 'ourParticipants': 'Aragorn', - 'providedBenefit': 'The Ring', - 'published': '2018-01-06 00:00:00+00:00', - 'receivedBenefit': '', - 'title': 'The Return of the King' - } + "body": "Aragorn is the King. And we have lost the Ring.", + "date": "2018-01-05 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjM=", + "isDraft": False, + "otherParticipants": "Sauron", + "ourParticipants": "Aragorn", + "providedBenefit": "The Ring", + "published": "2018-01-06 00:00:00+00:00", + "receivedBenefit": "", + "title": "The Return of the King", + }, }, { - 'cursor': 'Mg==', - 'node': { - 'author': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 + "cursor": "Mg==", + "node": { + "author": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, }, - 'body': 'Another long story.', - 'date': '2018-01-03 00:00:00+00:00', - 'extra': '{"rings": 1}', - 'id': 'UmVwb3J0OjI=', - 'isDraft': False, - 'otherParticipants': 'Saruman, Sauron', - 'ourParticipants': 'Frodo, Gimli, Legolas', - 'providedBenefit': '', - 'published': '2018-01-04 00:00:00+00:00', - 'receivedBenefit': 'Mithrill Jacket', - 'title': 'The Two Towers' - } + "body": "Another long story.", + "date": "2018-01-03 00:00:00+00:00", + "extra": '{"rings": 1}', + "id": "UmVwb3J0OjI=", + "isDraft": False, + "otherParticipants": "Saruman, Sauron", + "ourParticipants": "Frodo, Gimli, Legolas", + "providedBenefit": "", + "published": "2018-01-04 00:00:00+00:00", + "receivedBenefit": "Mithrill Jacket", + "title": "The Two Towers", + }, }, { - 'cursor': 'Mw==', - 'node': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 + "cursor": "Mw==", + "node": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, }, - 'body': 'Long story short: we got the Ring!', - 'date': '2018-01-01 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Saruman', - 'ourParticipants': 'Frodo, Gandalf', - 'providedBenefit': '', - 'published': '2018-01-02 00:00:00+00:00', - 'receivedBenefit': 'The Ring', - 'title': 'The Fellowship of the Ring' - } - } + "body": "Long story short: we got the Ring!", + "date": "2018-01-01 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Saruman", + "ourParticipants": "Frodo, Gandalf", + "providedBenefit": "", + "published": "2018-01-02 00:00:00+00:00", + "receivedBenefit": "The Ring", + "title": "The Fellowship of the Ring", + }, + }, ], - 'pageInfo': { - 'endCursor': 'Mw==', - 'hasNextPage': False, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "Mw==", + "hasNextPage": False, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_query 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_query 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'author': { - 'extra': None, - 'firstName': 'Spongebob', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjI=', - 'lastName': 'Squarepants', - 'totalReports': 1 + "cursor": "MQ==", + "node": { + "author": { + "extra": None, + "firstName": "Spongebob", + "hasCollidingName": False, + "id": "QXV0aG9yOjI=", + "lastName": "Squarepants", + "totalReports": 1, }, - 'body': 'Another long story.', - 'date': '2018-01-03 00:00:00+00:00', - 'extra': '{"rings": 1}', - 'id': 'UmVwb3J0OjI=', - 'isDraft': False, - 'otherParticipants': 'Saruman, Sauron', - 'ourParticipants': 'Frodo, Gimli, Legolas', - 'providedBenefit': '', - 'published': '2018-01-04 00:00:00+00:00', - 'receivedBenefit': 'Mithrill Jacket', - 'title': 'The Two Towers' - } + "body": "Another long story.", + "date": "2018-01-03 00:00:00+00:00", + "extra": '{"rings": 1}', + "id": "UmVwb3J0OjI=", + "isDraft": False, + "otherParticipants": "Saruman, Sauron", + "ourParticipants": "Frodo, Gimli, Legolas", + "providedBenefit": "", + "published": "2018-01-04 00:00:00+00:00", + "receivedBenefit": "Mithrill Jacket", + "title": "The Two Towers", + }, } ], - 'totalCount': 1 + "totalCount": 1, } } } -snapshots['test_highlight 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_highlight 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 + "cursor": "MQ==", + "node": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, }, - 'body': 'Aragorn is the King. And we have lost the <mark>Ring</mark>.', - 'date': '2018-01-05 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjM=', - 'isDraft': False, - 'otherParticipants': 'Sauron', - 'ourParticipants': 'Aragorn', - 'providedBenefit': 'The <mark>Ring</mark>', - 'published': '2018-01-06 00:00:00+00:00', - 'receivedBenefit': '', - 'title': 'The Return of the King' - } + "body": "Aragorn is the King. And we have lost the <mark>Ring</mark>.", + "date": "2018-01-05 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjM=", + "isDraft": False, + "otherParticipants": "Sauron", + "ourParticipants": "Aragorn", + "providedBenefit": "The <mark>Ring</mark>", + "published": "2018-01-06 00:00:00+00:00", + "receivedBenefit": "", + "title": "The Return of the King", + }, }, { - 'cursor': 'Mg==', - 'node': { - 'author': { - 'extra': '{"movies": 1}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'QXV0aG9yOjE=', - 'lastName': 'Wolfe', - 'totalReports': 2 + "cursor": "Mg==", + "node": { + "author": { + "extra": '{"movies": 1}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "QXV0aG9yOjE=", + "lastName": "Wolfe", + "totalReports": 2, }, - 'body': 'Long story short: we got the <mark>Ring</mark>!', - 'date': '2018-01-01 00:00:00+00:00', - 'extra': None, - 'id': 'UmVwb3J0OjE=', - 'isDraft': False, - 'otherParticipants': 'Saruman', - 'ourParticipants': 'Frodo, Gandalf', - 'providedBenefit': '', - 'published': '2018-01-02 00:00:00+00:00', - 'receivedBenefit': 'The <mark>Ring</mark>', - 'title': 'The Fellowship of the <mark>Ring</mark>' - } - } + "body": "Long story short: we got the <mark>Ring</mark>!", + "date": "2018-01-01 00:00:00+00:00", + "extra": None, + "id": "UmVwb3J0OjE=", + "isDraft": False, + "otherParticipants": "Saruman", + "ourParticipants": "Frodo, Gandalf", + "providedBenefit": "", + "published": "2018-01-02 00:00:00+00:00", + "receivedBenefit": "The <mark>Ring</mark>", + "title": "The Fellowship of the <mark>Ring</mark>", + }, + }, ], - 'totalCount': 2 + "totalCount": 2, } } } -snapshots['test_first 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_first 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'MQ==', - 'node': { - 'id': 'UmVwb3J0OjM=', - 'title': 'The Return of the King' - } + "cursor": "MQ==", + "node": {"id": "UmVwb3J0OjM=", "title": "The Return of the King"}, } ], - 'pageInfo': { - 'endCursor': 'MQ==', - 'hasNextPage': True, - 'hasPreviousPage': False, - 'startCursor': 'MQ==' + "pageInfo": { + "endCursor": "MQ==", + "hasNextPage": True, + "hasPreviousPage": False, + "startCursor": "MQ==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_first_after 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_first_after 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'Mg==', - 'node': { - 'id': 'UmVwb3J0OjI=', - 'title': 'The Two Towers' - } + "cursor": "Mg==", + "node": {"id": "UmVwb3J0OjI=", "title": "The Two Towers"}, } ], - 'pageInfo': { - 'endCursor': 'Mg==', - 'hasNextPage': True, - 'hasPreviousPage': True, - 'startCursor': 'Mg==' + "pageInfo": { + "endCursor": "Mg==", + "hasNextPage": True, + "hasPreviousPage": True, + "startCursor": "Mg==", }, - 'totalCount': 3 + "totalCount": 3, } } } -snapshots['test_last 1'] = { - 'data': { - 'searchReports': None - }, - 'errors': [ +snapshots["test_last 1"] = { + "data": {"searchReports": None}, + "errors": [ { - 'locations': [ - { - 'column': 9, - 'line': 3 - } - ], - 'message': 'Pagination "last" works only in combination with "before" argument.' + "locations": [{"column": 9, "line": 3}], + "message": 'Pagination "last" works only in combination with "before" argument.', } - ] + ], } -snapshots['test_last_before 1'] = { - 'data': { - 'searchReports': { - 'edges': [ +snapshots["test_last_before 1"] = { + "data": { + "searchReports": { + "edges": [ { - 'cursor': 'Mg==', - 'node': { - 'id': 'UmVwb3J0OjI=', - 'title': 'The Two Towers' - } + "cursor": "Mg==", + "node": {"id": "UmVwb3J0OjI=", "title": "The Two Towers"}, } ], - 'pageInfo': { - 'endCursor': 'Mg==', - 'hasNextPage': True, - 'hasPreviousPage': True, - 'startCursor': 'Mg==' + "pageInfo": { + "endCursor": "Mg==", + "hasNextPage": True, + "hasPreviousPage": True, + "startCursor": "Mg==", }, - 'totalCount': 3 + "totalCount": 3, } } } diff --git a/tests/schema/snapshots/snap_test_viewer.py b/tests/schema/snapshots/snap_test_viewer.py index fb88edfc1557b7f419ab91d39a872731cc332863..326a64bdc6a7d9c6726f34aa01b973b34fafe144 100644 --- a/tests/schema/snapshots/snap_test_viewer.py +++ b/tests/schema/snapshots/snap_test_viewer.py @@ -7,45 +7,27 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_unauthenticated 1'] = { - 'data': { - 'viewer': None - } -} - -snapshots['test_authenticated 1'] = { - 'data': { - 'viewer': { - 'email': 'winston@wolfe.com', - 'extra': '{"caliber": 45}', - 'firstName': 'Winston', - 'hasCollidingName': False, - 'id': 'VXNlcjox', - 'isAuthor': True, - 'lastName': 'Wolfe', - 'openidUid': 'TheWolf' +snapshots["test_unauthenticated 1"] = {"data": {"viewer": None}} + +snapshots["test_authenticated 1"] = { + "data": { + "viewer": { + "email": "winston@wolfe.com", + "extra": '{"caliber": 45}', + "firstName": "Winston", + "hasCollidingName": False, + "id": "VXNlcjox", + "isAuthor": True, + "lastName": "Wolfe", + "openidUid": "TheWolf", } } } -snapshots['test_wrong_header 1'] = { - 'errors': [ - { - 'message': 'Wrong Authorization header. Expected: "Bearer <token>"' - } - ] +snapshots["test_wrong_header 1"] = { + "errors": [{"message": 'Wrong Authorization header. Expected: "Bearer <token>"'}] } -snapshots['test_wrong_token 1'] = { - 'errors': [ - { - 'message': 'Invalid Token.' - } - ] -} +snapshots["test_wrong_token 1"] = {"errors": [{"message": "Invalid Token."}]} -snapshots['test_unknown_user 1'] = { - 'data': { - 'viewer': None - } -} +snapshots["test_unknown_user 1"] = {"data": {"viewer": None}} diff --git a/tests/schema/test_authors.py b/tests/schema/test_authors.py index 5c59a37386187dff0949ef7bb8dedee57d827897..3d4bb07a7a857f0b383e7da94cba8c6dd01d3066 100644 --- a/tests/schema/test_authors.py +++ b/tests/schema/test_authors.py @@ -6,12 +6,12 @@ from ..dummy import prepare_reports from ..utils import call_api -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] def test_all(client, snapshot): prepare_reports() - User.objects.create(id=4, is_author=False, username='x') + User.objects.create(id=4, is_author=False, username="x") query = """ query { authors { @@ -200,6 +200,7 @@ def test_with_reports(client, snapshot): response = call_api(client, query) snapshot.assert_match(response) + def test_sort_by_last_name(client, snapshot): prepare_reports() query = """ @@ -229,6 +230,7 @@ def test_sort_by_last_name(client, snapshot): response = call_api(client, query) snapshot.assert_match(response) + def test_sort_by_last_name_reversed(client, snapshot): prepare_reports() query = """ @@ -258,6 +260,7 @@ def test_sort_by_last_name_reversed(client, snapshot): response = call_api(client, query) snapshot.assert_match(response) + def test_sort_by_total_reports(client, snapshot): prepare_reports() query = """ @@ -287,6 +290,7 @@ def test_sort_by_total_reports(client, snapshot): response = call_api(client, query) snapshot.assert_match(response) + def test_sort_by_total_reports_reversed(client, snapshot): prepare_reports() query = """ @@ -316,6 +320,7 @@ def test_sort_by_total_reports_reversed(client, snapshot): response = call_api(client, query) snapshot.assert_match(response) + def test_sort_by_default_reversed(client, snapshot): prepare_reports() query = """ @@ -343,4 +348,4 @@ def test_sort_by_default_reversed(client, snapshot): } """ response = call_api(client, query) - snapshot.assert_match(response) \ No newline at end of file + snapshot.assert_match(response) diff --git a/tests/schema/test_login_shortcuts.py b/tests/schema/test_login_shortcuts.py index 2b0ad968eb6ccffe8a6da89c099ac21cb2fc3174..4ec90abd615e15c5cc1b12c35e9cdfc831e2212f 100644 --- a/tests/schema/test_login_shortcuts.py +++ b/tests/schema/test_login_shortcuts.py @@ -9,8 +9,8 @@ pytestmark = pytest.mark.django_db def test_returns_only_shortcuts(client, snapshot): - OpenIdClient.objects.create(id=10, name='foo', issuer='foo') - OpenIdClient.objects.create(id=20, name='bar', issuer='bar', is_shortcut=True) + OpenIdClient.objects.create(id=10, name="foo", issuer="foo") + OpenIdClient.objects.create(id=20, name="bar", issuer="bar", is_shortcut=True) query = """ query { loginShortcuts { @@ -24,7 +24,7 @@ def test_returns_only_shortcuts(client, snapshot): def test_none(client, snapshot): - OpenIdClient.objects.create(id=10, name='foo') + OpenIdClient.objects.create(id=10, name="foo") query = """ query { loginShortcuts { diff --git a/tests/schema/test_node.py b/tests/schema/test_node.py index 6a42cb509207607c73355a05d332f7e707ae2d48..f13de1239c25b1b3de54b82906df11b18fd179d9 100644 --- a/tests/schema/test_node.py +++ b/tests/schema/test_node.py @@ -7,11 +7,11 @@ from ..dummy import prepare_reports from ..utils import call_api -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] def test_login_shortcut(client, snapshot): - OpenIdClient.objects.create(id=10, name='foo', issuer='foo', is_shortcut=True) + OpenIdClient.objects.create(id=10, name="foo", issuer="foo", is_shortcut=True) query = """ query {{ node (id:"{id}") {{ @@ -21,7 +21,9 @@ def test_login_shortcut(client, snapshot): }} }} }} - """.format(id=to_global_id('LoginShortcut', 10)) + """.format( + id=to_global_id("LoginShortcut", 10) + ) response = call_api(client, query) snapshot.assert_match(response) @@ -41,7 +43,9 @@ def test_author(client, snapshot): }} }} }} - """.format(id=to_global_id('Author', 1)) + """.format( + id=to_global_id("Author", 1) + ) response = call_api(client, query) snapshot.assert_match(response) @@ -56,7 +60,9 @@ def test_author__returns_only_if_is_author(client, snapshot): }} }} }} - """.format(id=to_global_id('Author', 7)) + """.format( + id=to_global_id("Author", 7) + ) response = call_api(client, query) snapshot.assert_match(response) @@ -89,7 +95,9 @@ def test_report(client, snapshot): }} }} }} - """.format(id=to_global_id('Report', 1)) + """.format( + id=to_global_id("Report", 1) + ) response = call_api(client, query) snapshot.assert_match(response) @@ -106,8 +114,10 @@ def test_report__is_draft(client, snapshot): }} }} }} - """.format(id=to_global_id('Report', 4)) - response = call_api(client, query, username='wolf') + """.format( + id=to_global_id("Report", 4) + ) + response = call_api(client, query, username="wolf") snapshot.assert_match(response) @@ -123,7 +133,9 @@ def test_report__is_draft__unauthorized_viewer(client, snapshot): }} }} }} - """.format(id=to_global_id('Report', 4)) + """.format( + id=to_global_id("Report", 4) + ) response = call_api(client, query) snapshot.assert_match(response) @@ -140,14 +152,22 @@ def test_report__is_draft__viewer_is_not_author(client, snapshot): }} }} }} - """.format(id=to_global_id('Report', 4)) - response = call_api(client, query, username='spongebob') + """.format( + id=to_global_id("Report", 4) + ) + response = call_api(client, query, username="spongebob") snapshot.assert_match(response) def test_user__unauthorized(client, snapshot): - User.objects.create(id=8, username='albert', openid_uid='albert@einstein.id', - first_name='Albert', last_name='Einstein', extra={'e': 'mc2'}) + User.objects.create( + id=8, + username="albert", + openid_uid="albert@einstein.id", + first_name="Albert", + last_name="Einstein", + extra={"e": "mc2"}, + ) query = """ query {{ node (id:"{id}") {{ @@ -162,16 +182,30 @@ def test_user__unauthorized(client, snapshot): }} }} }} - """.format(id=to_global_id('User', 8)) + """.format( + id=to_global_id("User", 8) + ) response = call_api(client, query) snapshot.assert_match(response) def test_user__not_a_viewer(client, snapshot): - User.objects.create(id=8, username='albert', openid_uid='albert@einstein.id', - first_name='Albert', last_name='Einstein', extra={'e': 'mc2'}) - User.objects.create(id=2, username='isaac', openid_uid='isaac@newton.id', - first_name='Isaac', last_name='Newton', extra={'apple': 'hit'}) + User.objects.create( + id=8, + username="albert", + openid_uid="albert@einstein.id", + first_name="Albert", + last_name="Einstein", + extra={"e": "mc2"}, + ) + User.objects.create( + id=2, + username="isaac", + openid_uid="isaac@newton.id", + first_name="Isaac", + last_name="Newton", + extra={"apple": "hit"}, + ) query = """ query {{ node (id:"{id}") {{ @@ -186,14 +220,22 @@ def test_user__not_a_viewer(client, snapshot): }} }} }} - """.format(id=to_global_id('User', 8)) - response = call_api(client, query, username='isaac') + """.format( + id=to_global_id("User", 8) + ) + response = call_api(client, query, username="isaac") snapshot.assert_match(response) def test_user(client, snapshot): - User.objects.create(id=8, username='albert', openid_uid='albert@einstein.id', - first_name='Albert', last_name='Einstein', extra={'e': 'mc2'}) + User.objects.create( + id=8, + username="albert", + openid_uid="albert@einstein.id", + first_name="Albert", + last_name="Einstein", + extra={"e": "mc2"}, + ) query = """ query {{ node (id:"{id}") {{ @@ -208,6 +250,8 @@ def test_user(client, snapshot): }} }} }} - """.format(id=to_global_id('User', 8)) - response = call_api(client, query, username='albert') + """.format( + id=to_global_id("User", 8) + ) + response = call_api(client, query, username="albert") snapshot.assert_match(response) diff --git a/tests/schema/test_report_drafts.py b/tests/schema/test_report_drafts.py index 81898755a2bff62ffdccc45fc63c85f8ddb0b680..013f6dab0c1b5e65ce06eb338f3ce830a94a8a3c 100644 --- a/tests/schema/test_report_drafts.py +++ b/tests/schema/test_report_drafts.py @@ -4,7 +4,7 @@ from ..dummy import prepare_reports from ..utils import call_api -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] def test_unauthenticated(client, snapshot): @@ -38,5 +38,5 @@ def test_authenticated(client, snapshot): } } """ - response = call_api(client, query, username='wolf') + response = call_api(client, query, username="wolf") snapshot.assert_match(response) diff --git a/tests/schema/test_search_reports.py b/tests/schema/test_search_reports.py index 4da763b95db5203a1a302fee74f69b67079536d7..68cbd11e76d8416281597cf1adbee8447c9df415 100644 --- a/tests/schema/test_search_reports.py +++ b/tests/schema/test_search_reports.py @@ -4,7 +4,7 @@ from ..dummy import prepare_reports from ..utils import call_api -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] def test_all(client, snapshot): diff --git a/tests/schema/test_viewer.py b/tests/schema/test_viewer.py index 3895debd1ea53ba632191471810acc7f99348912..1255eff15f9147a4f5585bc3bb765e8a24a638b9 100644 --- a/tests/schema/test_viewer.py +++ b/tests/schema/test_viewer.py @@ -11,9 +11,16 @@ pytestmark = pytest.mark.django_db @pytest.fixture(autouse=True) def setup(): - User.objects.create(id=1, is_author=True, username='wolf', openid_uid='TheWolf', - first_name='Winston', last_name='Wolfe', email='winston@wolfe.com', - extra={'caliber': 45}) + User.objects.create( + id=1, + is_author=True, + username="wolf", + openid_uid="TheWolf", + first_name="Winston", + last_name="Wolfe", + email="winston@wolfe.com", + extra={"caliber": 45}, + ) def test_unauthenticated(client, snapshot): @@ -43,46 +50,65 @@ def test_authenticated(client, snapshot): } } """ - response = call_api(client, query, username='wolf') + response = call_api(client, query, username="wolf") snapshot.assert_match(response) # integration tests of wrong authentication + def test_wrong_header(client, snapshot): - token = create_access_token('wolfe') - auth_header = 'WRONG {}'.format(token) - res = client.post('/graphql', {'query': """ + token = create_access_token("wolfe") + auth_header = "WRONG {}".format(token) + res = client.post( + "/graphql", + { + "query": """ query { viewer { id } } - """}, HTTP_AUTHORIZATION=auth_header) + """ + }, + HTTP_AUTHORIZATION=auth_header, + ) snapshot.assert_match(res.json()) def test_wrong_token(client, snapshot): - token = create_access_token('wolfe') - auth_header = 'Bearer XXX{}'.format(token) - res = client.post('/graphql', {'query': """ + token = create_access_token("wolfe") + auth_header = "Bearer XXX{}".format(token) + res = client.post( + "/graphql", + { + "query": """ query { viewer { id } } - """}, HTTP_AUTHORIZATION=auth_header) + """ + }, + HTTP_AUTHORIZATION=auth_header, + ) snapshot.assert_match(res.json()) def test_unknown_user(client, snapshot): - token = create_access_token('unknown') - auth_header = 'Bearer {}'.format(token) - res = client.post('/graphql', {'query': """ + token = create_access_token("unknown") + auth_header = "Bearer {}".format(token) + res = client.post( + "/graphql", + { + "query": """ query { viewer { id } } - """}, HTTP_AUTHORIZATION=auth_header) + """ + }, + HTTP_AUTHORIZATION=auth_header, + ) snapshot.assert_match(res.json()) diff --git a/tests/snapshots/snap_test_management.py b/tests/snapshots/snap_test_management.py index ff10ca76366130dd48abf3d4828fa3acb96a314b..5cf4f3f010765d0c0c6232adf25df8487c393c1f 100644 --- a/tests/snapshots/snap_test_management.py +++ b/tests/snapshots/snap_test_management.py @@ -7,325 +7,159 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_create_index__check_analysis_settings 1'] = { - 'analyzer': { - 'czech': { - 'filter': [ - 'icu_folding', - 'lowercase', - 'czech_synonym', - 'czech_stop', - 'czech_stemmer', - 'cs_CZ' +snapshots["test_create_index__check_analysis_settings 1"] = { + "analyzer": { + "czech": { + "filter": [ + "icu_folding", + "lowercase", + "czech_synonym", + "czech_stop", + "czech_stemmer", + "cs_CZ", ], - 'tokenizer': 'standard' + "tokenizer": "standard", } }, - 'filter': { - 'cs_CZ': { - 'dedup': 'true', - 'locale': 'cs_CZ', - 'type': 'hunspell' + "filter": { + "cs_CZ": {"dedup": "true", "locale": "cs_CZ", "type": "hunspell"}, + "czech_stemmer": {"language": "czech", "type": "stemmer"}, + "czech_stop": {"stopwords": "_czech_", "type": "stop"}, + "czech_synonym": { + "synonyms_path": "analysis/cs_CZ/synonym.txt", + "type": "synonym", }, - 'czech_stemmer': { - 'language': 'czech', - 'type': 'stemmer' - }, - 'czech_stop': { - 'stopwords': '_czech_', - 'type': 'stop' - }, - 'czech_synonym': { - 'synonyms_path': 'analysis/cs_CZ/synonym.txt', - 'type': 'synonym' - } - } + }, } -snapshots['test_create_index__check_mappings 1'] = { - 'mappings': { - 'report': { - 'properties': { - 'author_id': { - 'type': 'keyword' - }, - 'body': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'date': { - 'type': 'date' - }, - 'extra': { - 'type': 'object' - }, - 'other_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'our_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'provided_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'published': { - 'type': 'date' - }, - 'received_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'title': { - 'analyzer': 'czech', - 'type': 'text' - } +snapshots["test_create_index__check_mappings 1"] = { + "mappings": { + "report": { + "properties": { + "author_id": {"type": "keyword"}, + "body": {"analyzer": "czech", "type": "text"}, + "date": {"type": "date"}, + "extra": {"type": "object"}, + "other_participants": {"analyzer": "czech", "type": "text"}, + "our_participants": {"analyzer": "czech", "type": "text"}, + "provided_benefit": {"analyzer": "czech", "type": "text"}, + "published": {"type": "date"}, + "received_benefit": {"analyzer": "czech", "type": "text"}, + "title": {"analyzer": "czech", "type": "text"}, } }, - 'session': { - 'properties': { - 'expiration': { - 'type': 'integer' - }, - 'user_id': { - 'type': 'keyword' - } + "session": { + "properties": { + "expiration": {"type": "integer"}, + "user_id": {"type": "keyword"}, } }, - 'user': { - 'properties': { - 'email': { - 'type': 'keyword' - }, - 'extra': { - 'type': 'object' - }, - 'name': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'openid_uid': { - 'type': 'keyword' - } + "user": { + "properties": { + "email": {"type": "keyword"}, + "extra": {"type": "object"}, + "name": {"analyzer": "czech", "type": "text"}, + "openid_uid": {"type": "keyword"}, } - } + }, } } -snapshots['test_init_alias 1'] = { - 'mappings': { - 'report': { - 'properties': { - 'author_id': { - 'type': 'keyword' - }, - 'body': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'date': { - 'type': 'date' - }, - 'extra': { - 'type': 'object' - }, - 'other_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'our_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'provided_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'published': { - 'type': 'date' - }, - 'received_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'title': { - 'analyzer': 'czech', - 'type': 'text' - } +snapshots["test_init_alias 1"] = { + "mappings": { + "report": { + "properties": { + "author_id": {"type": "keyword"}, + "body": {"analyzer": "czech", "type": "text"}, + "date": {"type": "date"}, + "extra": {"type": "object"}, + "other_participants": {"analyzer": "czech", "type": "text"}, + "our_participants": {"analyzer": "czech", "type": "text"}, + "provided_benefit": {"analyzer": "czech", "type": "text"}, + "published": {"type": "date"}, + "received_benefit": {"analyzer": "czech", "type": "text"}, + "title": {"analyzer": "czech", "type": "text"}, } }, - 'session': { - 'properties': { - 'expiration': { - 'type': 'integer' - }, - 'user_id': { - 'type': 'keyword' - } + "session": { + "properties": { + "expiration": {"type": "integer"}, + "user_id": {"type": "keyword"}, } }, - 'user': { - 'properties': { - 'email': { - 'type': 'keyword' - }, - 'extra': { - 'type': 'object' - }, - 'name': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'openid_uid': { - 'type': 'keyword' - } + "user": { + "properties": { + "email": {"type": "keyword"}, + "extra": {"type": "object"}, + "name": {"analyzer": "czech", "type": "text"}, + "openid_uid": {"type": "keyword"}, } - } + }, } } -snapshots['test_reindex__check_new_index 1'] = { - 'mappings': { - 'report': { - 'properties': { - 'author_id': { - 'type': 'keyword' - }, - 'body': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'date': { - 'type': 'date' - }, - 'extra': { - 'type': 'object' - }, - 'other_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'our_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'provided_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'published': { - 'type': 'date' - }, - 'received_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'title': { - 'analyzer': 'czech', - 'type': 'text' - } +snapshots["test_reindex__check_new_index 1"] = { + "mappings": { + "report": { + "properties": { + "author_id": {"type": "keyword"}, + "body": {"analyzer": "czech", "type": "text"}, + "date": {"type": "date"}, + "extra": {"type": "object"}, + "other_participants": {"analyzer": "czech", "type": "text"}, + "our_participants": {"analyzer": "czech", "type": "text"}, + "provided_benefit": {"analyzer": "czech", "type": "text"}, + "published": {"type": "date"}, + "received_benefit": {"analyzer": "czech", "type": "text"}, + "title": {"analyzer": "czech", "type": "text"}, } }, - 'session': { - 'properties': { - 'expiration': { - 'type': 'integer' - }, - 'user_id': { - 'type': 'keyword' - } + "session": { + "properties": { + "expiration": {"type": "integer"}, + "user_id": {"type": "keyword"}, } }, - 'user': { - 'properties': { - 'email': { - 'type': 'keyword' - }, - 'extra': { - 'type': 'object' - }, - 'name': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'openid_uid': { - 'type': 'keyword' - } + "user": { + "properties": { + "email": {"type": "keyword"}, + "extra": {"type": "object"}, + "name": {"analyzer": "czech", "type": "text"}, + "openid_uid": {"type": "keyword"}, } - } + }, } } -snapshots['test_init_documents 1'] = { - 'mappings': { - 'report': { - 'properties': { - 'author_id': { - 'type': 'keyword' - }, - 'body': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'date': { - 'type': 'date' - }, - 'extra': { - 'type': 'object' - }, - 'other_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'our_participants': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'provided_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'published': { - 'type': 'date' - }, - 'received_benefit': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'title': { - 'analyzer': 'czech', - 'type': 'text' - } +snapshots["test_init_documents 1"] = { + "mappings": { + "report": { + "properties": { + "author_id": {"type": "keyword"}, + "body": {"analyzer": "czech", "type": "text"}, + "date": {"type": "date"}, + "extra": {"type": "object"}, + "other_participants": {"analyzer": "czech", "type": "text"}, + "our_participants": {"analyzer": "czech", "type": "text"}, + "provided_benefit": {"analyzer": "czech", "type": "text"}, + "published": {"type": "date"}, + "received_benefit": {"analyzer": "czech", "type": "text"}, + "title": {"analyzer": "czech", "type": "text"}, } }, - 'session': { - 'properties': { - 'expiration': { - 'type': 'integer' - }, - 'user_id': { - 'type': 'keyword' - } + "session": { + "properties": { + "expiration": {"type": "integer"}, + "user_id": {"type": "keyword"}, } }, - 'user': { - 'properties': { - 'email': { - 'type': 'keyword' - }, - 'extra': { - 'type': 'object' - }, - 'name': { - 'analyzer': 'czech', - 'type': 'text' - }, - 'openid_uid': { - 'type': 'keyword' - } + "user": { + "properties": { + "email": {"type": "keyword"}, + "extra": {"type": "object"}, + "name": {"analyzer": "czech", "type": "text"}, + "openid_uid": {"type": "keyword"}, } - } + }, } } diff --git a/tests/snapshots/snap_test_middleware.py b/tests/snapshots/snap_test_middleware.py index 2be80f56b2e39b8ef8bb4d16440d117633067ad3..a69726798d676b82f9e1ad0f177f6214a0d386ea 100644 --- a/tests/snapshots/snap_test_middleware.py +++ b/tests/snapshots/snap_test_middleware.py @@ -7,18 +7,8 @@ from snapshottest import Snapshot snapshots = Snapshot() -snapshots['test_wrong_header 1'] = { - 'errors': [ - { - 'message': 'Wrong Authorization header. Expected: "Bearer <token>"' - } - ] +snapshots["test_wrong_header 1"] = { + "errors": [{"message": 'Wrong Authorization header. Expected: "Bearer <token>"'}] } -snapshots['test_invalid_token 1'] = { - 'errors': [ - { - 'message': 'Invalid Token.' - } - ] -} +snapshots["test_invalid_token 1"] = {"errors": [{"message": "Invalid Token."}]} diff --git a/tests/snapshots/snap_test_models.py b/tests/snapshots/snap_test_models.py index 61f5a0a38292a80edc46aa69a4e27d7342a62a3f..c957574f7d54a72319c1124d198b9f945038b44e 100644 --- a/tests/snapshots/snap_test_models.py +++ b/tests/snapshots/snap_test_models.py @@ -7,6 +7,6 @@ from snapshottest import Snapshot, GenericRepr snapshots = Snapshot() -snapshots['test_report_is_saved_in_elasticsearch 1'] = [ +snapshots["test_report_is_saved_in_elasticsearch 1"] = [ GenericRepr("ReportDoc(index='report_ded_test', doc_type='report_doc', id='2')") ] diff --git a/tests/test_auth.py b/tests/test_auth.py index 580bcf807c08a23d34346ba608f186b3993d5429..2373708bd90c0034f02897d01a39c4921afc32f5 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -3,31 +3,30 @@ import time import jwt import pytest -from openlobby.core.auth import ( - create_access_token, - parse_access_token, -) +from openlobby.core.auth import create_access_token, parse_access_token def test_create_access_token(): - username = 'idkfa' + username = "idkfa" token = create_access_token(username) - payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.JWT_ALGORITHM]) + payload = jwt.decode( + token, settings.SECRET_KEY, algorithms=[settings.JWT_ALGORITHM] + ) assert isinstance(token, str) - assert payload['sub'] == username + assert payload["sub"] == username expected_expiration = int(time.time() + settings.SESSION_EXPIRATION) - assert expected_expiration <= payload['exp'] <= expected_expiration + 1 + assert expected_expiration <= payload["exp"] <= expected_expiration + 1 def test_parse_access_token(): - username = 'iddqd' + username = "iddqd" token = create_access_token(username) result = parse_access_token(token) assert result == username def test_parse_access_token__expired(): - username = 'idfa' + username = "idfa" expiration = int(time.time() - 1) token = create_access_token(username, expiration) with pytest.raises(jwt.ExpiredSignatureError): diff --git a/tests/test_middleware.py b/tests/test_middleware.py index d599f7413bc149b2c0ac283c2af7d252833e68ea..45973d7ad43f67d9fe1ad30380f51fdb7f199544 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -18,22 +18,26 @@ def test_no_auth_header(): middleware = TokenAuthMiddleware(lambda r: r) response = middleware(request) - request.META.get.assert_called_once_with('HTTP_AUTHORIZATION') + request.META.get.assert_called_once_with("HTTP_AUTHORIZATION") assert response == request assert response.user is None def test_authorized_user(): - user = User.objects.create(username='wolfe', first_name='Winston', - last_name='Wolfe', email='winston@wolfe.com') + user = User.objects.create( + username="wolfe", + first_name="Winston", + last_name="Wolfe", + email="winston@wolfe.com", + ) request = Mock() request.user = None - request.META.get.return_value = 'Bearer {}'.format(create_access_token('wolfe')) + request.META.get.return_value = "Bearer {}".format(create_access_token("wolfe")) middleware = TokenAuthMiddleware(lambda r: r) response = middleware(request) - request.META.get.assert_called_once_with('HTTP_AUTHORIZATION') + request.META.get.assert_called_once_with("HTTP_AUTHORIZATION") assert response == request assert response.user == user @@ -41,39 +45,49 @@ def test_authorized_user(): def test_wrong_header(snapshot): request = Mock() request.user = None - request.META.get.return_value = 'WRONG {}'.format(create_access_token('unknown')) + request.META.get.return_value = "WRONG {}".format(create_access_token("unknown")) middleware = TokenAuthMiddleware(lambda r: r) response = middleware(request) - request.META.get.assert_called_once_with('HTTP_AUTHORIZATION') + request.META.get.assert_called_once_with("HTTP_AUTHORIZATION") assert response.status_code == 400 - as_str = response.content.decode() if hasattr(response.content, 'decode') else response.content + as_str = ( + response.content.decode() + if hasattr(response.content, "decode") + else response.content + ) snapshot.assert_match(json.loads(as_str)) def test_invalid_token(snapshot): request = Mock() request.user = None - request.META.get.return_value = 'Bearer XXX{}'.format(create_access_token('unknown')) + request.META.get.return_value = "Bearer XXX{}".format( + create_access_token("unknown") + ) middleware = TokenAuthMiddleware(lambda r: r) response = middleware(request) - request.META.get.assert_called_once_with('HTTP_AUTHORIZATION') + request.META.get.assert_called_once_with("HTTP_AUTHORIZATION") assert response.status_code == 401 - as_str = response.content.decode() if hasattr(response.content,'decode') else response.content + as_str = ( + response.content.decode() + if hasattr(response.content, "decode") + else response.content + ) snapshot.assert_match(json.loads(as_str)) def test_unknown_user(snapshot): request = Mock() request.user = None - request.META.get.return_value = 'Bearer {}'.format(create_access_token('unknown')) + request.META.get.return_value = "Bearer {}".format(create_access_token("unknown")) middleware = TokenAuthMiddleware(lambda r: r) response = middleware(request) - request.META.get.assert_called_once_with('HTTP_AUTHORIZATION') + request.META.get.assert_called_once_with("HTTP_AUTHORIZATION") assert response == request assert response.user is None diff --git a/tests/test_models.py b/tests/test_models.py index 80e382a634e2b929e4c7a7ec5912bd2d1cee682d..748ab929f347080f0da3483846097b21e54513c9 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -3,17 +3,20 @@ from unittest.mock import patch import arrow import pytest from django.conf import settings -from openlobby.core.api.schema import AUTHOR_SORT_LAST_NAME_ID, AUTHOR_SORT_TOTAL_REPORTS_ID +from openlobby.core.api.schema import ( + AUTHOR_SORT_LAST_NAME_ID, + AUTHOR_SORT_TOTAL_REPORTS_ID, +) from openlobby.core.documents import ReportDoc from openlobby.core.models import Report, User, OpenIdClient, LoginAttempt -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] def test_report__marks_user_as_author_on_save(): author = User.objects.create(id=1, is_author=False) date = arrow.get(2018, 1, 1).datetime - Report.objects.create(author=author, date=date, body='Lorem ipsum.') + Report.objects.create(author=author, date=date, body="Lorem ipsum.") user = User.objects.get(id=1) assert user.is_author @@ -21,7 +24,7 @@ def test_report__marks_user_as_author_on_save(): def test_report__marks_user_as_author_on_save__not_if_draft(): author = User.objects.create(id=1, is_author=False) date = arrow.get(2018, 1, 1).datetime - Report.objects.create(author=author, is_draft=True, date=date, body='Lorem ipsum.') + Report.objects.create(author=author, is_draft=True, date=date, body="Lorem ipsum.") user = User.objects.get(id=1) assert not user.is_author @@ -35,29 +38,29 @@ def test_report__is_saved_in_elasticsearch(): author=author, date=date, published=published, - title='It happened', - body='Lorem ipsum.', - received_benefit='coffee', - provided_benefit='tea', - our_participants='me', - other_participants='them', - extra={'a': 3}, + title="It happened", + body="Lorem ipsum.", + received_benefit="coffee", + provided_benefit="tea", + our_participants="me", + other_participants="them", + extra={"a": 3}, is_draft=False, ) docs = list(ReportDoc.search()) assert len(docs) == 1 doc = docs[0] - assert doc.meta.id == '3' + assert doc.meta.id == "3" assert doc.author_id == 6 assert doc.date == date assert doc.published == published - assert doc.title == 'It happened' - assert doc.body == 'Lorem ipsum.' - assert doc.received_benefit == 'coffee' - assert doc.provided_benefit == 'tea' - assert doc.our_participants == 'me' - assert doc.other_participants == 'them' - assert doc.extra == {'a': 3} + assert doc.title == "It happened" + assert doc.body == "Lorem ipsum." + assert doc.received_benefit == "coffee" + assert doc.provided_benefit == "tea" + assert doc.our_participants == "me" + assert doc.other_participants == "them" + assert doc.extra == {"a": 3} assert not doc.is_draft @@ -65,95 +68,144 @@ def test_report__save_works_with_no_extra(): author = User.objects.create(id=6) date = arrow.get(2018, 1, 1).datetime Report.objects.create( - id=7, - author=author, - date=date, - published=date, - body='Lorem ipsum.', + id=7, author=author, date=date, published=date, body="Lorem ipsum." ) docs = list(ReportDoc.search()) assert len(docs) == 1 doc = docs[0] - assert doc.meta.id == '7' + assert doc.meta.id == "7" assert doc.extra is None def test_login_attempt__default_expiration(): - client = OpenIdClient.objects.create(name='a', client_id='b', client_secret='c') - with patch('openlobby.core.models.time.time', return_value=10000): - attempt = LoginAttempt.objects.create(openid_client=client, state='foo', - app_redirect_uri='http://openlobby/app') + client = OpenIdClient.objects.create(name="a", client_id="b", client_secret="c") + with patch("openlobby.core.models.time.time", return_value=10000): + attempt = LoginAttempt.objects.create( + openid_client=client, state="foo", app_redirect_uri="http://openlobby/app" + ) assert attempt.expiration == 10000 + settings.LOGIN_ATTEMPT_EXPIRATION def test_user__no_name_collision(): - User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='Gosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='Reynolds') - assert User.objects.get(username='a').has_colliding_name is False - assert User.objects.get(username='b').has_colliding_name is False + User.objects.create( + username="a", is_author=True, first_name="Ryan", last_name="Gosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="Reynolds" + ) + assert User.objects.get(username="a").has_colliding_name is False + assert User.objects.get(username="b").has_colliding_name is False def test_user__name_collision(): - User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='Gosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='Gosling') - assert User.objects.get(username='a').has_colliding_name is True - assert User.objects.get(username='b').has_colliding_name is True + User.objects.create( + username="a", is_author=True, first_name="Ryan", last_name="Gosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="Gosling" + ) + assert User.objects.get(username="a").has_colliding_name is True + assert User.objects.get(username="b").has_colliding_name is True def test_user__name_collision_affects_only_authors(): - User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='Gosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='Gosling') - User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='Gosling') - assert User.objects.get(username='a').has_colliding_name is False - assert User.objects.get(username='b').has_colliding_name is False - assert User.objects.get(username='c').has_colliding_name is False - User.objects.create(username='d', is_author=True, first_name='Ryan', last_name='Gosling') - assert User.objects.get(username='a').has_colliding_name is False - assert User.objects.get(username='b').has_colliding_name is True - assert User.objects.get(username='c').has_colliding_name is False - assert User.objects.get(username='d').has_colliding_name is True + User.objects.create( + username="a", is_author=False, first_name="Ryan", last_name="Gosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="Gosling" + ) + User.objects.create( + username="c", is_author=False, first_name="Ryan", last_name="Gosling" + ) + assert User.objects.get(username="a").has_colliding_name is False + assert User.objects.get(username="b").has_colliding_name is False + assert User.objects.get(username="c").has_colliding_name is False + User.objects.create( + username="d", is_author=True, first_name="Ryan", last_name="Gosling" + ) + assert User.objects.get(username="a").has_colliding_name is False + assert User.objects.get(username="b").has_colliding_name is True + assert User.objects.get(username="c").has_colliding_name is False + assert User.objects.get(username="d").has_colliding_name is True def test_user__name_collision_excludes_self_on_update(): - u = User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='Gosling') + u = User.objects.create( + username="a", is_author=True, first_name="Ryan", last_name="Gosling" + ) u.save() - assert User.objects.get(username='a').has_colliding_name is False + assert User.objects.get(username="a").has_colliding_name is False def test_user__sorted_default(): - User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') - User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') - assert User.objects.sorted()[0].username == 'a' + User.objects.create( + username="a", is_author=False, first_name="Ryan", last_name="AGosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="BGosling" + ) + User.objects.create( + username="c", is_author=False, first_name="Ryan", last_name="CGosling" + ) + assert User.objects.sorted()[0].username == "a" def test_user__sorted_default_reversed(): - User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') - User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') - assert User.objects.sorted(reversed=True)[0].username == 'c' + User.objects.create( + username="a", is_author=False, first_name="Ryan", last_name="AGosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="BGosling" + ) + User.objects.create( + username="c", is_author=False, first_name="Ryan", last_name="CGosling" + ) + assert User.objects.sorted(reversed=True)[0].username == "c" def test_user__sorted_last_name(): - User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') - User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') - assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID)[0].username == 'a' - assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=False)[0].username == 'a' - assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=True)[0].username == 'c' + User.objects.create( + username="a", is_author=False, first_name="Ryan", last_name="AGosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="BGosling" + ) + User.objects.create( + username="c", is_author=False, first_name="Ryan", last_name="CGosling" + ) + assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID)[0].username == "a" + assert ( + User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=False)[0].username + == "a" + ) + assert ( + User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=True)[0].username + == "c" + ) def test_user__sorted_total_reports(): - author = User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='AGosling') - User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') + author = User.objects.create( + username="a", is_author=True, first_name="Ryan", last_name="AGosling" + ) + User.objects.create( + username="b", is_author=True, first_name="Ryan", last_name="BGosling" + ) date = arrow.get(2018, 1, 1).datetime Report.objects.create( - id=7, - author=author, - date=date, - published=date, - body='Lorem ipsum.', + id=7, author=author, date=date, published=date, body="Lorem ipsum." + ) + assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID)[0].username == "a" + assert ( + User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=False)[ + 0 + ].username + == "a" + ) + assert ( + User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=True)[ + 0 + ].username + == "b" ) - assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID)[0].username == 'a' - assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=False)[0].username == 'a' - assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=True)[0].username == 'b' diff --git a/tests/test_paginator.py b/tests/test_paginator.py index 8a8d08c8fb823235a518ef05ddf7c8c27c056743..c859a6ca595ddcbf4c003fbc593f6a8b0e5bf3cb 100644 --- a/tests/test_paginator.py +++ b/tests/test_paginator.py @@ -9,20 +9,12 @@ from openlobby.core.api.paginator import ( ) -@pytest.mark.parametrize('num, cursor', [ - (5, 'NQ=='), - (777, 'Nzc3'), - (12, 'MTI='), -]) +@pytest.mark.parametrize("num, cursor", [(5, "NQ=="), (777, "Nzc3"), (12, "MTI=")]) def test_encode_cursor(num, cursor): assert encode_cursor(num) == cursor -@pytest.mark.parametrize('num, cursor', [ - (8, 'OA=='), - (123, 'MTIz'), - (65, 'NjU='), -]) +@pytest.mark.parametrize("num, cursor", [(8, "OA=="), (123, "MTIz"), (65, "NjU=")]) def test_decode_cursor(num, cursor): assert decode_cursor(cursor) == num @@ -44,15 +36,18 @@ def test_paginator__custom_per_page(): assert paginator.slice_to == 5 -@pytest.mark.parametrize('kw, slice_from, slice_to', [ - ({'first': 15}, 0, 15), - ({'first': 5, 'after': encode_cursor(3)}, 3, 8), - ({'last': 8, 'before': encode_cursor(20)}, 11, 19), - # overflow of slice_from - ({'last': 100, 'before': encode_cursor(42)}, 0, 41), - # preffer first before last if both provided - ({'first': 20, 'last': 4}, 0, 20), -]) +@pytest.mark.parametrize( + "kw, slice_from, slice_to", + [ + ({"first": 15}, 0, 15), + ({"first": 5, "after": encode_cursor(3)}, 3, 8), + ({"last": 8, "before": encode_cursor(20)}, 11, 19), + # overflow of slice_from + ({"last": 100, "before": encode_cursor(42)}, 0, 41), + # preffer first before last if both provided + ({"first": 20, "last": 4}, 0, 20), + ], +) def test_paginator__input_combinations(kw, slice_from, slice_to): paginator = Paginator(**kw) assert paginator.slice_from == slice_from @@ -64,24 +59,27 @@ def test_paginator__last_without_before(): Paginator(last=1) -@pytest.mark.parametrize('kw, total, previous, next, start, end', [ - ({}, 10, False, False, 1, 10), - ({}, 15, False, True, 1, 10), - ({}, 5, False, False, 1, 5), - ({'first': 1}, 10, False, True, 1, 1), - ({'first': 6}, 10, False, True, 1, 6), - ({'first': 6}, 4, False, False, 1, 4), - ({'first': 6}, 6, False, False, 1, 6), - ({'first': 3, 'after': encode_cursor(7)}, 20, True, True, 8, 10), - ({'first': 3, 'after': encode_cursor(17)}, 20, True, False, 18, 20), - ({'first': 5, 'after': encode_cursor(17)}, 20, True, False, 18, 20), - ({'last': 4, 'before': encode_cursor(10)}, 20, True, True, 6, 9), - ({'last': 4, 'before': encode_cursor(5)}, 20, False, True, 1, 4), - ({'last': 4, 'before': encode_cursor(3)}, 20, False, True, 1, 2), - # out of bounds - ({'first': 3, 'after': encode_cursor(10)}, 10, False, False, None, None), - ({'last': 3, 'before': encode_cursor(1)}, 10, False, False, None, None), -]) +@pytest.mark.parametrize( + "kw, total, previous, next, start, end", + [ + ({}, 10, False, False, 1, 10), + ({}, 15, False, True, 1, 10), + ({}, 5, False, False, 1, 5), + ({"first": 1}, 10, False, True, 1, 1), + ({"first": 6}, 10, False, True, 1, 6), + ({"first": 6}, 4, False, False, 1, 4), + ({"first": 6}, 6, False, False, 1, 6), + ({"first": 3, "after": encode_cursor(7)}, 20, True, True, 8, 10), + ({"first": 3, "after": encode_cursor(17)}, 20, True, False, 18, 20), + ({"first": 5, "after": encode_cursor(17)}, 20, True, False, 18, 20), + ({"last": 4, "before": encode_cursor(10)}, 20, True, True, 6, 9), + ({"last": 4, "before": encode_cursor(5)}, 20, False, True, 1, 4), + ({"last": 4, "before": encode_cursor(3)}, 20, False, True, 1, 2), + # out of bounds + ({"first": 3, "after": encode_cursor(10)}, 10, False, False, None, None), + ({"last": 3, "before": encode_cursor(1)}, 10, False, False, None, None), + ], +) def test_paginator__get_page_info(kw, total, previous, next, start, end): paginator = Paginator(**kw) page_info = paginator.get_page_info(total) @@ -91,11 +89,14 @@ def test_paginator__get_page_info(kw, total, previous, next, start, end): assert page_info.end_cursor == end if end is None else encode_cursor(end) -@pytest.mark.parametrize('kw, num, cursor', [ - ({}, 3, encode_cursor(3)), - ({'first': 6, 'after': encode_cursor(1)}, 3, encode_cursor(4)), - ({'last': 6, 'before': encode_cursor(11)}, 3, encode_cursor(7)), -]) +@pytest.mark.parametrize( + "kw, num, cursor", + [ + ({}, 3, encode_cursor(3)), + ({"first": 6, "after": encode_cursor(1)}, 3, encode_cursor(4)), + ({"last": 6, "before": encode_cursor(11)}, 3, encode_cursor(7)), + ], +) def test_paginator__get_edge_cursor(kw, num, cursor): paginator = Paginator(**kw) assert paginator.get_edge_cursor(num) == cursor diff --git a/tests/test_sanitizers.py b/tests/test_sanitizers.py index 74ed2722145b8b924253ebe6046baacd866eac90..08162d31efa6f0b662b598c05b6f67850fecb228 100644 --- a/tests/test_sanitizers.py +++ b/tests/test_sanitizers.py @@ -3,24 +3,30 @@ import pytest from openlobby.core.api.sanitizers import strip_all_tags, extract_text -@pytest.mark.parametrize('input, text', [ - ('foo', 'foo'), - ('has multiple words', 'has multiple words'), - ('has <b>some</b> tags', 'has some tags'), - ("<IMG SRC=jAvascript:alert('test2')>", ''), -]) +@pytest.mark.parametrize( + "input, text", + [ + ("foo", "foo"), + ("has multiple words", "has multiple words"), + ("has <b>some</b> tags", "has some tags"), + ("<IMG SRC=jAvascript:alert('test2')>", ""), + ], +) def test_strip_all_tags(input, text): assert strip_all_tags(input) == text -@pytest.mark.parametrize('input, text', [ - ('foo', 'foo'), - ('has multiple words', 'has multiple words'), - ('has <b>some</b> tags', 'has some tags'), - ('x" onload="alert()"', 'x onload alert'), - ("'; drop database; x='y", 'drop database x y'), - ("<IMG SRC=jAvascript:alert('test2')>", ''), - ('=/*-+.', ''), -]) +@pytest.mark.parametrize( + "input, text", + [ + ("foo", "foo"), + ("has multiple words", "has multiple words"), + ("has <b>some</b> tags", "has some tags"), + ('x" onload="alert()"', "x onload alert"), + ("'; drop database; x='y", "drop database x y"), + ("<IMG SRC=jAvascript:alert('test2')>", ""), + ("=/*-+.", ""), + ], +) def test_extract_text(input, text): assert extract_text(input) == text diff --git a/tests/test_search.py b/tests/test_search.py index 5e8d6d0495d6c7a504626e67a895fd985a17e67e..27c77702829a18631501ee5460b4a3932ffe8361 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -6,15 +6,13 @@ from openlobby.core.search import query_reports, reports_by_author from .dummy import prepare_reports -pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] +pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures("django_es")] -@pytest.mark.parametrize('query, expected_ids', [ - ('', [3, 2, 1]), - ('sauron', [3, 2]), - ('towers', [2]), - ('Aragorn Gandalf', [3, 1]), -]) +@pytest.mark.parametrize( + "query, expected_ids", + [("", [3, 2, 1]), ("sauron", [3, 2]), ("towers", [2]), ("Aragorn Gandalf", [3, 1])], +) def test_query_reports(query, expected_ids): prepare_reports() paginator = Paginator() @@ -25,20 +23,19 @@ def test_query_reports(query, expected_ids): def test_query_reports__highlight(): prepare_reports() paginator = Paginator() - query = 'King' + query = "King" response = query_reports(query, paginator, highlight=True) doc = response.hits[0] - assert '<mark>King</mark>' in doc.meta.highlight.title[0] - assert '<mark>King</mark>' in doc.meta.highlight.body[0] + assert "<mark>King</mark>" in doc.meta.highlight.title[0] + assert "<mark>King</mark>" in doc.meta.highlight.body[0] -@pytest.mark.parametrize('first, after, expected_ids', [ - (2, None, [3, 2]), - (2, encode_cursor(1), [2, 1]), -]) +@pytest.mark.parametrize( + "first, after, expected_ids", [(2, None, [3, 2]), (2, encode_cursor(1), [2, 1])] +) def test_query_reports__pagination(first, after, expected_ids): prepare_reports() - query = '' + query = "" paginator = Paginator(first=first, after=after) response = query_reports(query, paginator) assert expected_ids == [int(r.meta.id) for r in response] @@ -52,10 +49,9 @@ def test_reports_by_author(): assert [3, 1] == [int(r.meta.id) for r in response] -@pytest.mark.parametrize('first, after, expected_ids', [ - (1, None, [3]), - (1, encode_cursor(1), [1]), -]) +@pytest.mark.parametrize( + "first, after, expected_ids", [(1, None, [3]), (1, encode_cursor(1), [1])] +) def test_reports_by_author__pagination(first, after, expected_ids): prepare_reports() author_id = 1 diff --git a/tests/test_views.py b/tests/test_views.py index b67547d90cc05e2d2e095b1910bfce1cbdc4d2a0..7eb86f996f9515a2470ba94c8420c33969edb122 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -12,39 +12,47 @@ pytestmark = pytest.mark.django_db def test_login_redirect__new_user(client, issuer): - state = 'IDDQD' - sub = 'IDKFA' - openid_uid = 'elon.musk@openid' - first_name = 'Elon' - last_name = 'Musk' - email = 'elon.musk@tesla.com' - app_redirect_uri = 'http://doom.is.legend' + state = "IDDQD" + sub = "IDKFA" + openid_uid = "elon.musk@openid" + first_name = "Elon" + last_name = "Musk" + email = "elon.musk@tesla.com" + app_redirect_uri = "http://doom.is.legend" oc = register_client(issuer) - oid_client = OpenIdClient.objects.create(name='Test', issuer=issuer, - client_id=oc.client_id, client_secret=oc.client_secret) - LoginAttempt.objects.create(openid_client=oid_client, state=state, - app_redirect_uri=app_redirect_uri, openid_uid=openid_uid) + oid_client = OpenIdClient.objects.create( + name="Test", + issuer=issuer, + client_id=oc.client_id, + client_secret=oc.client_secret, + ) + LoginAttempt.objects.create( + openid_client=oid_client, + state=state, + app_redirect_uri=app_redirect_uri, + openid_uid=openid_uid, + ) # we are not testing real redirect url params, so we mock communication with # OpenID Provider user_info = { - 'sub': sub, - 'given_name': first_name, - 'family_name': last_name, - 'email': email, + "sub": sub, + "given_name": first_name, + "family_name": last_name, + "email": email, } - with patch('openlobby.core.views.get_user_info', return_value=user_info) as mock: - response = client.get(reverse('login-redirect'), {'state': state}) + with patch("openlobby.core.views.get_user_info", return_value=user_info) as mock: + response = client.get(reverse("login-redirect"), {"state": state}) m_client, m_query_string = mock.call_args[0] assert m_client.client_id == oc.client_id - assert m_query_string == 'state={}'.format(state) + assert m_query_string == "state={}".format(state) assert response.status_code == 302 - url, query_string = response.url.split('?') + url, query_string = response.url.split("?") qs = urllib.parse.parse_qs(query_string) assert url == app_redirect_uri - assert sub == parse_access_token(qs['token'][0]) + assert sub == parse_access_token(qs["token"][0]) user = User.objects.get() assert user.username == sub @@ -55,42 +63,55 @@ def test_login_redirect__new_user(client, issuer): def test_login_redirect__existing_user(client, issuer): - state = 'IDDQD' - sub = 'IDKFA' - openid_uid = 'elon.musk@openid' - first_name = 'Elon' - last_name = 'Musk' - email = 'elon.musk@tesla.com' - app_redirect_uri = 'http://doom.is.legend' + state = "IDDQD" + sub = "IDKFA" + openid_uid = "elon.musk@openid" + first_name = "Elon" + last_name = "Musk" + email = "elon.musk@tesla.com" + app_redirect_uri = "http://doom.is.legend" oc = register_client(issuer) - oid_client = OpenIdClient.objects.create(name='Test', issuer=issuer, - client_id=oc.client_id, client_secret=oc.client_secret) - LoginAttempt.objects.create(openid_client=oid_client, state=state, - app_redirect_uri=app_redirect_uri, openid_uid=openid_uid) - User.objects.create(username=sub, first_name=first_name, last_name=last_name, - email=email, openid_uid=openid_uid) + oid_client = OpenIdClient.objects.create( + name="Test", + issuer=issuer, + client_id=oc.client_id, + client_secret=oc.client_secret, + ) + LoginAttempt.objects.create( + openid_client=oid_client, + state=state, + app_redirect_uri=app_redirect_uri, + openid_uid=openid_uid, + ) + User.objects.create( + username=sub, + first_name=first_name, + last_name=last_name, + email=email, + openid_uid=openid_uid, + ) # we are not testing real redirect url params, so we mock communication with # OpenID Provider user_info = { - 'sub': sub, + "sub": sub, # return different details - 'given_name': 'Elons', - 'family_name': 'Mustache', - 'email': 'elons.mustache@spacex.com', + "given_name": "Elons", + "family_name": "Mustache", + "email": "elons.mustache@spacex.com", } - with patch('openlobby.core.views.get_user_info', return_value=user_info) as mock: - response = client.get(reverse('login-redirect'), {'state': state}) + with patch("openlobby.core.views.get_user_info", return_value=user_info) as mock: + response = client.get(reverse("login-redirect"), {"state": state}) m_client, m_query_string = mock.call_args[0] assert m_client.client_id == oc.client_id - assert m_query_string == 'state={}'.format(state) + assert m_query_string == "state={}".format(state) assert response.status_code == 302 - url, query_string = response.url.split('?') + url, query_string = response.url.split("?") qs = urllib.parse.parse_qs(query_string) assert url == app_redirect_uri - assert sub == parse_access_token(qs['token'][0]) + assert sub == parse_access_token(qs["token"][0]) # check there is still just one user, who's details are not updated user = User.objects.get() diff --git a/tests/utils.py b/tests/utils.py index 2f03456bd4bd7f729652a852ceb95cc4390c5b3d..e836d9db592b058b87e65a4d0ed613d8f575bf70 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,14 +4,17 @@ from openlobby.core.auth import create_access_token def call_api(client, query, input=None, username=None): - variables = json.dumps({'input': input or {}}) + variables = json.dumps({"input": input or {}}) if username is None: - res = client.post('/graphql', {'query': query, 'variables': variables}) + res = client.post("/graphql", {"query": query, "variables": variables}) else: token = create_access_token(username) - auth_header = 'Bearer {}'.format(token) - res = client.post('/graphql', {'query': query, 'variables': variables}, - HTTP_AUTHORIZATION=auth_header) + auth_header = "Bearer {}".format(token) + res = client.post( + "/graphql", + {"query": query, "variables": variables}, + HTTP_AUTHORIZATION=auth_header, + ) return res.json() @@ -19,7 +22,7 @@ def strip_value(data, *path): element = path[0] value = data.get(element) if len(path) == 1: - data[element] = '__STRIPPED__' + data[element] = "__STRIPPED__" return value else: return strip_value(value, *path[1:])