Exemple #1
0
    def test_nested_series(self):
        """Handle a series sent in-reply-to an existing series."""
        # create an old series with a "cover letter"
        msgids = [make_msgid()]
        project = create_project()
        series_v1 = create_series(project=project)
        create_series_reference(msgid=msgids[0], series=series_v1)

        # ...and three patches
        for i in range(3):
            msgids.append(make_msgid())
            create_series_reference(msgid=msgids[-1], series=series_v1)

        # now create a new series with "cover letter"
        msgids.append(make_msgid())
        series_v2 = create_series(project=project)
        ref_v2 = create_series_reference(msgid=msgids[-1], series=series_v2)

        # ...and the "first patch" of this new series
        msgid = make_msgid()
        email = self._create_email(msgid, msgids)
        series = find_series(project, email, get_or_create_author(email))

        # this should link to the second series - not the first
        self.assertEqual(len(msgids), 4 + 1)  # old series + new cover
        self.assertEqual(series, ref_v2.series)
Exemple #2
0
    def test_nested_series(self):
        """Handle a series sent in-reply-to an existing series."""
        # create an old series with a "cover letter"
        msgids = [make_msgid()]
        project = create_project()
        series_v1 = create_series(project=project)
        create_series_reference(msgid=msgids[0], series=series_v1)

        # ...and three patches
        for i in range(3):
            msgids.append(make_msgid())
            create_series_reference(msgid=msgids[-1], series=series_v1)

        # now create a new series with "cover letter"
        msgids.append(make_msgid())
        series_v2 = create_series(project=project)
        ref_v2 = create_series_reference(msgid=msgids[-1], series=series_v2)

        # ...and the "first patch" of this new series
        msgid = make_msgid()
        email = self._create_email(msgid, msgids)
        series = find_series(project, email)

        # this should link to the second series - not the first
        self.assertEqual(len(msgids), 4 + 1)  # old series + new cover
        self.assertEqual(series, ref_v2.series)
Exemple #3
0
    def test_list_old_version(self):
        """Validate that newer fields are dropped for older API versions."""
        create_series()

        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('web_url', resp.data[0])
Exemple #4
0
    def test_list_old_version(self):
        """Validate that newer fields are dropped for older API versions."""
        create_series()

        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('web_url', resp.data[0])
Exemple #5
0
    def test_list_filter_project(self):
        """Filter events by project."""
        events = self._create_events()
        project = events[0].project
        create_series()  # create series in a random project

        resp = self.client.get(self.api_url(), {'project': project.pk})
        # All but one event belongs to the same project
        self.assertEqual(8, len(resp.data))

        resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
        self.assertEqual(0, len(resp.data))
Exemple #6
0
 def test_series_created(self):
     series = utils.create_series()
     events = _get_events(series=series)
     self.assertEqual(events.count(), 1)
     self.assertEqual(events[0].category, Event.CATEGORY_SERIES_CREATED)
     self.assertEqual(events[0].project, series.project)
     self.assertEventFields(events[0])
Exemple #7
0
    def test_patch_dependencies_out_of_order(self):
        series = utils.create_series()
        series_patch_3 = utils.create_series_patch(series=series, number=3)
        series_patch_2 = utils.create_series_patch(series=series, number=2)

        # This should only raise the CATEGORY_PATCH_CREATED event for
        # both patches as they are both missing dependencies
        for series_patch in [series_patch_2, series_patch_3]:
            events = _get_events(patch=series_patch.patch)
            self.assertEqual(events.count(), 1)
            self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
            self.assertEventFields(events[0])

        series_patch_1 = utils.create_series_patch(series=series, number=1)

        # We should now see the CATEGORY_PATCH_COMPLETED event for all patches
        # as the dependencies for all have been met
        for series_patch in [series_patch_1, series_patch_2, series_patch_3]:
            events = _get_events(patch=series_patch.patch)
            self.assertEqual(events.count(), 2)
            self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
            self.assertEqual(events[1].category,
                             Event.CATEGORY_PATCH_COMPLETED)
            self.assertEventFields(events[0])
            self.assertEventFields(events[1])
Exemple #8
0
    def _create_events(self):
        """Create sample events.

        This one's a bit weird. While we could generate event models ourselves,
        it seems wiser to test the event machinery as many times as possible.
        As a result, we actually create a load of *other* objects, which will
        raise signals and trigger the remainder.
        """
        # series-created
        series = create_series()
        # patch-created, patch-completed, series-completed
        patch = create_patch(series=series)
        # cover-created
        create_cover(series=series)
        # check-created
        create_check(patch=patch)
        # patch-delegated, patch-state-changed
        actor = create_maintainer(project=patch.project)
        user = create_maintainer(project=patch.project)
        state = create_state()
        patch.delegate = user
        patch.state = state
        self.assertTrue(patch.is_editable(actor))
        patch.save()

        return Event.objects.all()
