Beispiel #1
0
def test_search(db_session, client):
    edka = airports.merzbrueck()
    lva = clubs.lva()

    add_fixtures(
        db_session,
        users.john(),
        users.jane(),
        lva,
        clubs.sfn(),
        edka,
        airports.meiersberg(),
    )

    res = client.get("/search?text=aachen")
    assert res.status_code == 200
    assert res.json == {
        "results": [
            {
                "id": edka.id,
                "type": "airport",
                "name": "Aachen Merzbruck",
                "icao": "EDKA",
                "frequency": "122.875",
            },
            {
                "id": lva.id,
                "type": "club",
                "name": "LV Aachen",
                "website": "http://www.lv-aachen.de",
            },
        ]
    }
def test_clear_all(db_session, client):
    john = users.john()
    jane = users.jane()
    max = users.max()

    create_follower_notification(john, jane)
    create_follower_notification(john, max)
    create_follower_notification(jane, max)

    db_session.commit()

    res = client.post("/notifications/clear", headers=auth_for(john))
    assert res.status_code == 200
    assert res.json == {}

    johns_notifications = db_session.query(Notification).filter_by(recipient=john).all()
    assert len(johns_notifications) == 2
    assert johns_notifications[0].event.actor_id == jane.id
    assert johns_notifications[0].time_read is not None
    assert johns_notifications[1].event.actor_id == max.id
    assert johns_notifications[1].time_read is not None

    janes_notifications = db_session.query(Notification).filter_by(recipient=jane).all()
    assert len(janes_notifications) == 1
    assert janes_notifications[0].event.actor_id == max.id
    assert janes_notifications[0].time_read is None
