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], })
def test_finalize_with_pending_take_precedence(self): """Testing StatusUpdatesEntryMixin.finalize with PENDING taking precedence SUCCESS """ entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.PENDING)) entry.add_update(StatusUpdate(state=StatusUpdate.DONE_SUCCESS)) entry.finalize() self.assertEqual(entry.state_summary, '1 succeeded, 1 pending') self.assertEqual(entry.state_summary_class, 'status-update-state-pending')
def test_finalize_with_failures_take_precedence(self): """Testing StatusUpdatesEntryMixin.finalize with failures taking precedence over PENDING and DONE_SUCCESS """ entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.DONE_FAILURE)) entry.add_update(StatusUpdate(state=StatusUpdate.PENDING)) entry.add_update(StatusUpdate(state=StatusUpdate.DONE_SUCCESS)) entry.finalize() self.assertEqual(entry.state_summary, '1 failed, 1 succeeded, 1 pending') self.assertEqual(entry.state_summary_class, 'status-update-state-failure')
def _update_status(self, status_update, extra_fields, **kwargs): """Update the fields of the StatusUpdate model. Args: status_update (reviewboard.reviews.models.StatusUpdate): The status update to modify. extra_fields (dict): Any additional fields to update into the status update's ``extra_data`` field. **kwargs (dict): A dictionary of field names and new values to update. """ for field_name in ('description', 'service_id', 'summary', 'timeout', 'url', 'url_text'): if field_name in kwargs: setattr(status_update, field_name, kwargs[field_name]) if 'state' in kwargs: status_update.state = StatusUpdate.string_to_state(kwargs['state']) if 'change_id' in kwargs: status_update.change_description = \ ChangeDescription.objects.get(pk=kwargs['change_id']) if 'review_id' in kwargs: status_update.review = Review.objects.get(pk=kwargs['review_id']) self.import_extra_data(status_update, status_update.extra_data, extra_fields)
def _update_status(self, status_update, extra_fields, **kwargs): """Update the fields of the StatusUpdate model. Args: status_update (reviewboard.reviews.models.StatusUpdate): The status update to modify. extra_fields (dict): Any additional fields to update into the status update's ``extra_data`` field. **kwargs (dict): A dictionary of field names and new values to update. """ for field_name in ('description', 'service_id', 'summary', 'timeout', 'url', 'url_text'): if field_name in kwargs: setattr(status_update, field_name, kwargs[field_name]) if 'state' in kwargs: status_update.state = StatusUpdate.string_to_state(kwargs['state']) if 'change_id' in kwargs: try: status_update.change_description = \ ChangeDescription.objects.get(pk=kwargs['change_id']) except ChangeDescription.DoesNotExist: return INVALID_FORM_DATA, { 'fields': { 'change_id': ['Invalid change description ID'], }, } if 'review_id' in kwargs: try: status_update.review = \ Review.objects.get(pk=kwargs['review_id']) except Review.DoesNotExist: return INVALID_FORM_DATA, { 'fields': { 'review_id': ['Invalid review ID'], }, } try: self.import_extra_data(status_update, status_update.extra_data, extra_fields) except ImportExtraDataError as e: return e.error_payload if status_update.pk is None: code = 201 else: code = 200 status_update.save() return code, { self.item_result_key: status_update, }
def test_finalize_with_timeout(self): """Testing StatusUpdatesEntryMixin.finalize with TIMEOUT""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.TIMEOUT)) entry.finalize() self.assertEqual(entry.state_summary, '1 timed out') self.assertEqual(entry.state_summary_class, 'status-update-state-failure')
def test_add_update_with_done_success(self): """Testing StatusUpdatesEntryMixin.add_update with DONE_SUCCESS""" status_update = StatusUpdate(state=StatusUpdate.DONE_SUCCESS) entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertEqual(entry.status_updates, [status_update]) self.assertEqual(status_update.header_class, 'status-update-state-success')
def test_add_update_with_timeout(self): """Testing StatusUpdatesEntryMixin.add_update with TIMEOUT""" status_update = StatusUpdate(state=StatusUpdate.TIMEOUT) entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertEqual(entry.status_updates, [status_update]) self.assertEqual(status_update.header_class, 'status-update-state-failure')
def test_add_update_with_pending(self): """Testing StatusUpdatesEntryMixin.add_update with PENDING""" status_update = StatusUpdate(state=StatusUpdate.PENDING) entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertEqual(entry.status_updates, [status_update]) self.assertEqual(status_update.header_class, 'status-update-state-pending')
def test_add_update_with_error(self): """Testing StatusUpdatesEntryMixin.add_update with ERROR""" status_update = StatusUpdate(state=StatusUpdate.ERROR) entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertEqual(entry.status_updates, [status_update]) self.assertEqual(status_update.header_class, 'status-update-state-failure')
def test_finalize_with_pending(self): """Testing StatusUpdatesEntryMixin.finalize with PENDING""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.PENDING)) entry.finalize() self.assertEqual(entry.state_summary, '1 pending') self.assertEqual(entry.state_summary_class, 'status-update-state-pending')
def test_finalize_with_done_success(self): """Testing StatusUpdatesEntryMixin.finalize with DONE_SUCCESS""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.DONE_SUCCESS)) entry.finalize() self.assertEqual(entry.state_summary, '1 succeeded') self.assertEqual(entry.state_summary_class, 'status-update-state-success')
def test_finalize_with_error(self): """Testing StatusUpdatesEntryMixin.finalize with ERROR""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.ERROR)) entry.finalize() self.assertEqual(entry.state_summary, '1 failed with error') self.assertEqual(entry.state_summary_class, 'status-update-state-failure')
def test_add_update_with_done_failure(self): """Testing StatusUpdatesEntryMixin.add_update with DONE_FAILURE""" status_update = StatusUpdate(state=StatusUpdate.DONE_FAILURE) entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertEqual(entry.status_updates, [status_update]) self.assertEqual(status_update.header_class, 'status-update-state-failure')
def test_finalize_with_done_failure(self): """Testing StatusUpdatesEntryMixin.finalize with DONE_FAILURE""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.DONE_FAILURE)) entry.finalize() self.assertEqual(entry.state_summary, '1 failed') self.assertEqual(entry.state_summary_class, 'status-update-state-failure')
def test_add_update_html_rendering(self): """Testing StatusUpdatesEntryMixin.add_update HTML rendering""" status_update = StatusUpdate(state=StatusUpdate.DONE_SUCCESS, description='My description.', summary='My summary.') entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertHTMLEqual(status_update.summary_html, ('<div class="status-update-summary-entry' ' status-update-state-success">\n' ' <span class="summary">My summary.</span>\n' ' My description.\n' '</div>'))
def serialize_state_field(self, obj, **kwargs): """Return a serialized version of the ``state`` field. Args: obj (reviewboard.reviews.models.StatusUpdate): The status update being serialized. **kwargs (dict): Additional keyword arguments (unused). Returns: unicode: The serialized state. """ return StatusUpdate.state_to_string(obj.effective_state)
def test_finalize_with_all_states(self): """Testing StatusUpdatesEntryMixin.finalize with all states""" entry = StatusUpdatesEntryMixin() entry.add_update(StatusUpdate(state=StatusUpdate.DONE_FAILURE)) for i in range(2): entry.add_update(StatusUpdate(state=StatusUpdate.DONE_SUCCESS)) for i in range(3): entry.add_update(StatusUpdate(state=StatusUpdate.PENDING)) for i in range(4): entry.add_update(StatusUpdate(state=StatusUpdate.ERROR)) for i in range(5): entry.add_update(StatusUpdate(state=StatusUpdate.TIMEOUT)) entry.finalize() self.assertEqual( entry.state_summary, '1 failed, 2 succeeded, 3 pending, 4 failed with error, ' '5 timed out')
def test_add_update_html_rendering_with_timeout(self): """Testing StatusUpdatesEntryMixin.add_update HTML rendering with timeout """ status_update = StatusUpdate(state=StatusUpdate.TIMEOUT, description='My description.', summary='My summary.') entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertHTMLEqual(status_update.summary_html, ('<div class="status-update-summary-entry' ' status-update-state-failure">\n' ' <span class="summary">My summary.</span>\n' ' timed out.\n' '</div>'))
def test_add_update_html_rendering_with_url(self): """Testing StatusUpdatesEntryMixin.add_update HTML rendering with URL """ status_update = StatusUpdate(state=StatusUpdate.DONE_SUCCESS, description='My description.', summary='My summary.', url='https://example.com/') entry = StatusUpdatesEntryMixin() entry.add_update(status_update) self.assertHTMLEqual( status_update.summary_html, ('<div class="status-update-summary-entry' ' status-update-state-success">\n' ' <span class="summary">My summary.</span>\n' ' My description.\n' ' <a href="https://example.com/">https://example.com/</a>' '</div>'))
def get_queryset(self, request, is_list=False, *args, **kwargs): """Return a queryset for StatusUpdate models. Args: request (django.http.HttpRequest): The HTTP request. is_list (boolean): Whether this query is for the list resource (which supports additional query options). *args (tuple): Additional arguments to be passed to parent resources. **kwargs (dict): Additional keyword arguments to be passed to parent resources. Returns: django.db.models.query.QuerySet: A QuerySet containing the matching status updates. """ review_request = resources.review_request.get_object( request, *args, **kwargs) q = Q() if is_list: if 'change' in request.GET: q = q & Q(change_description=int(request.GET.get('change'))) if 'service-id' in request.GET: q = q & Q(service_id=request.GET.get('service-id')) if 'state' in request.GET: q = q & Q(state=StatusUpdate.string_to_state( request.GET.get('state'))) return review_request.status_updates.filter(q)
def _update_status(self, status_update, extra_fields, **kwargs): """Update the fields of the StatusUpdate model. Args: status_update (reviewboard.reviews.models.StatusUpdate): The status update to modify. extra_fields (dict): Any additional fields to update into the status update's ``extra_data`` field. **kwargs (dict): A dictionary of field names and new values to update. """ for field_name in ('description', 'service_id', 'summary', 'timeout', 'url', 'url_text'): if field_name in kwargs: setattr(status_update, field_name, kwargs[field_name]) state = kwargs.get('state') if state is not None: # request-run is special in that it does not correspond to a stored # state. Instead, it will attempt to trigger a run of the # associated tool. if state == 'request-run': if status_update.can_run: status_update.run() else: return INVALID_FORM_DATA, { 'fields': { 'state': ['This status update cannot be run'], }, } else: status_update.state = \ StatusUpdate.string_to_state(state) if 'change_id' in kwargs: try: status_update.change_description = \ ChangeDescription.objects.get(pk=kwargs['change_id']) except ChangeDescription.DoesNotExist: return INVALID_FORM_DATA, { 'fields': { 'change_id': ['Invalid change description ID'], }, } if 'review_id' in kwargs: try: status_update.review = \ Review.objects.get(pk=kwargs['review_id']) except Review.DoesNotExist: return INVALID_FORM_DATA, { 'fields': { 'review_id': ['Invalid review ID'], }, } try: self.import_extra_data(status_update, status_update.extra_data, extra_fields) except ImportExtraDataError as e: return e.error_payload if status_update.pk is None: code = 201 else: code = 200 status_update.save() return code, { self.item_result_key: status_update, }