コード例 #1
0
def get_baz_caseblock(owner_id):
    return CaseBlock(
        create=True,
        case_id=BAZ_CASE_ID,
        case_type='person',
        case_name='BAZ, Bazza',
        external_id='P-GBR-012345678',
        owner_id=owner_id,
        update={
            'first_name': 'Bazza',
            'last_name': 'Baz',
            'passport_type': 'P',
            'passport_country_code': 'GBR',
            'passport_number': '012345678',
            'sex': 'male',
            'dob': '1990-01-01',
            'covid19_last_test_date': '2021-01-01',
            'covid19_last_test_status': 'negative',
        }
    )
コード例 #2
0
ファイル: test_basics.py プロジェクト: xbryanc/commcare-hq
    def test_date_opened_coercion(self):
        delete_all_users()
        self.project = Domain(name='some-domain')
        self.project.save()
        user = create_restore_user(self.project.name)
        case_id = uuid.uuid4().hex
        modified_on = datetime.utcnow()
        case = CaseBlock(
            create=True,
            case_id=case_id,
            user_id=user.user_id, owner_id=user.user_id, case_type='demo',
            case_name='create_case', date_modified=modified_on, date_opened=modified_on, update={
                'dynamic': '123'
            }
        )

        post_case_blocks([case.as_xml()], domain='some-domain')
        # update the date_opened to date type to check for value on restore
        case.date_opened = case.date_opened.date()
        deprecated_check_user_has_case(self, user, case.as_xml())
コード例 #3
0
def _update_case_id_properties(domain, user):
    """Some case properties store the ID of related cases.  This updates those IDs"""
    case_ids = CommCareCase.objects.get_case_ids_in_domain(domain)
    cases = CommCareCase.objects.get_cases(case_ids, domain)
    case_ids_by_external_id = {c.external_id: c.case_id for c in cases}

    case_blocks = []
    for case in cases:
        update = {}
        for k, v in case.dynamic_case_properties().items():
            if v in case_ids_by_external_id:
                update[k] = case_ids_by_external_id[v]
        if update:
            case_blocks.append(
                CaseBlock(
                    case_id=case.case_id,
                    user_id=user._id,
                    update=update,
                ).as_xml()
            )
コード例 #4
0
    def setUp(self):
        super(CommTrackSyncTest, self).setUp()
        self.group = Group(domain=util.TEST_DOMAIN,
                           name='commtrack-folks',
                           users=[self.user._id],
                           case_sharing=True)
        self.group._id = self.sp.owner_id
        self.group.save()

        self.restore_user = self.user.to_ota_restore_user()
        self.sp_block = CaseBlock(case_id=self.sp.case_id, ).as_xml()

        # get initial restore token
        restore_config = RestoreConfig(
            project=self.domain,
            restore_user=self.restore_user,
            params=RestoreParams(version=V2),
        )
        self.sync_log_id = deprecated_synclog_id_from_restore_payload(
            restore_config.get_payload().as_string())
コード例 #5
0
def get_addpatient_caseblock(
    case_type: str,
    default_owner: Optional[CommCareUser],
    patient: dict,
    repeater: OpenmrsRepeater,
) -> CaseBlock:

    case_block_kwargs = get_case_block_kwargs_from_patient(patient, repeater)
    if default_owner:
        case_block_kwargs.setdefault("owner_id", default_owner.user_id)
    if not case_block_kwargs.get("owner_id"):
        raise ConfigurationError(
            _(f'No users found at location "{repeater.location_id}" to own '
              'patients added from OpenMRS Atom feed.'))
    case_id = uuid.uuid4().hex
    return CaseBlock(create=True,
                     case_id=case_id,
                     case_type=case_type,
                     external_id=patient['uuid'],
                     **case_block_kwargs)
コード例 #6
0
 def to_xml(self):
     extras = {}
     if self.owner_id:
         extras['owner_id'] = self.owner_id
     if self.create:
         extras['case_name'] = self.product_stock_case.name
         extras['index'] = {
             const.PARENT_CASE_REF: (const.SUPPLY_POINT_PRODUCT_CASE_TYPE,
                                     self.product_stock_case._id),
         }
     caseblock = CaseBlock(case_id=self.id,
                           create=self.create,
                           version=V2,
                           user_id=self.user_id,
                           case_type=const.REQUISITION_CASE_TYPE,
                           update=copy(self.custom_fields),
                           close=self.close,
                           **extras)
     return ElementTree.tostring(
         caseblock.as_xml(format_datetime=json_format_datetime))
