예제 #1
0
    def test_query_data_pre_etag(self):
        """Testing ReviewRequestPageData.query_data_pre_etag"""
        self._populate_review_request()

        request = RequestFactory().get('/r/1/')
        request.user = self.review_request.submitter

        data = ReviewRequestPageData(review_request=self.review_request,
                                     request=request)
        data.query_data_pre_etag()

        self.assertEqual(data.reviews, [self.review2, self.review1])
        self.assertEqual(data.latest_review_timestamp, self.review2.timestamp)
        self.assertEqual(data.changedescs,
                         [self.changedesc2, self.changedesc1])
        self.assertEqual(data.latest_changedesc_timestamp,
                         self.changedesc2.timestamp)
        self.assertEqual(data.draft, self.draft)
        self.assertEqual(data.diffsets, [self.diffset1, self.diffset2])
        self.assertEqual(data.diffsets_by_id, {
            1: self.diffset1,
            2: self.diffset2,
        })
        self.assertEqual(data.status_updates,
                         [self.status_update1, self.status_update2])
예제 #2
0
    def _make_field(self, review_request):
        request = self.request_factory.get('/')
        request.user = AnonymousUser()

        data = ReviewRequestPageData(review_request, request)
        data.query_data_pre_etag()
        data.query_data_post_etag()

        return CommitListField(review_request, request=request, data=data)
예제 #3
0
    def setUp(self):
        super(ReviewEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.review = self.create_review(self.review_request, id=123)
        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)
예제 #4
0
    def setUp(self):
        super(ChangeEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.changedesc = ChangeDescription.objects.create(id=123, public=True)
        self.review_request.changedescs.add(self.changedesc)
        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)
예제 #5
0
    def setUp(self):
        super(InitialStatusUpdatesEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.review = self.create_review(self.review_request, public=True)
        self.general_comment = self.create_general_comment(self.review,
                                                           issue_opened=False)
        self.status_update = self.create_status_update(self.review_request,
                                                       review=self.review)

        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)
    def _build_data(self, entry_classes=None):
        self._populate_review_request()

        request = RequestFactory().get('/r/1/')
        request.user = self.review_request.submitter

        return ReviewRequestPageData(review_request=self.review_request,
                                     request=request,
                                     entry_classes=entry_classes)
예제 #7
0
    def test_populate_status_updates_with_draft_replies(self):
        """Testing StatusUpdatesEntryMixin.populate_status_updates with
        draft replies
        """
        review_request = self.create_review_request()
        review = self.create_review(review_request, public=True)
        comment = self.create_general_comment(review)

        reply = self.create_reply(review)
        reply_comment = self.create_general_comment(reply, reply_to=comment)

        # This state is normally set in ReviewRequestPageData.
        comment._type = 'general_comments'
        comment.review_obj = review

        status_updates = [
            StatusUpdate(state=StatusUpdate.PENDING),
            StatusUpdate(state=StatusUpdate.DONE_FAILURE, review=review)
        ]

        request = RequestFactory().get('/r/1/')
        request.user = AnonymousUser()

        data = ReviewRequestPageData(review_request=review_request,
                                     request=request)
        data.review_comments[review.pk] = [comment]
        data.draft_reply_comments[review.pk] = [reply_comment]

        entry = StatusUpdatesEntryMixin()
        entry.collapsed = True
        entry.populate_status_updates(status_updates, data)

        self.assertFalse(entry.collapsed)
        self.assertEqual(entry.status_updates, status_updates)

        status_update = entry.status_updates[0]
        self.assertIsNone(status_update.review)
        self.assertEqual(
            status_update.comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [],
            })

        status_update = entry.status_updates[1]
        self.assertEqual(status_update.review, review)
        self.assertEqual(
            status_update.comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [comment],
            })
예제 #8
0
    def _make_field(self, review_request):
        request = self.request_factory.get('/')
        request.user = AnonymousUser()

        data = ReviewRequestPageData(review_request, request)
        data.query_data_pre_etag()
        data.query_data_post_etag()

        return CommitListField(review_request, request=request, data=data)