Exemple #9
0
 def test_series_created(self):
     series = utils.create_series()
     events = _get_events(series=series)
     self.assertEqual(events.count(), 1)
     self.assertEqual(events[0].category, Event.CATEGORY_SERIES_CREATED)
     self.assertEqual(events[0].project, series.project)
     self.assertEventFields(events[0])
Exemple #10
0
    def test_patch_dependencies_out_of_order(self):
        series = utils.create_series()
        patch_3 = utils.create_patch(series=series, number=3)
        patch_2 = utils.create_patch(series=series, number=2)

        # This should only raise the CATEGORY_PATCH_CREATED event for
        # both patches as they are both missing dependencies
        for patch in [patch_2, patch_3]:
            events = _get_events(patch=patch)
            self.assertEqual(events.count(), 1)
            self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
            self.assertEventFields(events[0])

        patch_1 = utils.create_patch(series=series, number=1)

        # We should now see the CATEGORY_PATCH_COMPLETED event for all patches
        # as the dependencies for all have been met
        for patch in [patch_1, patch_2, patch_3]:
            events = _get_events(patch=patch)
            self.assertEqual(events.count(), 2)
            self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
            self.assertEqual(events[1].category,
                             Event.CATEGORY_PATCH_COMPLETED)
            self.assertEventFields(events[0])
            self.assertEventFields(events[1])
Exemple #11
0
    def test_list_bug_335(self):
        """Ensure we retrieve the embedded series project in O(1)."""
        series = create_series()
        create_patches(5, series=series)

        with self.assertNumQueries(5):
            self.client.get(self.api_url())
Exemple #12
0
    def _create_series(self):
        project_obj = create_project(linkname='myproject')
        person_obj = create_person(email='*****@*****.**')
        series_obj = create_series(project=project_obj, submitter=person_obj)
        create_cover(series=series_obj)
        create_patch(series=series_obj)

        return series_obj
Exemple #13
0
    def _create_series(self):
        project_obj = create_project(linkname='myproject')
        person_obj = create_person(email='*****@*****.**')
        series_obj = create_series(project=project_obj, submitter=person_obj)
        create_cover(series=series_obj)
        create_patch(series=series_obj)

        return series_obj
Exemple #14
0
    def test_detail(self):
        """Validate we can get a specific series."""
        series = create_series()
        create_cover(series=series)

        resp = self.client.get(self.api_url(series.id))
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertSerialized(series, resp.data)
Exemple #15
0
    def test_series(self):
        series = create_series()
        patch_a = create_patch(series=series)
        patch_b = create_patch(series=series)

        response = self.client.get(reverse('series-mbox', args=[series.id]))

        self.assertContains(response, patch_a.content)
        self.assertContains(response, patch_b.content)
Exemple #16
0
    def test_series(self):
        series = create_series()
        patch_a = create_patch(series=series)
        patch_b = create_patch(series=series)

        response = self.client.get(reverse('series-mbox', args=[series.id]))

        self.assertContains(response, patch_a.content)
        self.assertContains(response, patch_b.content)
    def test_series(self):
        series = create_series()
        patch_a = create_patch(series=series)
        patch_b = create_patch(series=series)

        mbox = utils.series_to_mbox(series)

        self.assertIn(patch_a.content, mbox)
        self.assertIn(patch_b.content, mbox)
Exemple #18
0
    def test_patch_dependencies_missing(self):
        series = utils.create_series()
        patch = utils.create_patch(series=series, number=2)

        # This should only raise the CATEGORY_PATCH_CREATED event as
        # there is a missing dependency (patch 1)
        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 1)
        self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
        self.assertEventFields(events[0])
Exemple #19
0
    def test_patch_dependencies_missing(self):
        series = utils.create_series()
        patch = utils.create_patch(series=series, number=2)

        # This should only raise the CATEGORY_PATCH_CREATED event as
        # there is a missing dependency (patch 1)
        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 1)
        self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
        self.assertEventFields(events[0])