Beispiel #3
0
def test_comments(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    comment1 = flight_comments.yeah(flight=flight)
    comment2 = flight_comments.emoji(flight=flight)
    comment3 = flight_comments.yeah(
        flight=flight, user=flight.igc_file.owner, text=u"foo"
    )
    comment4 = flight_comments.yeah(flight=flight, text=u"bar")
    comment5 = flight_comments.yeah(flight=flight, user=users.jane(), text=u"baz")
    add_fixtures(db_session, flight, comment1, comment2, comment3, comment4, comment5)

    res = client.get("/flights/{id}?extended".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight": expected_basic_flight_json(flight),
        u"near_flights": [],
        u"comments": [
            {u"user": None, u"text": u"Yeah!"},
            {u"user": None, u"text": u"\U0001f44d"},
            {u"user": {u"id": comment3.user.id, u"name": u"John Doe"}, u"text": u"foo"},
            {u"user": None, u"text": u"bar"},
            {u"user": {u"id": comment5.user.id, u"name": u"Jane Doe"}, u"text": u"baz"},
        ],
        u"contest_legs": {u"classic": [], u"triangle": []},
        u"phases": [],
        u"performance": {u"circling": [], u"cruise": {}},
    }
Beispiel #4
0
def test_clear_all(db_session, client):
    john = users.john()
    jane = users.jane()
    max = users.max()

    create_follower_notification(john, jane)
    create_follower_notification(john, max)
    create_follower_notification(jane, max)

    db_session.commit()

    res = client.post('/notifications/clear', headers=auth_for(john))
    assert res.status_code == 200
    assert res.json == {}

    johns_notifications = db_session.query(Notification).filter_by(
        recipient=john).all()
    assert len(johns_notifications) == 2
    assert johns_notifications[0].event.actor_id == jane.id
    assert johns_notifications[0].time_read is not None
    assert johns_notifications[1].event.actor_id == max.id
    assert johns_notifications[1].time_read is not None

    janes_notifications = db_session.query(Notification).filter_by(
        recipient=jane).all()
    assert len(janes_notifications) == 1
    assert janes_notifications[0].event.actor_id == max.id
    assert janes_notifications[0].time_read is None
Beispiel #5
0
def test_comments(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    comment1 = flight_comments.yeah(flight=flight)
    comment2 = flight_comments.emoji(flight=flight)
    comment3 = flight_comments.yeah(flight=flight,
                                    user=flight.igc_file.owner,
                                    text=u"foo")
    comment4 = flight_comments.yeah(flight=flight, text=u"bar")
    comment5 = flight_comments.yeah(flight=flight,
                                    user=users.jane(),
                                    text=u"baz")
    add_fixtures(db_session, flight, comment1, comment2, comment3, comment4,
                 comment5)

    res = client.get("/flights/{id}?extended".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight":
        expected_basic_flight_json(flight),
        u"near_flights": [],
        u"comments": [
            {
                u"user": None,
                u"text": u"Yeah!"
            },
            {
                u"user": None,
                u"text": u"\U0001f44d"
            },
            {
                u"user": {
                    u"id": comment3.user.id,
                    u"name": u"John Doe"
                },
                u"text": u"foo"
            },
            {
                u"user": None,
                u"text": u"bar"
            },
            {
                u"user": {
                    u"id": comment5.user.id,
                    u"name": u"Jane Doe"
                },
                u"text": u"baz"
            },
        ],
        u"contest_legs": {
            u"classic": [],
            u"triangle": []
        },
        u"phases": [],
        u"performance": {
            u"circling": [],
            u"cruise": {}
        },
    }
Beispiel #6
0
def test_manager_access_on_private_flight(db_session, client):
    jane = users.jane(admin=True)
    flight = flights.one(privacy_level=Flight.PrivacyLevel.PRIVATE,
                         igc_file=igcs.simple(owner=users.john()))
    add_fixtures(db_session, flight, jane)

    res = client.get('/flights/{id}'.format(id=flight.id), headers=auth_for(jane))
    assert res.status_code == 200
    assert 'flight' in res.json
Beispiel #7
0
def test_unfriendly_user_access_on_private_flight(db_session, client):
    jane = users.jane()
    flight = flights.one(
        privacy_level=Flight.PrivacyLevel.PRIVATE,
        igc_file=igcs.simple(owner=users.john()),
    )
    add_fixtures(db_session, flight, jane)

    res = client.get("/flights/{id}".format(id=flight.id), headers=auth_for(jane))
    assert res.status_code == 404
    assert res.json == {}
Beispiel #8
0
def test_with_club_parameter(db_session, client):
    john = users.john(club=clubs.lva())
    add_fixtures(db_session, john, users.jane(), users.max())

    res = client.get("/users")
    assert res.status_code == 200
    assert len(res.json["users"]) == 3

    res = client.get("/users?club={club}".format(club=john.club.id))
    assert res.status_code == 200
    assert len(res.json["users"]) == 1
    assert res.json == {u"users": [{u"id": john.id, u"name": u"John Doe"}]}
Beispiel #9
0
def test_with_club_parameter(db_session, client):
    john = users.john(club=clubs.lva())
    add_fixtures(db_session, john, users.jane(), users.max())

    res = client.get("/users")
    assert res.status_code == 200
    assert len(res.json["users"]) == 3

    res = client.get("/users?club={club}".format(club=john.club.id))
    assert res.status_code == 200
    assert len(res.json["users"]) == 1
    assert res.json == {u"users": [{u"id": john.id, u"name": u"John Doe"}]}
Beispiel #10
0
def test_unfriendly_user_access_on_private_flight(db_session, client):
    jane = users.jane()
    flight = flights.one(
        privacy_level=Flight.PrivacyLevel.PRIVATE,
        igc_file=igcs.simple(owner=users.john()),
    )
    add_fixtures(db_session, flight, jane)

    res = client.get("/flights/{id}".format(id=flight.id),
                     headers=auth_for(jane))
    assert res.status_code == 404
    assert res.json == {}
Beispiel #11
0
def test_comments(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    comment1 = flight_comments.yeah(flight=flight)
    comment2 = flight_comments.emoji(flight=flight)
    comment3 = flight_comments.yeah(flight=flight,
                                    user=flight.igc_file.owner,
                                    text='foo')
    comment4 = flight_comments.yeah(flight=flight, text='bar')
    comment5 = flight_comments.yeah(flight=flight,
                                    user=users.jane(),
                                    text='baz')
    add_fixtures(db_session, flight, comment1, comment2, comment3, comment4,
                 comment5)

    res = client.get('/flights/{id}?extended'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight':
        expected_basic_flight_json(flight),
        u'near_flights': [],
        u'comments': [{
            u'user': None,
            u'text': u'Yeah!',
        }, {
            u'user': None,
            u'text': u'\U0001f44d',
        }, {
            u'user': {
                u'id': comment3.user.id,
                u'name': u'John Doe'
            },
            u'text': u'foo',
        }, {
            u'user': None,
            u'text': u'bar',
        }, {
            u'user': {
                u'id': comment5.user.id,
                u'name': u'Jane Doe'
            },
            u'text': u'baz',
        }],
        u'contest_legs': {
            u'classic': [],
            u'triangle': [],
        },
        u'phases': [],
        u'performance': {
            u'circling': [],
            u'cruise': {},
        },
    }
Beispiel #12
0
def test_pilot_changing_clubless_co(db_session, client):
    """ Pilot is trying to change copilot to user without club. """

    john = users.john(club=clubs.lva())
    jane = users.jane()
    flight = flights.one(igc_file=igcs.simple(owner=john))
    add_fixtures(db_session, flight, john, jane)

    response = client.post('/flights/{id}'.format(id=flight.id), headers=auth_for(john), json={
        'pilotId': john.id,
        'copilotId': jane.id,
    })

    assert response.status_code == 422
Beispiel #13
0
def test_pilot_changing_disowned_flight(db_session, client):
    """ Unrelated user is trying to change pilots. """

    john = users.john(club=clubs.lva())
    jane = users.jane(club=john.club)
    max = users.max(club=clubs.sfn())
    flight = flights.one(igc_file=igcs.simple(owner=john))
    add_fixtures(db_session, flight, john, jane, max)

    response = client.post('/flights/{id}'.format(id=flight.id), headers=auth_for(jane), json={
        'pilotId': john.id,
        'copilotId': max.id,
    })

    assert response.status_code == 403
def test_pilot_changing_correct_with_co(db_session, client):
    """ Pilot is changing copilot to user from same club. """

    john = users.john(club=clubs.lva())
    jane = users.jane(club=john.club)
    flight = flights.one(igc_file=igcs.simple(owner=john))
    add_fixtures(db_session, flight, john, jane)

    response = client.post(
        "/flights/{id}".format(id=flight.id),
        headers=auth_for(john),
        json={"pilotId": john.id, "copilotId": jane.id},
    )

    assert response.status_code == 200
Beispiel #15
0
def test_comments(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    comment1 = flight_comments.yeah(flight=flight)
    comment2 = flight_comments.emoji(flight=flight)
    comment3 = flight_comments.yeah(flight=flight, user=flight.igc_file.owner, text=u'foo')
    comment4 = flight_comments.yeah(flight=flight, text=u'bar')
    comment5 = flight_comments.yeah(flight=flight, user=users.jane(), text=u'baz')
    add_fixtures(db_session, flight, comment1, comment2, comment3, comment4, comment5)

    res = client.get('/flights/{id}?extended'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight': expected_basic_flight_json(flight),
        u'near_flights': [],
        u'comments': [{
            u'user': None,
            u'text': u'Yeah!',
        }, {
            u'user': None,
            u'text': u'\U0001f44d',
        }, {
            u'user': {
                u'id': comment3.user.id,
                u'name': u'John Doe'
            },
            u'text': u'foo',
        }, {
            u'user': None,
            u'text': u'bar',
        }, {
            u'user': {
                u'id': comment5.user.id,
                u'name': u'Jane Doe'
            },
            u'text': u'baz',
        }],
        u'contest_legs': {
            u'classic': [],
            u'triangle': [],
        },
        u'phases': [],
        u'performance': {
            u'circling': [],
            u'cruise': {},
        },
    }
Beispiel #16
0
def test_with_club_parameter(db_session, client):
    john = users.john(club=clubs.lva())
    add_fixtures(db_session, john, users.jane(), users.max())

    res = client.get('/users')
    assert res.status_code == 200
    assert len(res.json['users']) == 3

    res = client.get('/users?club={club}'.format(club=john.club.id))
    assert res.status_code == 200
    assert len(res.json['users']) == 1
    assert res.json == {
        u'users': [{
            u'id': john.id,
            u'name': u'John Doe',
        }]
    }
Beispiel #17
0
def test_list_all(db_session, client):
    john = users.john()
    jane = users.jane()
    max = users.max()

    create_follower_notification(john, jane)
    create_follower_notification(john, max)
    create_follower_notification(jane, max)

    db_session.commit()

    res = client.get("/notifications", headers=auth_for(john))
    assert res.status_code == 200
    assert res.json == S({
        u"events":
        ExactSequence([
            {
                u"actor": {
                    u"id": int,
                    u"name": u"Max Mustermann"
                },
                u"id": int,
                u"time": Datetime("%Y-%m-%dT%H:%M:%S.%f+00:00"),
                u"type": u"follower",
                u"unread": True,
                u"user": {
                    u"id": int,
                    u"name": u"John Doe"
                },
            },
            {
                u"actor": {
                    u"id": int,
                    u"name": u"Jane Doe"
                },
                u"id": int,
                u"time": Datetime("%Y-%m-%dT%H:%M:%S.%f+00:00"),
                u"type": u"follower",
                u"unread": True,
                u"user": {
                    u"id": int,
                    u"name": u"John Doe"
                },
            },
        ])
    })
Beispiel #18
0
def test_pilot_changing_correct_with_co(db_session, client):
    """ Pilot is changing copilot to user from same club. """

    john = users.john(club=clubs.lva())
    jane = users.jane(club=john.club)
    flight = flights.one(igc_file=igcs.simple(owner=john))
    add_fixtures(db_session, flight, john, jane)

    response = client.post(
        "/flights/{id}".format(id=flight.id),
        headers=auth_for(john),
        json={
            "pilotId": john.id,
            "copilotId": jane.id
        },
    )

    assert response.status_code == 200
Beispiel #19
0
def test_search_doe(db_session, client):
    john = users.john()
    jane = users.jane()

    add_fixtures(db_session, john, jane, clubs.lva(), clubs.sfn(), airports.merzbrueck(), airports.meiersberg())

    res = client.get('/search?text=doe')
    assert res.status_code == 200
    assert res.json == {
        'results': [{
            'id': jane.id,
            'type': 'user',
            'name': 'Jane Doe',
        }, {
            'id': john.id,
            'type': 'user',
            'name': 'John Doe',
        }],
    }
Beispiel #20
0
def test_following(db_session, client):
    john = users.john()
    jane = users.jane()
    add_fixtures(db_session, john, jane)
    Follower.follow(john, jane)

    res = client.get("/users/{id}".format(id=john.id))
    assert res.status_code == 200
    assert res.json["following"] == 1

    res = client.get("/users/{id}".format(id=jane.id))
    assert res.status_code == 200
    assert res.json["followers"] == 1
    assert "followed" not in res.json

    res = client.get("/users/{id}".format(id=jane.id), headers=auth_for(john))
    assert res.status_code == 200
    assert res.json["followers"] == 1
    assert res.json["followed"] == True
Beispiel #21
0
def test_search_doe(db_session, client):
    john = users.john()
    jane = users.jane()

    add_fixtures(db_session, john, jane, clubs.lva(), clubs.sfn(), airports.merzbrueck(), airports.meiersberg())

    res = client.get('/search?text=doe')
    assert res.status_code == 200
    assert res.json == {
        'results': [{
            'id': jane.id,
            'type': 'user',
            'name': 'Jane Doe',
        }, {
            'id': john.id,
            'type': 'user',
            'name': 'John Doe',
        }],
    }
Beispiel #22
0
def test_search_doe(db_session, client):
    john = users.john()
    jane = users.jane()

    add_fixtures(
        db_session,
        john,
        jane,
        clubs.lva(),
        clubs.sfn(),
        airports.merzbrueck(),
        airports.meiersberg(),
    )

    res = client.get("/search?text=doe")
    assert res.status_code == 200
    assert res.json == {
        "results": [
            {"id": jane.id, "type": "user", "name": "Jane Doe"},
            {"id": john.id, "type": "user", "name": "John Doe"},
        ]
    }
Beispiel #23
0
def test_search(db_session, client):
    edka = airports.merzbrueck()
    lva = clubs.lva()

    add_fixtures(db_session, users.john(), users.jane(), lva, clubs.sfn(), edka, airports.meiersberg())

    res = client.get('/search?text=aachen')
    assert res.status_code == 200
    assert res.json == {
        'results': [{
            'id': edka.id,
            'type': 'airport',
            'name': 'Aachen Merzbruck',
            'icao': 'EDKA',
            'frequency': '122.875',
        }, {
            'id': lva.id,
            'type': 'club',
            'name': 'LV Aachen',
            'website': 'http://www.lv-aachen.de',
        }],
    }
Beispiel #24
0
def test_search(db_session, client):
    edka = airports.merzbrueck()
    lva = clubs.lva()

    add_fixtures(db_session, users.john(), users.jane(), lva, clubs.sfn(), edka, airports.meiersberg())

    res = client.get('/search?text=aachen')
    assert res.status_code == 200
    assert res.json == {
        'results': [{
            'id': edka.id,
            'type': 'airport',
            'name': 'Aachen Merzbruck',
            'icao': 'EDKA',
            'frequency': '122.875',
        }, {
            'id': lva.id,
            'type': 'club',
            'name': 'LV Aachen',
            'website': 'http://www.lv-aachen.de',
        }],
    }
Beispiel #25
0
def test_list_all(db_session, client):
    john = users.john()
    jane = users.jane()
    max = users.max()

    create_follower_notification(john, jane)
    create_follower_notification(john, max)
    create_follower_notification(jane, max)

    db_session.commit()

    res = client.get("/notifications", headers=auth_for(john))
    assert res.status_code == 200
    assert res.json == S(
        {
            u"events": ExactSequence(
                [
                    {
                        u"actor": {u"id": int, u"name": u"Max Mustermann"},
                        u"id": int,
                        u"time": Datetime("%Y-%m-%dT%H:%M:%S.%f+00:00"),
                        u"type": u"follower",
                        u"unread": True,
                        u"user": {u"id": int, u"name": u"John Doe"},
                    },
                    {
                        u"actor": {u"id": int, u"name": u"Jane Doe"},
                        u"id": int,
                        u"time": Datetime("%Y-%m-%dT%H:%M:%S.%f+00:00"),
                        u"type": u"follower",
                        u"unread": True,
                        u"user": {u"id": int, u"name": u"John Doe"},
                    },
                ]
            )
        }
    )
Beispiel #26
0
def test_get_latest_default_max_age(db_session, client):
    """The default max_age is 6 hours"""
    utcnow = datetime(year=2020, month=12, day=20, hour=12)

    # Only the latest_fix should be returned
    john = users.john()
    fix = live_fix.create(john, utcnow - timedelta(hours=2), 10, 20)
    latest_fix = live_fix.create(john, utcnow - timedelta(minutes=5), 11, 21)

    # Fix older than 6h should not be returned
    jane = users.jane()
    old_fix = live_fix.create(jane, utcnow - timedelta(hours=7), 12, 22)

    add_fixtures(db_session, john, fix, latest_fix, jane, old_fix)

    with patch("skylines.model.tracking.datetime") as datetime_mock:
        datetime_mock.utcnow.return_value = utcnow

        res = client.get("/tracking/latest.json")

        assert res.status_code == 200
        assert res.json == {
            u"fixes": [{
                u"airspeed": 10,
                u"altitude": 100,
                u"ground_speed": 10,
                u"location": u"POINT(11.0 21.0)",
                u"pilot": {
                    u"id": john.id,
                    u"name": u"John Doe"
                },
                u"time": u"2020-12-20T11:55:00Z",
                u"track": 0,
                u"vario": 0,
            }]
        }
Beispiel #27
0
def test_meetings(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    flight2 = flights.one(
        igc_file=igcs.simple(owner=users.jane(), md5="foobar"))
    meeting1 = FlightMeetings(
        source=flight,
        destination=flight2,
        start_time=datetime(2016, 4, 3, 12, 34, 56),
        end_time=datetime(2016, 4, 3, 12, 38, 1),
    )
    meeting2 = FlightMeetings(
        source=flight2,
        destination=flight,
        start_time=datetime(2016, 4, 3, 12, 56, 36),
        end_time=datetime(2016, 4, 3, 13, 1, 31),
    )
    add_fixtures(db_session, flight, flight2, meeting1, meeting2)

    res = client.get("/flights/{id}?extended".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight":
        expected_basic_flight_json(flight),
        u"near_flights": [{
            u"flight": {
                u"id": flight2.id,
                u"pilot": {
                    u"id": flight2.pilot.id,
                    u"name": u"Jane Doe"
                },
                u"pilotName": None,
                u"copilot": None,
                u"copilotName": None,
                u"model": None,
                u"registration": None,
                u"competitionId": None,
                u"igcFile": {
                    u"filename": u"simple.igc",
                    u"date": u"2011-06-18",
                    u"registration": None,
                    u"owner": {
                        u"id": flight2.igc_file.owner.id,
                        u"name": u"Jane Doe",
                    },
                    u"model": None,
                    u"competitionId": None,
                },
            },
            u"times": [
                {
                    u"start": u"2016-04-03T12:34:56+00:00",
                    u"end": u"2016-04-03T12:38:01+00:00",
                },
                {
                    u"start": u"2016-04-03T12:56:36+00:00",
                    u"end": u"2016-04-03T13:01:31+00:00",
                },
            ],
        }],
        u"comments": [],
        u"contest_legs": {
            u"classic": [],
            u"triangle": []
        },
        u"phases": [],
        u"performance": {
            u"circling": [],
            u"cruise": {}
        },
    }
Beispiel #28
0
def test_event_types(db_session, client):
    john = users.john()
    jane = users.jane()
    flight = flights.one(igc_file=igcs.simple(owner=john))
    flight_comment = flight_comments.emoji(flight=flight)

    flight_event = events.flight(actor=john, flight=flight)
    flight_comment_event = events.flight_comment(actor=john, flight=flight, flight_comment=flight_comment)
    follower_event = events.follower(actor=john, user=jane)
    new_user_event = events.new_user(actor=jane)
    club_join_event = events.club_join(actor=john, club=clubs.lva())
    add_fixtures(db_session, flight_event, flight_comment_event, follower_event, new_user_event, club_join_event)

    res = client.get('/timeline')
    assert res.status_code == 200
    assert res.json == {
        'events': [{
            'id': club_join_event.id,
            'type': 'club-join',
            'time': '2017-02-15T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'club': {
                'id': club_join_event.club.id,
                'name': 'LV Aachen',
            },
        }, {
            'id': new_user_event.id,
            'type': 'new-user',
            'time': '2017-02-14T12:34:56',
            'actor': {
                'id': jane.id,
                'name': 'Jane Doe',
            },
        }, {
            'id': follower_event.id,
            'type': 'follower',
            'time': '2017-02-13T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'user': {
                'id': jane.id,
                'name': 'Jane Doe',
            },
        }, {
            'id': flight_event.id,
            'type': 'flight-upload',
            'time': '2017-02-12T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'flight': {
                'id': flight.id,
                'date': '2011-06-18',
                'pilot_id': john.id,
                'copilot_id': None,
                'distance': None,
            },
        }, {
            'id': flight_comment_event.id,
            'type': 'flight-comment',
            'time': '2017-02-11T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'flightComment': {
                'id': flight_comment.id,
            },
            'flight': {
                'id': flight.id,
                'date': '2011-06-18',
                'pilot_id': john.id,
                'copilot_id': None,
                'distance': None,
            },
        }]
    }
Beispiel #29
0
def test_filled_flight(db_session, client):
    lva = clubs.lva()
    john = users.john(club=lva)
    jane = users.jane()
    flight = flights.filled(
        pilot=john,
        pilot_name=u"johnny_d",
        co_pilot=jane,
        co_pilot_name=u"jane",
        club=lva,
        model=aircraft_models.nimeta(),
        takeoff_airport=airports.meiersberg(),
        landing_airport=airports.merzbrueck(),
        igc_file=igcs.filled(owner=john),
    )
    add_fixtures(db_session, flight, traces.olc_classic(flight=flight))

    res = client.get("/flights/{id}".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight": {
            u"id": flight.id,
            u"timeCreated": u"2016-12-30T11:23:45+00:00",
            u"pilot": {
                u"id": john.id,
                u"name": u"John Doe"
            },
            u"pilotName": u"johnny_d",
            u"copilot": {
                u"id": jane.id,
                u"name": u"Jane Doe"
            },
            u"copilotName": u"jane",
            u"club": {
                u"id": lva.id,
                u"name": u"LV Aachen"
            },
            u"model": {
                u"id": flight.model_id,
                u"name": u"Nimeta",
                u"type": u"glider",
                u"index": 112,
            },
            u"registration": u"D-1234",
            u"competitionId": u"701",
            u"scoreDate": u"2011-06-18",
            u"takeoffTime": u"2016-12-30T11:12:23+00:00",
            u"scoreStartTime": u"2016-12-30T11:17:23+00:00",
            u"scoreEndTime": u"2016-12-30T16:04:40+00:00",
            u"landingTime": u"2016-12-30T16:15:40+00:00",
            u"takeoffAirport": {
                u"id": flight.takeoff_airport.id,
                u"name": u"Meiersberg",
                u"countryCode": u"DE",
            },
            u"landingAirport": {
                u"id": flight.landing_airport.id,
                u"name": u"Aachen Merzbruck",
                u"countryCode": u"DE",
            },
            u"distance": 512,
            u"triangleDistance": 432,
            u"rawScore": 799.0,
            u"score": 713.3928571428571,
            u"speed": 30.84579717542964,
            u"privacyLevel": 0,
            u"igcFile": {
                u"owner": {
                    u"id": john.id,
                    u"name": u"John Doe"
                },
                u"filename": u"abc1234d.igc",
                u"registration": u"D-4449",
                u"competitionId": u"TH",
                u"model": u"Hornet",
                u"date": u"2017-01-15",
            },
        }
    }