コード例 #7
0
 def setUp(self):
     self.domain = create_domain(DOMAIN)
     self.user = CommCareUser.create(DOMAIN, USERNAME, PASSWORD, None, None)
     initialize_index_and_mapping(get_es_new(), CASE_SEARCH_INDEX_INFO)
     CaseSearchConfig.objects.get_or_create(pk=DOMAIN, enabled=True)
     delete_all_cases()
     self.case_id = uuid4().hex
     _, [self.case] = post_case_blocks([CaseBlock(
         create=True,
         case_id=self.case_id,
         case_type=CASE_TYPE,
         case_name=CASE_NAME,
         external_id=CASE_NAME,
         user_id=OWNER_ID,
         owner_id=OWNER_ID,
         update={'opened_by': OWNER_ID},
     ).as_xml()], {'domain': DOMAIN})
     CaseSearchReindexerFactory(domain=DOMAIN).build().reindex()
     es = get_es_new()
     es.indices.refresh(CASE_SEARCH_INDEX)
コード例 #8
0
    def test_rebuild_cases_with_new_owner(self, rebuild_case):
        """
            If cases have a different owner to the person who submitted it
            rebuild it when the submitter is retired.
        """

        case_id = uuid.uuid4().hex
        caseblock = CaseBlock(
            create=True,
            case_id=case_id,
            owner_id=self.commcare_user._id,
            user_id=self.commcare_user._id,
        )
        casexml = ElementTree.tostring(caseblock.as_xml())
        submit_case_blocks(casexml, self.domain, user_id=self.other_user._id)

        self.other_user.retire()

        detail = UserArchivedRebuild(user_id=self.other_user.user_id)
        rebuild_case.assert_called_once_with(self.domain, case_id, detail)
コード例 #9
0
def get_foo_caseblock(owner_id):
    return CaseBlock(
        create=True,
        case_id=FOO_CASE_ID,
        case_type='person',
        case_name='FOO, Fred',
        external_id='PM-ZAF-F01234567',
        owner_id=owner_id,
        update={
            'first_name': 'Fred',
            'last_name': 'Foo',
            'passport_type': 'PM',
            'passport_country_code': 'ZAF',
            'passport_number': 'F01234567',
            'sex': 'male',
            'dob': '1990-01-01',
            'covid19_last_test_date': '2021-01-01',
            'covid19_last_test_status': 'negative',
        }
    )
コード例 #10
0
def get_bar_caseblock(owner_id):
    return CaseBlock(
        create=True,
        case_id=BAR_CASE_ID,
        case_type='person',
        case_name='BAR, Barbara',
        external_id='PM-ZAF-B01234567',
        owner_id=owner_id,
        update={
            'first_name': 'Barbara',
            'last_name': 'Bar',
            'passport_type': 'PM',
            'passport_country_code': 'ZAF',
            'passport_number': 'B01234567',
            'sex': 'female',
            'dob': '1990-01-01',
            'covid19_last_test_date': '2021-01-01',
            'covid19_last_test_status': 'negative',
        }
    )
コード例 #11
0
def _post_util(create=False, case_id=None, user_id=None, owner_id=None,
              case_type=None, form_extras=None, close=False, date_modified=None,
              **kwargs):

    form_extras = form_extras or {}
    form_extras['domain'] = REBUILD_TEST_DOMAIN

    uid = lambda: uuid.uuid4().hex
    case_id = case_id or uid()
    block = CaseBlock(create=create,
                      case_id=case_id,
                      user_id=user_id or uid(),
                      owner_id=owner_id or uid(),
                      case_type=case_type or 'test',
                      date_modified=date_modified,
                      update=kwargs,
                      close=close)
    block = block.as_xml()
    post_case_blocks([block], form_extras)
    return case_id
コード例 #12
0
ファイル: models.py プロジェクト: ekush/commcare-hq
 def create_from_location(cls, domain, location):
     # a supply point is currently just a case with a special type
     id = uuid.uuid4().hex
     user_id = const.get_commtrack_user_id(domain)
     owner_id = location.group_id
     kwargs = {'external_id': location.external_id} if location.external_id else {}
     caseblock = CaseBlock(
         case_id=id,
         create=True,
         version=V2,
         case_name=location.name,
         user_id=user_id,
         owner_id=owner_id,
         case_type=const.SUPPLY_POINT_CASE_TYPE,
         update={
             'location_id': location._id,
         },
         **kwargs
     )
     return cls._from_caseblock(domain, caseblock)
