diff --git a/openlobby/core/api/types.py b/openlobby/core/api/types.py
index 3b8b31737d027bbd15250b8a31a69c79d8b8a25d..75113a89919b9e9a0239a464baaf995ca5032f9e 100644
--- a/openlobby/core/api/types.py
+++ b/openlobby/core/api/types.py
@@ -17,7 +17,7 @@ def get_higlighted(hit, field):
 
 
 class Report(graphene.ObjectType):
-    author = graphene.Field(lambda: User)
+    author = graphene.Field(lambda: Author)
     date = graphene.String()
     published = graphene.String()
     title = graphene.String()
@@ -44,7 +44,7 @@ class Report(graphene.ObjectType):
             provided_benefit=get_higlighted(report, 'provided_benefit'),
             our_participants=get_higlighted(report, 'our_participants'),
             other_participants=get_higlighted(report, 'other_participants'),
-            extra=report.extra._d_,
+            extra=report.extra,
         )
 
     @classmethod
diff --git a/tests/dummy.py b/tests/dummy.py
index dd168559ac0a74eedfc0c1f6b3828c14bf83c066..a6ab29872c4e106fff4d2f19ef91f7fdaadaca70 100644
--- a/tests/dummy.py
+++ b/tests/dummy.py
@@ -25,6 +25,7 @@ reports = [
         'provided_benefit': '',
         'our_participants': 'Frodo, Gimli, Legolas',
         'other_participants': 'Saruman, Sauron',
+        'extra': {'rings': 1},
     },
     {
         'id': 3,
diff --git a/tests/schema/snapshots/snap_test_search_reports.py b/tests/schema/snapshots/snap_test_search_reports.py
new file mode 100644
index 0000000000000000000000000000000000000000..4943bb139170a6aa5310aa0079fcc305d90972b8
--- /dev/null
+++ b/tests/schema/snapshots/snap_test_search_reports.py
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+# snapshottest: v1 - https://goo.gl/zC4yUc
+from __future__ import unicode_literals
+
+from snapshottest import Snapshot
+
+
+snapshots = Snapshot()
+
+snapshots['test_all 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'MQ==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Another long story.',
+                        'date': '2018-01-05 00:00:00+00:00',
+                        'extra': '{"rings": 1}',
+                        'id': 'UmVwb3J0OjI=',
+                        'otherParticipants': 'Saruman, Sauron',
+                        'ourParticipants': 'Frodo, Gimli, Legolas',
+                        'providedBenefit': '',
+                        'published': '2018-01-10 00:00:00+00:00',
+                        'receivedBenefit': 'Mithrill Jacket',
+                        'title': 'The Two Towers'
+                    }
+                },
+                {
+                    'cursor': 'Mg==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Aragorn is the King. And we have lost the Ring.',
+                        'date': '2018-01-07 00:00:00+00:00',
+                        'extra': None,
+                        'id': 'UmVwb3J0OjM=',
+                        'otherParticipants': 'Sauron',
+                        'ourParticipants': 'Aragorn',
+                        'providedBenefit': 'The Ring',
+                        'published': '2018-01-08 00:00:00+00:00',
+                        'receivedBenefit': '',
+                        'title': 'The Return of the King'
+                    }
+                },
+                {
+                    'cursor': 'Mw==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Long story short: we got the Ring!',
+                        'date': '2018-01-01 00:00:00+00:00',
+                        'extra': None,
+                        'id': 'UmVwb3J0OjE=',
+                        '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=='
+            },
+            'totalCount': 3
+        }
+    }
+}
+
+snapshots['test_query 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'MQ==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Another long story.',
+                        'date': '2018-01-05 00:00:00+00:00',
+                        'extra': '{"rings": 1}',
+                        'id': 'UmVwb3J0OjI=',
+                        'otherParticipants': 'Saruman, Sauron',
+                        'ourParticipants': 'Frodo, Gimli, Legolas',
+                        'providedBenefit': '',
+                        'published': '2018-01-10 00:00:00+00:00',
+                        'receivedBenefit': 'Mithrill Jacket',
+                        'title': 'The Two Towers'
+                    }
+                }
+            ],
+            'totalCount': 1
+        }
+    }
+}
+
+snapshots['test_highlight 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'MQ==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Aragorn is the King. And we have lost the <mark>Ring</mark>.',
+                        'date': '2018-01-07 00:00:00+00:00',
+                        'extra': None,
+                        'id': 'UmVwb3J0OjM=',
+                        'otherParticipants': 'Sauron',
+                        'ourParticipants': 'Aragorn',
+                        'providedBenefit': 'The <mark>Ring</mark>',
+                        'published': '2018-01-08 00:00:00+00:00',
+                        'receivedBenefit': '',
+                        'title': 'The Return of the King'
+                    }
+                },
+                {
+                    'cursor': 'Mg==',
+                    'node': {
+                        'author': {
+                            'extra': None,
+                            'firstName': 'Winston',
+                            'id': 'QXV0aG9yOjE=',
+                            'lastName': 'Wolfe'
+                        },
+                        'body': 'Long story short: we got the <mark>Ring</mark>!',
+                        'date': '2018-01-01 00:00:00+00:00',
+                        'extra': None,
+                        'id': 'UmVwb3J0OjE=',
+                        '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
+        }
+    }
+}
+
+snapshots['test_first 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'MQ==',
+                    'node': {
+                        'id': 'UmVwb3J0OjI=',
+                        'title': 'The Two Towers'
+                    }
+                }
+            ],
+            'pageInfo': {
+                'endCursor': 'MQ==',
+                'hasNextPage': True,
+                'hasPreviousPage': False,
+                'startCursor': 'MQ=='
+            },
+            'totalCount': 3
+        }
+    }
+}
+
+snapshots['test_first_after 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'Mg==',
+                    'node': {
+                        'id': 'UmVwb3J0OjM=',
+                        'title': 'The Return of the King'
+                    }
+                }
+            ],
+            'pageInfo': {
+                'endCursor': 'Mg==',
+                'hasNextPage': True,
+                'hasPreviousPage': True,
+                'startCursor': 'Mg=='
+            },
+            'totalCount': 3
+        }
+    }
+}
+
+snapshots['test_last 1'] = {
+    'data': {
+        'searchReports': None
+    },
+    'errors': [
+        {
+            'locations': [
+                {
+                    'column': 9,
+                    'line': 3
+                }
+            ],
+            'message': 'Pagination "last" works only in combination with "before" argument.'
+        }
+    ]
+}
+
+snapshots['test_last_before 1'] = {
+    'data': {
+        'searchReports': {
+            'edges': [
+                {
+                    'cursor': 'Mg==',
+                    'node': {
+                        'id': 'UmVwb3J0OjM=',
+                        'title': 'The Return of the King'
+                    }
+                }
+            ],
+            'pageInfo': {
+                'endCursor': 'Mg==',
+                'hasNextPage': True,
+                'hasPreviousPage': True,
+                'startCursor': 'Mg=='
+            },
+            'totalCount': 3
+        }
+    }
+}
diff --git a/tests/schema/test_search_reports.py b/tests/schema/test_search_reports.py
new file mode 100644
index 0000000000000000000000000000000000000000..a980aa37a4a31eb166716a9d9b1a486d61704be5
--- /dev/null
+++ b/tests/schema/test_search_reports.py
@@ -0,0 +1,211 @@
+import pytest
+
+from ..dummy import prepare_reports
+
+
+pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')]
+
+
+def test_all(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    date
+                    published
+                    title
+                    body
+                    receivedBenefit
+                    providedBenefit
+                    ourParticipants
+                    otherParticipants
+                    extra
+                    author {
+                        id
+                        firstName
+                        lastName
+                        extra
+                    }
+                }
+            }
+            pageInfo {
+                hasPreviousPage
+                hasNextPage
+                startCursor
+                endCursor
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_query(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (query: "towers") {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    date
+                    published
+                    title
+                    body
+                    receivedBenefit
+                    providedBenefit
+                    ourParticipants
+                    otherParticipants
+                    extra
+                    author {
+                        id
+                        firstName
+                        lastName
+                        extra
+                    }
+                }
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_highlight(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (query: "Ring", highlight: true) {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    date
+                    published
+                    title
+                    body
+                    receivedBenefit
+                    providedBenefit
+                    ourParticipants
+                    otherParticipants
+                    extra
+                    author {
+                        id
+                        firstName
+                        lastName
+                        extra
+                    }
+                }
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_first(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (first: 1) {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    title
+                }
+            }
+            pageInfo {
+                hasPreviousPage
+                hasNextPage
+                startCursor
+                endCursor
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_first_after(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (first: 1, after: "MQ==") {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    title
+                }
+            }
+            pageInfo {
+                hasPreviousPage
+                hasNextPage
+                startCursor
+                endCursor
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_last(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (last: 2) {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    title
+                }
+            }
+            pageInfo {
+                hasPreviousPage
+                hasNextPage
+                startCursor
+                endCursor
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())
+
+
+def test_last_before(client, snapshot):
+    prepare_reports()
+    res = client.post('/graphql', {'query': """
+    query {
+        searchReports (last: 1, before: "Mw==") {
+            totalCount
+            edges {
+                cursor
+                node {
+                    id
+                    title
+                }
+            }
+            pageInfo {
+                hasPreviousPage
+                hasNextPage
+                startCursor
+                endCursor
+            }
+        }
+    }
+    """})
+    snapshot.assert_match(res.json())