예제 #9
0
    def make_field(self, review_request):
        """Return an instance of the field to test with.

        The field will be populated with all review request page state.

        Args:
            review_request (reviewboard.reviews.models.review_request.
                            ReviewRequest):
                The review request being tested.

        Returns:
            reviewboard.reviews.fields.BaseReviewRequestField:
            The resulting field instance.
        """
        request = self.build_review_request_get(review_request)

        data = ReviewRequestPageData(review_request, request)
        data.query_data_pre_etag()
        data.query_data_post_etag()

        return self.field_cls(review_request, request=request, data=data)
예제 #10
0
class ChangeEntryTests(TestCase):
    """Unit tests for ChangeEntry."""

    fixtures = ['test_users']

    def setUp(self):
        super(ChangeEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.changedesc = ChangeDescription.objects.create(id=123, public=True)
        self.review_request.changedescs.add(self.changedesc)
        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)

    def test_get_dom_element_id(self):
        """Testing ChangeEntry.get_dom_element_id"""
        entry = ChangeEntry(request=self.request,
                            review_request=self.review_request,
                            changedesc=self.changedesc,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(entry.get_dom_element_id(), 'changedesc123')

    def test_get_js_model_data(self):
        """Testing ChangeEntry.get_js_model_data for standard ChangeDescription
        """
        entry = ChangeEntry(request=self.request,
                            review_request=self.review_request,
                            changedesc=self.changedesc,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(entry.get_js_model_data(), {
            'pendingStatusUpdates': False,
        })

    @add_fixtures(['test_scmtools'])
    def test_get_js_model_data_with_status_updates(self):
        """Testing ChangeEntry.get_js_model_data for ChangeDescription with
        status updates
        """
        self.review_request.repository = self.create_repository()
        diffset = self.create_diffset(self.review_request)
        filediff = self.create_filediff(diffset)

        review = self.create_review(self.review_request,
                                    body_top='Body top',
                                    body_bottom='Body bottom',
                                    ship_it=True)
        comment1 = self.create_diff_comment(review, filediff)
        comment2 = self.create_diff_comment(review, filediff)
        review.publish()

        # This is needed by the entry's add_comment(). It's normally built when
        # creating the entries and their data.
        comment1.review_obj = review
        comment2.review_obj = review

        status_update = self.create_status_update(
            self.review_request,
            review=review,
            change_description=self.changedesc)

        entry = ChangeEntry(request=self.request,
                            review_request=self.review_request,
                            changedesc=self.changedesc,
                            collapsed=False,
                            data=self.data)
        entry.add_update(status_update)
        entry.add_comment('diff_comments', comment1)
        entry.add_comment('diff_comments', comment2)

        self.assertEqual(
            entry.get_js_model_data(), {
                'reviewsData': [
                    {
                        'id': review.pk,
                        'bodyTop': 'Body top',
                        'bodyBottom': 'Body bottom',
                        'public': True,
                        'shipIt': True,
                    },
                ],
                'diffCommentsData': [
                    (six.text_type(comment1.pk), six.text_type(filediff.pk)),
                    (six.text_type(comment2.pk), six.text_type(filediff.pk)),
                ],
                'pendingStatusUpdates':
                False,
            })

    def test_build_entries(self):
        """Testing ChangeEntry.build_entries"""
        changedesc1 = self.changedesc
        changedesc2 = self.review_request.changedescs.create(
            timestamp=changedesc1.timestamp + timedelta(days=1), public=True)

        review = self.create_review(self.review_request, public=True)
        comment = self.create_general_comment(review)
        status_update = self.create_status_update(
            self.review_request, review=review, change_description=changedesc2)

        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entries = list(ChangeEntry.build_entries(self.data))

        # These will actually be in database query order (newest to oldest),
        # not the order shown on the page.
        entry = entries[0]
        self.assertEqual(entry.changedesc, changedesc2)
        self.assertFalse(entry.collapsed)
        self.assertEqual(entry.status_updates, [status_update])
        self.assertEqual(entry.status_updates_by_review, {
            review.pk: status_update,
        })
        self.assertEqual(
            entry.status_updates[0].comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [comment],
            })

        entry = entries[1]
        self.assertEqual(entry.changedesc, changedesc1)
        self.assertTrue(entry.collapsed)
        self.assertEqual(entry.status_updates, [])
예제 #11
0
class ReviewEntryTests(TestCase):
    """Unit tests for ReviewEntry."""

    fixtures = ['test_users']

    def setUp(self):
        super(ReviewEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.review = self.create_review(self.review_request,
                                         id=123,
                                         public=True)
        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)

    def test_get_dom_element_id(self):
        """Testing ReviewEntry.get_dom_element_id"""
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(entry.get_dom_element_id(), 'review123')

    def test_get_js_model_data(self):
        """Testing ReviewEntry.get_js_model_data"""
        self.review.ship_it = True
        self.review.publish()

        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(
            entry.get_js_model_data(), {
                'reviewData': {
                    'id': self.review.pk,
                    'bodyTop': 'Test Body Top',
                    'bodyBottom': 'Test Body Bottom',
                    'public': True,
                    'shipIt': True,
                },
            })

    @add_fixtures(['test_scmtools'])
    def test_get_js_model_data_with_diff_comments(self):
        """Testing ReviewEntry.get_js_model_data with diff comments"""
        self.review_request.repository = self.create_repository()
        diffset = self.create_diffset(self.review_request)
        filediff = self.create_filediff(diffset)

        comment1 = self.create_diff_comment(self.review, filediff)
        comment2 = self.create_diff_comment(self.review, filediff)
        self.review.publish()

        # This is needed by the entry's add_comment(). It's normally built when
        # creating the entries and their data.
        comment1.review_obj = self.review
        comment2.review_obj = self.review

        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)
        entry.add_comment('diff_comments', comment1)
        entry.add_comment('diff_comments', comment2)

        self.assertEqual(
            entry.get_js_model_data(), {
                'reviewData': {
                    'id': self.review.pk,
                    'bodyTop': 'Test Body Top',
                    'bodyBottom': 'Test Body Bottom',
                    'public': True,
                    'shipIt': False,
                },
                'diffCommentsData': [
                    (six.text_type(comment1.pk), six.text_type(filediff.pk)),
                    (six.text_type(comment2.pk), six.text_type(filediff.pk)),
                ],
            })

    def test_add_comment_with_no_open_issues(self):
        """Testing ReviewEntry.add_comment with comment not opening an issue"""
        self.request.user = self.review_request.submitter
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment('general_comments', GeneralComment())

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)
        self.assertTrue(entry.collapsed)

    def test_add_comment_with_open_issues(self):
        """Testing ReviewEntry.add_comment with comment opening an issue"""
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment(
            'general_comments',
            GeneralComment(issue_opened=True,
                           issue_status=GeneralComment.OPEN))

        self.assertTrue(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 1)
        self.assertTrue(entry.collapsed)

    def test_add_comment_with_open_issues_and_viewer_is_owner(self):
        """Testing ReviewEntry.add_comment with comment opening an issue and
        the review request owner is viewing the page
        """
        self.request.user = self.review_request.submitter
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment(
            'general_comments',
            GeneralComment(issue_opened=True,
                           issue_status=GeneralComment.OPEN))

        self.assertTrue(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 1)
        self.assertFalse(entry.collapsed)

    def test_build_entries(self):
        """Testing ReviewEntry.build_entries"""
        review1 = self.create_review(self.review_request,
                                     timestamp=self.review.timestamp -
                                     timedelta(days=2),
                                     public=True)
        review2 = self.review

        comment = self.create_general_comment(review1)

        # These shouldn't show up in the results.
        self.create_review(self.review_request,
                           timestamp=self.review.timestamp - timedelta(days=1),
                           public=False)
        self.create_reply(review1)

        status_update_review = self.create_review(self.review_request,
                                                  public=True)
        self.create_general_comment(status_update_review)
        self.create_status_update(self.review_request,
                                  review=status_update_review)

        # Create a change description to test collapsing.
        self.review_request.changedescs.create(timestamp=review2.timestamp -
                                               timedelta(days=1),
                                               public=True)

        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entries = list(ReviewEntry.build_entries(self.data))

        self.assertEqual(len(entries), 2)

        # These will actually be in database query order (newest to oldest),
        # not the order shown on the page.
        entry = entries[0]
        self.assertEqual(entry.review, review2)
        self.assertFalse(entry.collapsed)
        self.assertEqual(
            entry.comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [],
            })

        entry = entries[1]
        self.assertEqual(entry.review, review1)
        self.assertTrue(entry.collapsed)
        self.assertEqual(
            entry.comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [comment],
            })