コード例 #13
0
ファイル: helpers.py プロジェクト: twymer/commcare-hq
def make_supply_point(domain, location):
    # a supply point is currently just a case with a special type
    case_id = uuid.uuid4().hex
    user_id = const.get_commtrack_user_id(domain)
    owner_id = location.location_id
    kwargs = {
        'external_id': location.external_id
    } if location.external_id else {}
    caseblock = CaseBlock(case_id=case_id,
                          create=True,
                          case_name=location.name,
                          user_id=user_id,
                          owner_id=owner_id,
                          case_type=const.SUPPLY_POINT_CASE_TYPE,
                          update={
                              'location_id': location.location_id,
                          },
                          **kwargs)
    _submit_commtrack_caseblock(domain, caseblock, "make_supply_point")
    return SupplyInterface(domain).get_supply_point(case_id)
コード例 #14
0
    def create_case(cls,
                    case_type,
                    parent_case_id=None,
                    parent_case_type=None,
                    parent_identifier=None,
                    parent_relationship=None):

        kwargs = {}
        if parent_case_id:
            kwargs['index'] = {
                parent_identifier:
                (parent_case_type, parent_case_id, parent_relationship)
            }

        caseblock = CaseBlock(uuid.uuid4().hex,
                              case_type=case_type,
                              create=True,
                              **kwargs)
        return submit_case_blocks(ElementTree.tostring(caseblock.as_xml()),
                                  cls.domain)[1][0]
コード例 #15
0
ファイル: atom_feed.py プロジェクト: marionumza/commcare-hq
def get_case_block_for_indexed_case(
    mapping: ObservationMapping,
    external_data: dict,
    parent_case_attrs: CaseAttrs,
) -> CaseBlock:
    parent_case_id, parent_case_type, default_owner_id = parent_case_attrs

    relationship = mapping.indexed_case_mapping.relationship
    case_block_kwargs = {
        "index": {
            mapping.indexed_case_mapping.identifier: IndexAttrs(
                parent_case_type,
                parent_case_id,
                relationship,
            )
        },
        "update": {}
    }
    for value_source_config in mapping.indexed_case_mapping.case_properties:
        value_source = as_value_source(value_source_config)
        value = value_source.get_import_value(external_data)
        if value_source.case_property in CASE_BLOCK_ARGS:
            case_block_kwargs[value_source.case_property] = value
        else:
            case_block_kwargs["update"][value_source.case_property] = value

    case_id = uuid.uuid4().hex
    case_type = mapping.indexed_case_mapping.case_type
    case_block_kwargs.setdefault("owner_id", default_owner_id)
    if not case_block_kwargs["owner_id"]:
        raise ConfigurationError(_(
            f'Unable to determine mobile worker to own new "{case_type}" '
            f'{relationship} case or parent case "{parent_case_id}"'
        ))
    case_block = CaseBlock(
        create=True,
        case_id=case_id,
        case_type=case_type,
        **case_block_kwargs
    )
    return case_block
コード例 #16
0
ファイル: utils.py プロジェクト: amonkeykong81/commcare-hq
def assign_cases(caselist, owner_id, acting_user=None, update=None):
    """
    Assign all cases in a list to an owner. Won't update if the owner is already
    set on the case. Doesn't touch parent cases or subcases.

    Returns the list of ids of cases that were reassigned.
    """
    if not caselist:
        return

    def _assert(bool, msg):
        if not bool:
            raise CaseAssignmentError(msg)

    from corehq.apps.users.cases import get_wrapped_owner
    # "security"
    unique_domains = set([c.domain for c in caselist])
    _assert(len(unique_domains) == 1, 'case list had cases spanning multiple domains')
    [domain] = unique_domains
    _assert(domain, 'domain for cases was empty')
    owner = get_wrapped_owner(owner_id)
    _assert(owner, 'no owner with id "%s" found' % owner_id)
    _assert(owner.domain == domain, 'owner was not in domain %s for cases' % domain)

    username = acting_user.username if acting_user else 'system'
    user_id = acting_user._id if acting_user else 'system'
    filtered_cases = set([c for c in caselist if c.owner_id != owner_id])
    if filtered_cases:
        caseblocks = [ElementTree.tostring(CaseBlock(
                create=False,
                case_id=c._id,
                owner_id=owner_id,
                version=V2,
                update=update,
            ).as_xml(format_datetime=json_format_datetime)) for c in filtered_cases
        ]
        # todo: this should check whether the submit_case_blocks call actually succeeds
        submit_case_blocks(caseblocks, domain, username=username,
                           user_id=user_id)

    return [c._id for c in filtered_cases]