Beispiel #30
0
def test_filled_flight(db_session, client):
    lva = clubs.lva()
    john = users.john(club=lva)
    jane = users.jane()
    flight = flights.filled(
        pilot=john,
        pilot_name=u"johnny_d",
        co_pilot=jane,
        co_pilot_name=u"jane",
        club=lva,
        model=aircraft_models.nimeta(),
        takeoff_airport=airports.meiersberg(),
        landing_airport=airports.merzbrueck(),
        igc_file=igcs.filled(owner=john),
    )
    add_fixtures(db_session, flight, traces.olc_classic(flight=flight))

    res = client.get("/flights/{id}".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight": {
            u"id": flight.id,
            u"timeCreated": u"2016-12-30T11:23:45+00:00",
            u"pilot": {u"id": john.id, u"name": u"John Doe"},
            u"pilotName": u"johnny_d",
            u"copilot": {u"id": jane.id, u"name": u"Jane Doe"},
            u"copilotName": u"jane",
            u"club": {u"id": lva.id, u"name": u"LV Aachen"},
            u"model": {
                u"id": flight.model_id,
                u"name": u"Nimeta",
                u"type": u"glider",
                u"index": 112,
            },
            u"registration": u"D-1234",
            u"competitionId": u"701",
            u"scoreDate": u"2011-06-18",
            u"takeoffTime": u"2016-12-30T11:12:23+00:00",
            u"scoreStartTime": u"2016-12-30T11:17:23+00:00",
            u"scoreEndTime": u"2016-12-30T16:04:40+00:00",
            u"landingTime": u"2016-12-30T16:15:40+00:00",
            u"takeoffAirport": {
                u"id": flight.takeoff_airport.id,
                u"name": u"Meiersberg",
                u"countryCode": u"DE",
            },
            u"landingAirport": {
                u"id": flight.landing_airport.id,
                u"name": u"Aachen Merzbruck",
                u"countryCode": u"DE",
            },
            u"distance": 512,
            u"triangleDistance": 432,
            u"rawScore": 799.0,
            u"score": 713.3928571428571,
            u"speed": 30.84579717542964,
            u"privacyLevel": 0,
            u"igcFile": {
                u"owner": {u"id": john.id, u"name": u"John Doe"},
                u"filename": u"abc1234d.igc",
                u"registration": u"D-4449",
                u"competitionId": u"TH",
                u"model": u"Hornet",
                u"date": u"2017-01-15",
            },
        }
    }