예제 #12
0
class InitialStatusUpdatesEntryTests(TestCase):
    """Unit tests for InitialStatusUpdatesEntry."""

    fixtures = ['test_users']

    def setUp(self):
        super(InitialStatusUpdatesEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.review = self.create_review(self.review_request, public=True)
        self.general_comment = self.create_general_comment(self.review,
                                                           issue_opened=False)
        self.status_update = self.create_status_update(self.review_request,
                                                       review=self.review)

        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)

    def test_build_entries(self):
        """Testing InitialStatusUpdatesEntry.build_entries"""
        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entries = list(InitialStatusUpdatesEntry.build_entries(self.data))
        self.assertEqual(len(entries), 1)

        entry = entries[0]
        self.assertFalse(entry.collapsed)
        self.assertEqual(entry.status_updates, [self.status_update])
        self.assertEqual(entry.status_updates_by_review, {
            self.review.pk: self.status_update,
        })
        self.assertEqual(
            entry.status_updates[0].comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [self.general_comment],
            })

    def test_build_entries_with_changedesc(self):
        """Testing InitialStatusUpdatesEntry.build_entries with
        ChangeDescription following this entry
        """
        self.review_request.changedescs.create(public=True)

        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entries = list(InitialStatusUpdatesEntry.build_entries(self.data))
        self.assertEqual(len(entries), 1)

        entry = entries[0]
        self.assertTrue(entry.collapsed)
        self.assertEqual(entry.status_updates, [self.status_update])
        self.assertEqual(entry.status_updates_by_review, {
            self.review.pk: self.status_update,
        })

        status_update = entry.status_updates[0]
        self.assertEqual(status_update.review, self.review)
        self.assertIsNone(status_update.change_description)
        self.assertEqual(
            status_update.comments, {
                'diff_comments': [],
                'screenshot_comments': [],
                'file_attachment_comments': [],
                'general_comments': [self.general_comment],
            })