コード例 #17
0
 def test_couch_blob_migration_edit(self):
     form_id = uuid.uuid4().hex
     case_id = uuid.uuid4().hex
     case_block = CaseBlock(create=True, case_id=case_id).as_string()
     xform = submit_case_blocks(case_block,
                                domain=self.domain,
                                form_id=form_id)
     # explicitly convert to old-style couch attachments to test the migration workflow
     form_xml = xform.get_xml()
     xform.delete_attachment('form.xml')
     xform.get_db().put_attachment(xform.to_json(), form_xml, 'form.xml')
     # make sure that worked
     updated_form_xml = XFormInstance.get(xform._id).get_xml()
     self.assertEqual(form_xml, updated_form_xml)
     # this call was previously failing
     updated_form = submit_case_blocks(case_block,
                                       domain=self.domain,
                                       form_id=form_id)
     self.assertEqual(
         form_xml,
         XFormInstance.get(updated_form.deprecated_form_id).get_xml())
コード例 #18
0
    def test_multiple_case_blocks_all_rebuilt(self, rebuild_case):
        """ Rebuild all cases in forms with multiple case blocks """

        case_ids = [uuid.uuid4().hex, uuid.uuid4().hex, uuid.uuid4().hex]

        caseblocks = [CaseBlock(
            create=True,
            case_id=case_id,
            owner_id=self.commcare_user._id,
            user_id=self.commcare_user._id,
        ) for case_id in case_ids]
        casexmls = [ElementTree.tostring(caseblock.as_xml()) for caseblock in caseblocks]
        submit_case_blocks(casexmls, self.domain, user_id=self.other_user._id)

        self.other_user.retire()

        detail = UserArchivedRebuild(user_id=self.other_user.user_id)
        expected_call_args = [mock.call(self.domain, case_id, detail) for case_id in case_ids]

        self.assertEqual(rebuild_case.call_count, len(case_ids))
        self.assertItemsEqual(rebuild_case.call_args_list, expected_call_args)
コード例 #19
0
 def case_blocks(self, case):
     username_of_associated_mobile_workers = case.get_case_property(
         'username')
     try:
         normalized_username = normalize_username(
             username_of_associated_mobile_workers, case.domain)
     except ValidationError:
         self.logger.error(
             "ValidationError: invalid username:{} associated with "
             "case:{}".format(case.get_case_property('username'),
                              case.case_id))
         return None
     user_id_of_mobile_worker = username_to_user_id(normalized_username)
     if user_id_of_mobile_worker:
         return [
             CaseBlock(
                 create=False,
                 case_id=case.case_id,
                 update={'hq_user_id': user_id_of_mobile_worker},
             )
         ]
コード例 #20
0
ファイル: test_claim.py プロジェクト: soitun/commcare-hq
    def test_claim_index_deleted(self):
        """
        get_first_claim should return None if claim case is closed
        """
        claim_id = claim_case(DOMAIN,
                              self.restore_user,
                              self.host_case_id,
                              host_type=self.host_case_type,
                              host_name=self.host_case_name)

        # delete the case index
        case_block = CaseBlock(create=False,
                               case_id=claim_id,
                               index={
                                   "host": (self.host_case_type, "")
                               }).as_xml()
        post_case_blocks([case_block], {'domain': DOMAIN})

        first_claim = get_first_claims(DOMAIN, self.user.user_id,
                                       [self.host_case_id])
        self.assertEqual(len(first_claim), 0)
コード例 #21
0
    def testOtherUserCloses(self):
        # create a case from one user
        case_id = "other_user_closes"
        self._createCaseStubs([case_id], owner_id=SHARED_ID)

        # sync then close case from another user
        self.other_sync_log = synclog_from_restore_payload(
            generate_restore_payload(self.other_user))
        close_block = CaseBlock(create=False,
                                case_id=case_id,
                                user_id=USER_ID,
                                version=V2,
                                close=True).as_xml()
        self._postFakeWithSyncToken(close_block, self.other_sync_log.get_id)

        # original user syncs again
        # make sure close block appears
        assert_user_has_case(self,
                             self.user,
                             case_id,
                             restore_id=self.sync_log.get_id)