Beispiel #31
0
def test_meetings(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    flight2 = flights.one(igc_file=igcs.simple(owner=users.jane(), md5="foobar"))
    meeting1 = FlightMeetings(
        source=flight,
        destination=flight2,
        start_time=datetime(2016, 4, 3, 12, 34, 56),
        end_time=datetime(2016, 4, 3, 12, 38, 1),
    )
    meeting2 = FlightMeetings(
        source=flight2,
        destination=flight,
        start_time=datetime(2016, 4, 3, 12, 56, 36),
        end_time=datetime(2016, 4, 3, 13, 1, 31),
    )
    add_fixtures(db_session, flight, flight2, meeting1, meeting2)

    res = client.get("/flights/{id}?extended".format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u"flight": expected_basic_flight_json(flight),
        u"near_flights": [
            {
                u"flight": {
                    u"id": flight2.id,
                    u"pilot": {u"id": flight2.pilot.id, u"name": u"Jane Doe"},
                    u"pilotName": None,
                    u"copilot": None,
                    u"copilotName": None,
                    u"model": None,
                    u"registration": None,
                    u"competitionId": None,
                    u"igcFile": {
                        u"filename": u"simple.igc",
                        u"date": u"2011-06-18",
                        u"registration": None,
                        u"owner": {
                            u"id": flight2.igc_file.owner.id,
                            u"name": u"Jane Doe",
                        },
                        u"model": None,
                        u"competitionId": None,
                    },
                },
                u"times": [
                    {
                        u"start": u"2016-04-03T12:34:56+00:00",
                        u"end": u"2016-04-03T12:38:01+00:00",
                    },
                    {
                        u"start": u"2016-04-03T12:56:36+00:00",
                        u"end": u"2016-04-03T13:01:31+00:00",
                    },
                ],
            }
        ],
        u"comments": [],
        u"contest_legs": {u"classic": [], u"triangle": []},
        u"phases": [],
        u"performance": {u"circling": [], u"cruise": {}},
    }
Beispiel #32
0
def test_meetings(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    flight2 = flights.one(igc_file=igcs.simple(owner=users.jane(), md5='foobar'))
    meeting1 = FlightMeetings(
        source=flight,
        destination=flight2,
        start_time=datetime(2016, 4, 3, 12, 34, 56),
        end_time=datetime(2016, 4, 3, 12, 38, 1),
    )
    meeting2 = FlightMeetings(
        source=flight2,
        destination=flight,
        start_time=datetime(2016, 4, 3, 12, 56, 36),
        end_time=datetime(2016, 4, 3, 13, 1, 31),
    )
    add_fixtures(db_session, flight, flight2, meeting1, meeting2)

    res = client.get('/flights/{id}?extended'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight': expected_basic_flight_json(flight),
        u'near_flights': [{
            u'flight': {
                u'id': flight2.id,
                u'pilot': {
                    u'id': flight2.pilot.id,
                    u'name': u'Jane Doe',
                },
                u'pilotName': None,
                u'copilot': None,
                u'copilotName': None,
                u'model': None,
                u'registration': None,
                u'competitionId': None,
                u'igcFile': {
                    u'filename': u'simple.igc',
                    u'date': u'2011-06-18',
                    u'registration': None,
                    u'owner': {
                        u'id': flight2.igc_file.owner.id,
                        u'name': u'Jane Doe',
                    },
                    u'model': None,
                    u'competitionId': None,
                },
            },
            u'times': [{
                u'start': u'2016-04-03T12:34:56+00:00',
                u'end': u'2016-04-03T12:38:01+00:00',
            }, {
                u'start': u'2016-04-03T12:56:36+00:00',
                u'end': u'2016-04-03T13:01:31+00:00',
            }],
        }],
        u'comments': [],
        u'contest_legs': {
            u'classic': [],
            u'triangle': [],
        },
        u'phases': [],
        u'performance': {
            u'circling': [],
            u'cruise': {},
        },
    }
Beispiel #33
0
def test_filled_flight(db_session, client):
    lva = clubs.lva()
    john = users.john(club=lva)
    jane = users.jane()
    flight = flights.filled(
        pilot=john,
        pilot_name=u'johnny_d',
        co_pilot=jane,
        co_pilot_name=u'jane',
        club=lva,
        model=aircraft_models.nimeta(),
        takeoff_airport=airports.meiersberg(),
        landing_airport=airports.merzbrueck(),
        igc_file=igcs.filled(owner=john)
    )
    add_fixtures(db_session, flight, traces.olc_classic(flight=flight))

    res = client.get('/flights/{id}'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight': {
            u'id': flight.id,
            u'timeCreated': u'2016-12-30T11:23:45+00:00',
            u'pilot': {
                u'id': john.id,
                u'name': u'John Doe'
            },
            u'pilotName': u'johnny_d',
            u'copilot': {
                u'id': jane.id,
                u'name': u'Jane Doe'
            },
            u'copilotName': u'jane',
            u'club': {
                u'id': lva.id,
                u'name': u'LV Aachen',
            },
            u'model': {
                u'id': flight.model_id,
                u'name': u'Nimeta',
                u'type': u'glider',
                u'index': 112,
            },
            u'registration': u'D-1234',
            u'competitionId': u'701',
            u'scoreDate': u'2011-06-18',
            u'takeoffTime': u'2016-12-30T11:12:23+00:00',
            u'scoreStartTime': u'2016-12-30T11:17:23+00:00',
            u'scoreEndTime': u'2016-12-30T16:04:40+00:00',
            u'landingTime': u'2016-12-30T16:15:40+00:00',
            u'takeoffAirport': {
                u'id': flight.takeoff_airport.id,
                u'name': u'Meiersberg',
                u'countryCode': u'DE'
            },
            u'landingAirport': {
                u'id': flight.landing_airport.id,
                u'name': u'Aachen Merzbruck',
                u'countryCode': u'DE',
            },
            u'distance': 512,
            u'triangleDistance': 432,
            u'rawScore': 799.0,
            u'score': 713.0,
            u'speed': 30.84579717542964,
            u'privacyLevel': 0,
            u'igcFile': {
                u'owner': {
                    u'id': john.id,
                    u'name': u'John Doe'
                },
                u'filename': u'abc1234d.igc',
                u'registration': u'D-4449',
                u'competitionId': u'TH',
                u'model': u'Hornet',
                u'date': u'2017-01-15',
            },
        }
    }
Beispiel #34
0
def test_filled_flight(db_session, client):
    lva = clubs.lva()
    john = users.john(club=lva)
    jane = users.jane()
    flight = flights.filled(pilot=john,
                            pilot_name='johnny_d',
                            co_pilot=jane,
                            co_pilot_name='jane',
                            club=lva,
                            model=aircraft_models.nimeta(),
                            takeoff_airport=airports.meiersberg(),
                            landing_airport=airports.merzbrueck(),
                            igc_file=igcs.filled(owner=john))
    add_fixtures(db_session, flight, traces.olc_classic(flight=flight))

    res = client.get('/flights/{id}'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight': {
            u'id': flight.id,
            u'timeCreated': u'2016-12-30T11:23:45+00:00',
            u'pilot': {
                u'id': john.id,
                u'name': u'John Doe'
            },
            u'pilotName': u'johnny_d',
            u'copilot': {
                u'id': jane.id,
                u'name': u'Jane Doe'
            },
            u'copilotName': u'jane',
            u'club': {
                u'id': lva.id,
                u'name': u'LV Aachen',
            },
            u'model': {
                u'id': flight.model_id,
                u'name': u'Nimeta',
                u'type': u'glider',
                u'index': 112,
            },
            u'registration': u'D-1234',
            u'competitionId': u'701',
            u'scoreDate': u'2011-06-18',
            u'takeoffTime': u'2016-12-30T11:12:23+00:00',
            u'scoreStartTime': u'2016-12-30T11:17:23+00:00',
            u'scoreEndTime': u'2016-12-30T16:04:40+00:00',
            u'landingTime': u'2016-12-30T16:15:40+00:00',
            u'takeoffAirport': {
                u'id': flight.takeoff_airport.id,
                u'name': u'Meiersberg',
                u'countryCode': u'DE'
            },
            u'landingAirport': {
                u'id': flight.landing_airport.id,
                u'name': u'Aachen Merzbruck',
                u'countryCode': u'DE',
            },
            u'distance': 512,
            u'triangleDistance': 432,
            u'rawScore': 799.0,
            u'score': 713.0,
            u'speed': 30.84579717542964,
            u'privacyLevel': 0,
            u'igcFile': {
                u'owner': {
                    u'id': john.id,
                    u'name': u'John Doe'
                },
                u'filename': u'abc1234d.igc',
                u'registration': u'D-4449',
                u'competitionId': u'TH',
                u'model': u'Hornet',
                u'date': u'2017-01-15',
            },
        }
    }