예제 #13
0
    def test_query_data_post_etag(self):
        """Testing ReviewRequestPageData.query_data_post_etag"""
        self._populate_review_request()

        request = RequestFactory().get('/r/1/')
        request.user = self.review_request.submitter

        data = ReviewRequestPageData(review_request=self.review_request,
                                     request=request)
        data.query_data_pre_etag()
        data.query_data_post_etag()

        self.assertEqual(data.reviews_by_id, {
            1: self.review1,
            2: self.review2,
        })
        self.assertEqual(data.review_request_details, self.draft)
        self.assertEqual(data.active_file_attachments,
                         [self.file_attachment1, self.file_attachment2])
        self.assertEqual(data.all_file_attachments, [
            self.file_attachment1, self.file_attachment2,
            self.inactive_file_attachment1
        ])
        self.assertEqual(
            data.file_attachments_by_id, {
                1: self.file_attachment1,
                2: self.file_attachment2,
                3: self.inactive_file_attachment1,
            })
        self.assertEqual(data.active_screenshots,
                         [self.screenshot1, self.screenshot2])
        self.assertEqual(
            data.all_screenshots,
            [self.screenshot1, self.screenshot2, self.inactive_screenshot1])
        self.assertEqual(
            data.screenshots_by_id, {
                1: self.screenshot1,
                2: self.screenshot2,
                3: self.inactive_screenshot1,
            })
        self.assertEqual(data.comments, [
            self.diff_comment1,
            self.diff_comment2,
            self.screenshot_comment1,
            self.screenshot_comment2,
            self.file_attachment_comment1,
            self.file_attachment_comment2,
            self.general_comment1,
            self.general_comment2,
        ])
        self.assertEqual(data.issues, [
            self.diff_comment1,
            self.diff_comment2,
            self.file_attachment_comment1,
            self.file_attachment_comment2,
            self.general_comment1,
            self.general_comment2,
        ])
        self.assertEqual(data.issue_counts, {
            'total': 6,
            'open': 2,
            'resolved': 2,
            'dropped': 2,
        })