コード例 #22
0
    def test_edit_an_error(self):
        form_id = uuid.uuid4().hex
        case_block = CaseBlock(
            create=True,
            case_id='',  # this should cause the submission to error
            case_type='person',
            owner_id='some-owner',
        )

        form, _ = submit_case_blocks(case_block.as_text(),
                                     domain=self.domain,
                                     form_id=form_id)
        self.assertTrue(form.is_error)
        self.assertTrue('IllegalCaseId' in form.problem)

        case_block.case_id = uuid.uuid4().hex
        form, _ = submit_case_blocks(case_block.as_text(),
                                     domain=self.domain,
                                     form_id=form_id)
        self.assertFalse(form.is_error)
        self.assertEqual(None, getattr(form, 'problem', None))
コード例 #23
0
 def _submit_followup_form(cls, case_id, received_on):
     form_id = uuid.uuid4().hex
     form_meta = TestFormMetadata(
         domain=cls.domain,
         xmlns=cls.followup_form.xmlns,
         app_id=cls.app._id,
         received_on=received_on,
     )
     properties = cls._get_case_property_values()
     caseblock = CaseBlock(
         case_id=case_id,
         update=properties,
     )
     form_builder = FormSubmissionBuilder(
         form_id=form_id,
         metadata=form_meta,
         case_blocks=[caseblock],
         form_properties=properties,
     )
     submit_form_locally(form_builder.as_xml_string(), cls.domain, received_on=received_on, app_id=cls.app._id)
     return form_id
コード例 #24
0
ファイル: test_ledgers.py プロジェクト: soitun/commcare-hq
    def test_ledger_update_with_case_update(self):
        from corehq.apps.commtrack.tests.util import get_single_balance_block
        submit_case_blocks([
            CaseBlock(case_id=self.case.case_id, update={'a': "1"}).as_text(),
            get_single_balance_block(self.case.case_id, self.product_a._id, 100)],
            DOMAIN
        )

        self._assert_ledger_state(100)
        case = CommCareCase.objects.get_case(self.case.case_id, DOMAIN)
        self.assertEqual("1", case.dynamic_case_properties()['a'])
        transactions = CaseTransaction.objects.get_transactions(self.case.case_id)
        self.assertEqual(2, len(transactions))
        self.assertTrue(transactions[0].is_form_transaction)
        # ordering not guaranteed since they have the same date
        self.assertTrue(transactions[1].is_form_transaction)
        self.assertTrue(transactions[1].is_ledger_transaction)

        self._assert_transactions([
            self._expected_val(100, 100),
        ])
コード例 #25
0
class _UserCaseHelper(object):

    def __init__(self, domain, owner_id):
        self.domain = domain
        self.owner_id = owner_id

    def _submit_case_block(self, caseblock):
        casexml = ElementTree.tostring(caseblock.as_xml())
        submit_case_blocks(casexml, self.domain.name)

    @staticmethod
    def re_open_case(case):
        transactions = case.get_closing_transactions()
        for transaction in transactions:
            transaction.form.archive()

    def create_user_case(self, case_type, commcare_user, fields):
        fields['hq_user_id'] = commcare_user._id
        caseblock = CaseBlock(
            create=True,
            case_id=uuid.uuid4().hex,
            owner_id=self.owner_id,
            user_id=self.owner_id,
            case_type=case_type,
            case_name=fields.pop('name', None),
            update=fields
        )
        self._submit_case_block(caseblock)

    def update_user_case(self, case, case_type, fields):
        caseblock = CaseBlock(
            create=False,
            case_id=case.case_id,
            owner_id=self.owner_id,
            case_type=case_type,
            case_name=fields.pop('name', None),
            close=False,
            update=fields
        )
        self._submit_case_block(caseblock)
コード例 #26
0
def reassign_household_case(domain, household_case_id, old_owner_id, new_owner_id, supervisor_id,
                            deprecation_time=None):
    if deprecation_time is None:
        deprecation_time = datetime.utcnow()
    case_ids = get_household_and_child_case_ids_by_owner(domain, household_case_id, old_owner_id)
    case_ids.add(household_case_id)
    case_blocks = []
    for case_id in case_ids:
        updates = {
            'location_reassignment_last_owner_id': old_owner_id,
            'location_reassignment_datetime': deprecation_time
        }
        if supervisor_id:
            updates['location_reassignment_last_supervisor_id'] = supervisor_id
        case_block = CaseBlock(case_id,
                               update=updates,
                               owner_id=new_owner_id,
                               user_id=SYSTEM_USER_ID)
        case_block = ElementTree.tostring(case_block.as_xml()).decode('utf-8')
        case_blocks.append(case_block)
    if case_blocks:
        submit_case_blocks(case_blocks, domain, user_id=SYSTEM_USER_ID)