Exemple #20
0
    def test_list_bug_335(self):
        """Ensure we retrieve the embedded series project in O(1)."""
        series = create_series()
        create_patches(5, series=series)

        # TODO(stephenfin): Remove when we drop support for Django < 3.2
        num_queries = 7 if django.VERSION < (3, 2) else 5

        with self.assertNumQueries(num_queries):
            self.client.get(self.api_url())
    def test_list_bug_335(self):
        """Ensure we retrieve the embedded cover letter project in O(1)."""
        project_obj = create_project(linkname='myproject')
        person_obj = create_person(email='*****@*****.**')
        for i in range(10):
            series_obj = create_series(
                project=project_obj, submitter=person_obj,
            )
            create_cover(series=series_obj)
            create_patch(series=series_obj)

        with self.assertNumQueries(6):
            self.client.get(self.api_url())
Exemple #22
0
    def test_series_dropdown(self):
        patch = create_patch()
        series = [create_series() for x in range(5)]

        for series_ in series:
            series_.add_patch(patch, 1)

        response = self.client.get(
            reverse('patch-detail', kwargs={'patch_id': patch.id}))

        for series_ in series:
            self.assertContains(
                response,
                reverse('series-mbox', kwargs={'series_id': series_.id}))
Exemple #23
0
    def test_detail(self):
        """Validate we can get a specific series."""
        series = create_series()

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

        patch = create_patch(project=series.project)
        series.add_patch(patch, 1)
        resp = self.client.get(self.api_url(series.id))
        self.assertSerialized(series, resp.data)

        cover_letter = create_cover(project=series.project)
        series.add_cover_letter(cover_letter)
        resp = self.client.get(self.api_url(series.id))
        self.assertSerialized(series, resp.data)
Exemple #24
0
    def test_create_update_delete(self):
        """Ensure creates, updates and deletes aren't allowed"""
        user = create_maintainer()
        user.is_superuser = True
        user.save()
        self.client.force_authenticate(user=user)

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

        series = create_series()

        resp = self.client.patch(self.api_url(series.id), {'name': 'Test'})
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)

        resp = self.client.delete(self.api_url(series.id))
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)
Exemple #25
0
    def test_create_update_delete(self):
        """Ensure creates, updates and deletes aren't allowed"""
        user = create_maintainer()
        user.is_superuser = True
        user.save()
        self.client.force_authenticate(user=user)

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

        series = create_series()

        resp = self.client.patch(self.api_url(series.id), {'name': 'Test'})
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)

        resp = self.client.delete(self.api_url(series.id))
        self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)
Exemple #26
0
    def test_detail(self):
        """Validate we can get a specific series."""
        series = create_series()

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

        patch = create_patch(project=series.project)
        series.add_patch(patch, 1)
        resp = self.client.get(self.api_url(series.id))
        self.assertSerialized(series, resp.data)

        cover_letter = create_cover(project=series.project)
        series.add_cover_letter(cover_letter)
        resp = self.client.get(self.api_url(series.id))
        self.assertSerialized(series, resp.data)
Exemple #27
0
    def test_list(self):
        """Validate we can list series."""
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(0, len(resp.data))

        project_obj = create_project(linkname='myproject')
        person_obj = create_person(email='*****@*****.**')
        cover_obj = create_cover()
        series_obj = create_series(project=project_obj, submitter=person_obj)
        series_obj.add_cover_letter(cover_obj)
        create_series_patch(series=series_obj)

        # anonymous users
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(1, len(resp.data))
        series_rsp = resp.data[0]
        self.assertSerialized(series_obj, series_rsp)

        # authenticated user
        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))
        series_rsp = resp.data[0]
        self.assertSerialized(series_obj, series_rsp)

        # test filtering by project
        resp = self.client.get(self.api_url(), {'project': 'myproject'})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
        self.assertEqual(0, len(resp.data))

        # test filtering by owner, both ID and email
        resp = self.client.get(self.api_url(), {'submitter': person_obj.id})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(),
                               {'submitter': '*****@*****.**'})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(),
                               {'submitter': '*****@*****.**'})
        self.assertEqual(0, len(resp.data))
Exemple #28
0
    def test_list(self):
        """Validate we can list series."""
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(0, len(resp.data))

        project_obj = create_project(linkname='myproject')
        person_obj = create_person(email='*****@*****.**')
        series_obj = create_series(project=project_obj, submitter=person_obj)
        create_cover(series=series_obj)
        create_patch(series=series_obj)

        # anonymous users
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(1, len(resp.data))
        series_rsp = resp.data[0]
        self.assertSerialized(series_obj, series_rsp)

        # authenticated user
        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))
        series_rsp = resp.data[0]
        self.assertSerialized(series_obj, series_rsp)

        # test filtering by project
        resp = self.client.get(self.api_url(), {'project': 'myproject'})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
        self.assertEqual(0, len(resp.data))

        # test filtering by owner, both ID and email
        resp = self.client.get(self.api_url(), {'submitter': person_obj.id})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(), {
            'submitter': '*****@*****.**'})
        self.assertEqual([series_obj.id], [x['id'] for x in resp.data])
        resp = self.client.get(self.api_url(), {
            'submitter': '*****@*****.**'})
        self.assertEqual(0, len(resp.data))