Beispiel #35
0
def test_meetings(db_session, client):
    flight = flights.one(igc_file=igcs.simple(owner=users.john()))
    flight2 = flights.one(
        igc_file=igcs.simple(owner=users.jane(), md5='foobar'))
    meeting1 = FlightMeetings(
        source=flight,
        destination=flight2,
        start_time=datetime(2016, 4, 3, 12, 34, 56),
        end_time=datetime(2016, 4, 3, 12, 38, 1),
    )
    meeting2 = FlightMeetings(
        source=flight2,
        destination=flight,
        start_time=datetime(2016, 4, 3, 12, 56, 36),
        end_time=datetime(2016, 4, 3, 13, 1, 31),
    )
    add_fixtures(db_session, flight, flight2, meeting1, meeting2)

    res = client.get('/flights/{id}?extended'.format(id=flight.id))
    assert res.status_code == 200
    assert res.json == {
        u'flight':
        expected_basic_flight_json(flight),
        u'near_flights': [{
            u'flight': {
                u'id': flight2.id,
                u'pilot': {
                    u'id': flight2.pilot.id,
                    u'name': u'Jane Doe',
                },
                u'pilotName': None,
                u'copilot': None,
                u'copilotName': None,
                u'model': None,
                u'registration': None,
                u'competitionId': None,
                u'igcFile': {
                    u'filename': u'simple.igc',
                    u'date': u'2011-06-18',
                    u'registration': None,
                    u'owner': {
                        u'id': flight2.igc_file.owner.id,
                        u'name': u'Jane Doe',
                    },
                    u'model': None,
                    u'competitionId': None,
                },
            },
            u'times': [{
                u'start': u'2016-04-03T12:34:56+00:00',
                u'end': u'2016-04-03T12:38:01+00:00',
            }, {
                u'start': u'2016-04-03T12:56:36+00:00',
                u'end': u'2016-04-03T13:01:31+00:00',
            }],
        }],
        u'comments': [],
        u'contest_legs': {
            u'classic': [],
            u'triangle': [],
        },
        u'phases': [],
        u'performance': {
            u'circling': [],
            u'cruise': {},
        },
    }