コード例 #27
0
ファイル: test_ledgers.py プロジェクト: xbryanc/commcare-hq
    def test_ledger_update_with_case_update(self):
        from corehq.apps.commtrack.tests.util import get_single_balance_block
        submit_case_blocks([
            CaseBlock(case_id=self.case.case_id, update={'a': "1"}).as_string(),
            get_single_balance_block(self.case.case_id, self.product_a._id, 100)],
            DOMAIN
        )

        self._assert_ledger_state(100)
        case = CaseAccessors(DOMAIN).get_case(self.case.case_id)
        self.assertEqual("1", case.dynamic_case_properties()['a'])
        if getattr(settings, 'TESTS_SHOULD_USE_SQL_BACKEND', False):
            transactions = CaseAccessorSQL.get_transactions(self.case.case_id)
            self.assertEqual(2, len(transactions))
            self.assertTrue(transactions[0].is_form_transaction)
            # ordering not guaranteed since they have the same date
            self.assertTrue(transactions[1].is_form_transaction)
            self.assertTrue(transactions[1].is_ledger_transaction)

        self._assert_transactions([
            self._expected_val(100, 100),
        ])
コード例 #28
0
    def create_scan_case(self,
                         user_id,
                         serial,
                         scan_id,
                         scan_time,
                         scan_status=''):
        case_id = uuid.uuid4().hex
        case_block = CaseBlock(create=True,
                               case_id=case_id,
                               case_name='scan',
                               case_type=UTH_CASE_TYPE,
                               user_id=user_id,
                               owner_id=user_id,
                               update={
                                   'exam_number': scan_id,
                                   'scanner_serial': serial,
                                   'scan_status': scan_status,
                                   'scan_time': scan_time
                               }).as_xml()
        post_case_blocks([case_block], {'domain': UTH_DOMAIN})

        return case_id
コード例 #29
0
def set_schedule_case_properties(pact_case):
    """
    Sets the required schedule case properties on the case if they are different from the current
    case properties. See the README for more information.
    """
    SCHEDULE_CASE_PROPERTY_PREFIX = 'dotSchedule'
    DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']
    current_schedule = pact_case.current_schedule
    if current_schedule is not None:
        to_change = {}
        for day in DAYS:
            case_property_name = '{}{}'.format(SCHEDULE_CASE_PROPERTY_PREFIX, day)
            from_case = getattr(pact_case, case_property_name, None)
            from_schedule = current_schedule[day]
            if (from_case or from_schedule) and from_case != from_schedule:
                to_change[case_property_name] = current_schedule[day]
        if to_change:
            case_block = CaseBlock(
                case_id=pact_case._id,
                update=to_change,
            ).as_xml()
            submit_case_blocks([ElementTree.tostring(case_block)], 'pact')
コード例 #30
0
    def set_up_form(cls):
        cls.form_id = uuid4().hex
        user_id = uuid4().hex
        cls.case_update = {
            'year': '1970',
            'breakfast': 'spam egg spam spam bacon spam',
            'price': '2.40',
            'album_release': '1972-09-08',
            'breakfast_oclock': '09:00:00',
            'breakfast_exactly': '1972-09-08T09:00:00.000Z',
        }
        builder = FormSubmissionBuilder(
            form_id=cls.form_id,
            form_properties={
                'name': 'spam',
                **cls.case_update,
            },
            case_blocks=[
                CaseBlock(case_id=uuid4().hex,
                          create=True,
                          case_type='sketch',
                          case_name='spam',
                          owner_id=user_id,
                          update=cls.case_update)
            ],
            metadata=TestFormMetadata(
                domain=cls.domain,
                user_id=user_id,
            ),
        )
        submit_form_locally(builder.as_xml_string(), cls.domain)
        cls.form = FormAccessors(cls.domain).get_form(cls.form_id)

        form_json_gen = FormRepeaterJsonPayloadGenerator(None)
        cls.form_json_payload_info = cls.get_payload_info(form_json_gen)

        form_dict_gen = FormDictPayloadGenerator(None)
        cls.form_dict_payload_info = cls.get_payload_info(form_dict_gen)