summaryrefslogtreecommitdiff
path: root/patchwork/tests/api/test_cover.py
blob: 5eeb1902e1d17cc0cc7e2718db6e07e65136d20a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Patchwork - automated patch tracking system
# Copyright (C) 2016 Linaro Corporation
#
# SPDX-License-Identifier: GPL-2.0-or-later

import email.parser
import unittest

from django.conf import settings
from django.urls import reverse

from patchwork.tests.api import utils
from patchwork.tests.utils import create_cover
from patchwork.tests.utils import create_covers
from patchwork.tests.utils import create_maintainer
from patchwork.tests.utils import create_series
from patchwork.tests.utils import create_user

if settings.ENABLE_REST_API:
    from rest_framework import status


@unittest.skipUnless(settings.ENABLE_REST_API, 'requires ENABLE_REST_API')
class TestCoverLetterAPI(utils.APITestCase):
    fixtures = ['default_tags']

    @staticmethod
    def api_url(item=None, version=None):
        kwargs = {}
        if version:
            kwargs['version'] = version

        if item is None:
            return reverse('api-cover-list', kwargs=kwargs)
        kwargs['pk'] = item
        return reverse('api-cover-detail', kwargs=kwargs)

    def assertSerialized(self, cover_obj, cover_json):
        self.assertEqual(cover_obj.id, cover_json['id'])
        self.assertEqual(cover_obj.name, cover_json['name'])
        self.assertIn(cover_obj.get_mbox_url(), cover_json['mbox'])
        self.assertIn(cover_obj.get_absolute_url(), cover_json['web_url'])
        self.assertIn('comments', cover_json)

        # nested fields

        self.assertEqual(cover_obj.submitter.id,
                         cover_json['submitter']['id'])

        if hasattr(cover_obj, 'series'):
            self.assertEqual(1, len(cover_json['series']))
            self.assertEqual(cover_obj.series.id,
                             cover_json['series'][0]['id'])
        else:
            self.assertEqual([], cover_json['series'])

    def test_list_empty(self):
        """List cover letters when none are present."""
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(0, len(resp.data))

    def test_list_anonymous(self):
        """List cover letter as anonymous user."""
        # we specifically set series to None to test code that handles legacy
        # cover letters created before series existed
        cover = create_cover(series=None)

        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(1, len(resp.data))
        self.assertSerialized(cover, resp.data[0])

    @utils.store_samples('cover-list')
    def test_list_authenticated(self):
        """List cover letters as an authenticated user."""
        cover = create_cover()
        user = create_user()

        self.client.force_authenticate(user=user)
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(1, len(resp.data))
        self.assertSerialized(cover, resp.data[0])

    def test_list_filter_project(self):
        """Filter cover letters by project."""
        cover = create_cover()
        project = cover.project

        resp = self.client.get(self.api_url(), {'project': project.linkname})
        self.assertEqual([cover.id], [x['id'] for x in resp.data])

        resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
        self.assertEqual(0, len(resp.data))

    def test_list_filter_submitter(self):
        """Filter cover letter by submitter."""
        cover = create_cover()
        submitter = cover.submitter

        # test filtering by submitter, both ID and email
        resp = self.client.get(self.api_url(), {'submitter': submitter.id})
        self.assertEqual([cover.id], [x['id'] for x in resp.data])

        resp = self.client.get(self.api_url(), {
            'submitter': submitter.email})
        self.assertEqual([cover.id], [x['id'] for x in resp.data])

        resp = self.client.get(self.api_url(), {
            'submitter': 'test@example.org'})
        self.assertEqual(0, len(resp.data))

    @utils.store_samples('cover-list-1-0')
    def test_list_version_1_0(self):
        create_cover()

        resp = self.client.get(self.api_url(version='1.0'))
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(1, len(resp.data))
        self.assertIn('url', resp.data[0])
        self.assertNotIn('mbox', resp.data[0])
        self.assertNotIn('web_url', resp.data[0])

    def test_list_bug_335(self):
        """Ensure we retrieve the embedded series project once."""
        series = create_series()
        create_covers(5, series=series)

        with self.assertNumQueries(3):
            self.client.get(self.api_url())

    @utils.store_samples('cover-detail')
    def test_detail(self):
        """Validate we can get a specific cover letter."""
        cover_obj = create_cover(
            headers='Received: from somewhere\nReceived: from another place'
        )

        resp = self.client.get(self.api_url(cover_obj.id))
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertSerialized(cover_obj, resp.data)

        # Make sure we don't regress and all headers with the same key are
        # included in the response
        parsed_headers = email.parser.Parser().parsestr(cover_obj.headers,
                                                        True)
        for key, value in parsed_headers.items():
            self.assertIn(value, resp.data['headers'][key])

    @utils.store_samples('cover-detail-1-0')
    def test_detail_version_1_0(self):
        cover = create_cover()

        resp = self.client.get(self.api_url(cover.id, version='1.0'))
        self.assertIn('url', resp.data)
        self.assertNotIn('web_url', resp.data)
        self.assertNotIn('comments', resp.data)

    def test_create_update_delete(self):
        user = create_maintainer()
        user.is_superuser = True
        user.save()
        self.client.force_authenticate(user=user)

        resp = self.client.post(self.api_url(), {'name': 'test cover'})
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)

        resp = self.client.patch(self.api_url(), {'name': 'test cover'})
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)

        resp = self.client.delete(self.api_url())
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)