Beispiel #36
0
def test_get_live_default_max_age(db_session, client):
    """The default max_age is 12 hours"""
    utcnow = datetime(year=2020, month=12, day=20, hour=20)

    john = users.john()
    john_fixes = []
    for age_hour in range(14, 0, -1):
        time = utcnow - timedelta(hours=age_hour)
        john_fixes.append(live_fix.create(john, time, 10, 20))

    jane = users.jane()
    jane_fixes = []
    for age_hour in range(14, 0, -1):
        time = utcnow - timedelta(hours=age_hour, minutes=30)
        jane_fixes.append(live_fix.create(jane, time, 11, 21))

    add_fixtures(db_session, john, *(john_fixes + jane_fixes))

    with patch("skylines.model.tracking.datetime") as datetime_mock:
        datetime_mock.utcnow.return_value = utcnow

        res = client.get("/live/{john},{jane}".format(john=john.id,
                                                      jane=jane.id))

        assert res.status_code == 200
        json = res.json

        assert json == {
            u"flights": [
                {
                    u"additional": {
                        u"color": u"#2b56d8",
                        u"competition_id": u"JD"
                    },
                    u"barogram_h": u"eE???????????",
                    u"barogram_t": u"_gw@_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F",
                    u"contests": None,
                    u"elevations_h": u"????????????",
                    u"elevations_t": u"_gw@_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F",
                    u"enl": u"",
                    u"geoid": 26.504,
                    u"points": u"_gayB_c`|@??????????????????????",
                    u"sfid": john.id,
                },
                {
                    u"additional": {
                        u"color": u"#822bd8",
                        u"competition_id": u"JD"
                    },
                    u"barogram_h": u"eE??????????",
                    u"barogram_t": u"owz@_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F",
                    u"contests": None,
                    u"elevations_h": u"???????????",
                    u"elevations_t": u"owz@_`F_`F_`F_`F_`F_`F_`F_`F_`F_`F",
                    u"enl": u"",
                    u"geoid": 25.013,
                    u"points": u"_qd_C_mcbA????????????????????",
                    u"sfid": jane.id,
                },
            ],
            u"pilots": [
                {
                    u"club": None,
                    u"color": u"#2b56d8",
                    u"firstName": u"John",
                    u"followers": 0,
                    u"following": 0,
                    u"id": john.id,
                    u"lastName": u"Doe",
                    u"name": u"John Doe",
                    u"trackingCallsign": None,
                    u"trackingDelay": 0,
                },
                {
                    u"club": None,
                    u"color": u"#822bd8",
                    u"firstName": u"Jane",
                    u"followers": 0,
                    u"following": 0,
                    u"id": jane.id,
                    u"lastName": u"Doe",
                    u"name": u"Jane Doe",
                    u"trackingCallsign": None,
                    u"trackingDelay": 0,
                },
            ],
        }

        expected_fixes = list(
            filter(lambda f: f.time >= utcnow - timedelta(hours=12),
                   john_fixes))
        assert decode_time(
            json[u"flights"][0][u"barogram_t"]) == get_fixes_times_seconds(
                expected_fixes)

        expected_fixes = list(
            filter(lambda f: f.time >= utcnow - timedelta(hours=12),
                   jane_fixes))
        assert decode_time(
            json[u"flights"][1][u"barogram_t"]) == get_fixes_times_seconds(
                expected_fixes)