예제 #14
0
class ReviewEntryTests(TestCase):
    """Unit tests for ReviewEntry."""

    fixtures = ['test_users']

    def setUp(self):
        super(ReviewEntryTests, self).setUp()

        self.request = RequestFactory().get('/r/1/')
        self.request.user = AnonymousUser()

        self.review_request = self.create_review_request()
        self.review = self.create_review(self.review_request, id=123)
        self.data = ReviewRequestPageData(review_request=self.review_request,
                                          request=self.request)

    def test_get_dom_element_id(self):
        """Testing ReviewEntry.get_dom_element_id"""
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(entry.get_dom_element_id(), 'review123')

    def test_get_js_model_data(self):
        """Testing ReviewEntry.get_js_model_data"""
        self.review.ship_it = True
        self.review.publish()

        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)

        self.assertEqual(
            entry.get_js_model_data(), {
                'reviewData': {
                    'id': self.review.pk,
                    'bodyTop': 'Test Body Top',
                    'bodyBottom': 'Test Body Bottom',
                    'public': True,
                    'shipIt': True,
                },
            })

    @add_fixtures(['test_scmtools'])
    def test_get_js_model_data_with_diff_comments(self):
        """Testing ReviewEntry.get_js_model_data with diff comments"""
        self.review_request.repository = self.create_repository()
        diffset = self.create_diffset(self.review_request)
        filediff = self.create_filediff(diffset)

        comment1 = self.create_diff_comment(self.review, filediff)
        comment2 = self.create_diff_comment(self.review, filediff)
        self.review.publish()

        # This is needed by the entry's add_comment(). It's normally built when
        # creating the entries and their data.
        comment1.review_obj = self.review
        comment2.review_obj = self.review

        self.data.query_data_pre_etag()
        self.data.query_data_post_etag()

        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=False,
                            data=self.data)
        entry.add_comment('diff_comments', comment1)
        entry.add_comment('diff_comments', comment2)

        self.assertEqual(
            entry.get_js_model_data(), {
                'reviewData': {
                    'id': self.review.pk,
                    'bodyTop': 'Test Body Top',
                    'bodyBottom': 'Test Body Bottom',
                    'public': True,
                    'shipIt': False,
                },
                'diffCommentsData': [
                    (six.text_type(comment1.pk), six.text_type(filediff.pk)),
                    (six.text_type(comment2.pk), six.text_type(filediff.pk)),
                ],
            })

    def test_add_comment_with_no_open_issues(self):
        """Testing ReviewEntry.add_comment with comment not opening an issue"""
        self.request.user = self.review_request.submitter
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment('general_comments', GeneralComment())

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)
        self.assertTrue(entry.collapsed)

    def test_add_comment_with_open_issues(self):
        """Testing ReviewEntry.add_comment with comment opening an issue"""
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment(
            'general_comments',
            GeneralComment(issue_opened=True,
                           issue_status=GeneralComment.OPEN))

        self.assertTrue(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 1)
        self.assertTrue(entry.collapsed)

    def test_add_comment_with_open_issues_and_viewer_is_owner(self):
        """Testing ReviewEntry.add_comment with comment opening an issue and
        the review request owner is viewing the page
        """
        self.request.user = self.review_request.submitter
        entry = ReviewEntry(request=self.request,
                            review_request=self.review_request,
                            review=self.review,
                            collapsed=True,
                            data=self.data)

        self.assertFalse(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 0)

        entry.add_comment(
            'general_comments',
            GeneralComment(issue_opened=True,
                           issue_status=GeneralComment.OPEN))

        self.assertTrue(entry.has_issues)
        self.assertEqual(entry.issue_open_count, 1)
        self.assertFalse(entry.collapsed)