Exemple #29
0
    def test_series_completed(self):
        """Validate 'series-completed' events."""
        series = utils.create_series(total=2)

        # the series has no patches associated with it so it's not yet complete
        events = _get_events(series=series)
        self.assertNotIn(Event.CATEGORY_SERIES_COMPLETED,
                         [x.category for x in events])

        # create the second of two patches in the series; series is still not
        # complete
        utils.create_patch(series=series, number=2)
        events = _get_events(series=series)
        self.assertNotIn(Event.CATEGORY_SERIES_COMPLETED,
                         [x.category for x in events])

        # now create the first patch, which will "complete" the series
        utils.create_patch(series=series, number=1)
        events = _get_events(series=series)
        self.assertIn(Event.CATEGORY_SERIES_COMPLETED,
                      [x.category for x in events])
Exemple #30
0
    def test_series_completed(self):
        """Validate 'series-completed' events."""
        series = utils.create_series(total=2)

        # the series has no patches associated with it so it's not yet complete
        events = _get_events(series=series)
        self.assertNotIn(Event.CATEGORY_SERIES_COMPLETED,
                         [x.category for x in events])

        # create the second of two patches in the series; series is still not
        # complete
        utils.create_patch(series=series, number=2)
        events = _get_events(series=series)
        self.assertNotIn(Event.CATEGORY_SERIES_COMPLETED,
                         [x.category for x in events])

        # now create the first patch, which will "complete" the series
        utils.create_patch(series=series, number=1)
        events = _get_events(series=series)
        self.assertIn(Event.CATEGORY_SERIES_COMPLETED,
                      [x.category for x in events])
Exemple #31
0
    def test_list(self):
        """Validate we can list series."""
        resp = self.client.get(self.api_url())
        self.assertEqual(status.HTTP_200_OK, resp.status_code)
        self.assertEqual(0, len(resp.data))

        series = create_series()

        # anonymous 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(series, resp.data[0])

        # authenticated user
        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(series, resp.data[0])
Exemple #32
0
    def test_patch_dependencies_present_series(self):
        """Patch dependencies already exist."""
        series = utils.create_series()
        patch = utils.create_patch(series=series)

        # This should raise both the CATEGORY_PATCH_CREATED and
        # CATEGORY_PATCH_COMPLETED events
        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 2)
        self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
        self.assertEqual(events[0].project, patch.project)
        self.assertEqual(events[1].category, Event.CATEGORY_PATCH_COMPLETED)
        self.assertEqual(events[1].project, patch.project)
        self.assertEventFields(events[0])
        self.assertEventFields(events[1])

        # This shouldn't be affected by another update to the patch
        patch.commit_ref = 'aac76f0b0f8dd657ff07bb32df369705696d4831'
        patch.save()

        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 2)
Exemple #33
0
    def test_patch_dependencies_present_series(self):
        """Patch dependencies already exist."""
        series = utils.create_series()
        patch = utils.create_patch(series=series)

        # This should raise both the CATEGORY_PATCH_CREATED and
        # CATEGORY_PATCH_COMPLETED events
        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 2)
        self.assertEqual(events[0].category, Event.CATEGORY_PATCH_CREATED)
        self.assertEqual(events[0].project, patch.project)
        self.assertEqual(events[1].category, Event.CATEGORY_PATCH_COMPLETED)
        self.assertEqual(events[1].project, patch.project)
        self.assertEventFields(events[0])
        self.assertEventFields(events[1])

        # This shouldn't be affected by another update to the patch
        patch.commit_ref = 'aac76f0b0f8dd657ff07bb32df369705696d4831'
        patch.save()

        events = _get_events(patch=patch)
        self.assertEqual(events.count(), 2)
Exemple #34
0
    def test_detail_version_1_0(self):
        series = create_series()

        resp = self.client.get(self.api_url(series.id, version='1.0'))
        self.assertIn('url', resp.data)
        self.assertNotIn('web_url', resp.data)
    def _create_patches():
        series = create_series()
        patch_a = create_patch(series=series)
        patch_b = create_patch(series=series)

        return series, patch_a, patch_b
Exemple #36
0
    def _create_patches():
        series = create_series()
        patch_a = create_patch(series=series)
        patch_b = create_patch(series=series)

        return series, patch_a, patch_b
Exemple #37
0
    def test_detail_version_1_0(self):
        series = create_series()

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