Beispiel #37
0
def test_event_types(db_session, client):
    john = users.john()
    jane = users.jane()
    lva = clubs.lva()
    add_fixtures(db_session, john, jane, lva)

    flight = flights.one(igc_file=igcs.simple(owner=john))
    flight_comment = flight_comments.emoji(flight=flight, user=john)
    add_fixtures(db_session, flight, flight_comment)

    flight_event = events.flight(flight)
    flight_comment_event = events.flight_comment(flight_comment)
    follower_event = events.follower(actor=john, user=jane)
    new_user_event = events.new_user(jane)
    club_join_event = events.club_join(actor=john, club=lva)
    add_fixtures(
        db_session,
        flight_event,
        flight_comment_event,
        follower_event,
        new_user_event,
        club_join_event,
    )

    res = client.get("/timeline")
    assert res.status_code == 200
    assert res.json == {
        "events": [
            {
                "id": club_join_event.id,
                "type": "club-join",
                "time": "2017-02-15T12:34:56+00:00",
                "actor": {
                    "id": john.id,
                    "name": "John Doe"
                },
                "club": {
                    "id": club_join_event.club.id,
                    "name": "LV Aachen"
                },
            },
            {
                "id": new_user_event.id,
                "type": "new-user",
                "time": "2017-02-14T12:34:56+00:00",
                "actor": {
                    "id": jane.id,
                    "name": "Jane Doe"
                },
            },
            {
                "id": follower_event.id,
                "type": "follower",
                "time": "2017-02-13T12:34:56+00:00",
                "actor": {
                    "id": john.id,
                    "name": "John Doe"
                },
                "user": {
                    "id": jane.id,
                    "name": "Jane Doe"
                },
            },
            {
                "id": flight_event.id,
                "type": "flight-upload",
                "time": "2017-02-12T12:34:56+00:00",
                "actor": {
                    "id": john.id,
                    "name": "John Doe"
                },
                "flight": {
                    "id": flight.id,
                    "date": "2011-06-18",
                    "pilot_id": john.id,
                    "copilot_id": None,
                    "distance": None,
                },
            },
            {
                "id": flight_comment_event.id,
                "type": "flight-comment",
                "time": "2017-02-11T12:34:56+00:00",
                "actor": {
                    "id": john.id,
                    "name": "John Doe"
                },
                "flightComment": {
                    "id": flight_comment.id
                },
                "flight": {
                    "id": flight.id,
                    "date": "2011-06-18",
                    "pilot_id": john.id,
                    "copilot_id": None,
                    "distance": None,
                },
            },
        ]
    }
Beispiel #38
0
def test_event_types(db_session, client):
    john = users.john()
    jane = users.jane()
    lva = clubs.lva()
    add_fixtures(db_session, john, jane, lva)

    flight = flights.one(igc_file=igcs.simple(owner=john))
    flight_comment = flight_comments.emoji(flight=flight, user=john)
    add_fixtures(db_session, flight, flight_comment)

    flight_event = events.flight(flight)
    flight_comment_event = events.flight_comment(flight_comment)
    follower_event = events.follower(actor=john, user=jane)
    new_user_event = events.new_user(jane)
    club_join_event = events.club_join(actor=john, club=lva)
    add_fixtures(db_session, flight_event, flight_comment_event,
                 follower_event, new_user_event, club_join_event)

    res = client.get('/timeline')
    assert res.status_code == 200
    assert res.json == {
        'events': [{
            'id': club_join_event.id,
            'type': 'club-join',
            'time': '2017-02-15T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'club': {
                'id': club_join_event.club.id,
                'name': 'LV Aachen',
            },
        }, {
            'id': new_user_event.id,
            'type': 'new-user',
            'time': '2017-02-14T12:34:56',
            'actor': {
                'id': jane.id,
                'name': 'Jane Doe',
            },
        }, {
            'id': follower_event.id,
            'type': 'follower',
            'time': '2017-02-13T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'user': {
                'id': jane.id,
                'name': 'Jane Doe',
            },
        }, {
            'id': flight_event.id,
            'type': 'flight-upload',
            'time': '2017-02-12T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'flight': {
                'id': flight.id,
                'date': '2011-06-18',
                'pilot_id': john.id,
                'copilot_id': None,
                'distance': None,
            },
        }, {
            'id': flight_comment_event.id,
            'type': 'flight-comment',
            'time': '2017-02-11T12:34:56',
            'actor': {
                'id': john.id,
                'name': 'John Doe',
            },
            'flightComment': {
                'id': flight_comment.id,
            },
            'flight': {
                'id': flight.id,
                'date': '2011-06-18',
                'pilot_id': john.id,
                'copilot_id': None,
                'distance': None,
            },
        }]
    }
Beispiel #39
0
def test_event_types(db_session, client):
    john = users.john()
    jane = users.jane()
    lva = clubs.lva()
    add_fixtures(db_session, john, jane, lva)

    flight = flights.one(igc_file=igcs.simple(owner=john))
    flight_comment = flight_comments.emoji(flight=flight, user=john)
    add_fixtures(db_session, flight, flight_comment)

    flight_event = events.flight(flight)
    flight_comment_event = events.flight_comment(flight_comment)
    follower_event = events.follower(actor=john, user=jane)
    new_user_event = events.new_user(jane)
    club_join_event = events.club_join(actor=john, club=lva)
    add_fixtures(
        db_session,
        flight_event,
        flight_comment_event,
        follower_event,
        new_user_event,
        club_join_event,
    )

    res = client.get("/timeline")
    assert res.status_code == 200
    assert res.json == {
        "events": [
            {
                "id": club_join_event.id,
                "type": "club-join",
                "time": "2017-02-15T12:34:56+00:00",
                "actor": {"id": john.id, "name": "John Doe"},
                "club": {"id": club_join_event.club.id, "name": "LV Aachen"},
            },
            {
                "id": new_user_event.id,
                "type": "new-user",
                "time": "2017-02-14T12:34:56+00:00",
                "actor": {"id": jane.id, "name": "Jane Doe"},
            },
            {
                "id": follower_event.id,
                "type": "follower",
                "time": "2017-02-13T12:34:56+00:00",
                "actor": {"id": john.id, "name": "John Doe"},
                "user": {"id": jane.id, "name": "Jane Doe"},
            },
            {
                "id": flight_event.id,
                "type": "flight-upload",
                "time": "2017-02-12T12:34:56+00:00",
                "actor": {"id": john.id, "name": "John Doe"},
                "flight": {
                    "id": flight.id,
                    "date": "2011-06-18",
                    "pilot_id": john.id,
                    "copilot_id": None,
                    "distance": None,
                },
            },
            {
                "id": flight_comment_event.id,
                "type": "flight-comment",
                "time": "2017-02-11T12:34:56+00:00",
                "actor": {"id": john.id, "name": "John Doe"},
                "flightComment": {"id": flight_comment.id},
                "flight": {
                    "id": flight.id,
                    "date": "2011-06-18",
                    "pilot_id": john.id,
                    "copilot_id": None,
                    "distance": None,
                },
            },
        ]
    }