def setUpClass(cls): super(TestBuildingCaseSchemaFromMultipleApplications, cls).setUpClass() cls.current_app = Application.wrap(cls.get_json('basic_case_application')) cls.other_current_app = Application.wrap(cls.get_json('basic_case_application')) cls.other_current_app._id = 'other-app-id' cls.first_build = Application.wrap(cls.get_json('basic_case_application')) cls.first_build._id = '123' cls.first_build.copy_of = cls.current_app.get_id cls.first_build.version = 3 cls.other_build = Application.wrap(cls.get_json('basic_case_application')) cls.other_build._id = '456' cls.other_build.copy_of = cls.other_current_app._id cls.other_build.version = 4 cls.other_build.has_submissions = True cls.apps = [ cls.current_app, cls.other_current_app, cls.first_build, cls.other_build, ] with drop_connected_signals(app_post_save): for app in cls.apps: app.save()
def setUpClass(cls): super(TestDelayedSchema, cls).setUpClass() cls.current_app = Application.new_app(cls.domain, "Untitled Application") cls.current_app._id = '1234' cls.current_app.version = 10 module = cls.current_app.add_module(Module.new_module('Untitled Module', None)) form = module.new_form("Untitled Form", 'en', attachment=cls.get_xml('basic_form').decode('utf-8')) form.xmlns = cls.xmlns cls.build = Application.new_app(cls.domain, "Untitled Application") cls.build._id = '5678' cls.build.copy_of = cls.current_app._id cls.build.version = 5 cls.build.has_submissions = True module = cls.build.add_module(Module.new_module('Untitled Module', None)) form = module.new_form("Untitled Form", 'en', attachment=cls.get_xml('basic_form_version2').decode('utf-8')) form.xmlns = cls.xmlns cls.apps = [ cls.current_app, cls.build, ] with drop_connected_signals(app_post_save): for app in cls.apps: app.save()
def set_up_apps(self, how_many): apps = [] for _ in range(how_many): app = Application() app.profile["features"], app.profile["properties"] = {}, {} apps.append(app) return tuple(apps)
def update_schema(self): key = [self.domain, self.app_id] all_apps = Application.get_db().view( 'app_manager/saved_app', startkey=key + [self.last_processed_version], endkey=key + [{}], reduce=False, include_docs=False, skip=(1 if self.last_processed_version else 0)).all() all_seen_apps = self.apps_with_errors | self.processed_apps to_process = [ app['id'] for app in all_apps if app['id'] not in all_seen_apps ] if self.app_id not in all_seen_apps: to_process.append(self.app_id) for app_doc in iter_docs(Application.get_db(), to_process): if app_doc['doc_type'] == 'RemoteApp': continue app = Application.wrap(app_doc) try: self.update_for_app(app) except AppManagerException: self.apps_with_errors.add(app.get_id) self.last_processed_version = app.version if to_process: self.save()
def generate_schema_from_builds(domain, case_type): """Builds a schema from Application builds for a given identifier :param domain: The domain that the export belongs to :param unique_form_id: The unique identifier of the item being exported :returns: Returns a ExportDataSchema instance """ app_build_ids = get_all_app_ids(domain) all_case_schema = CaseExportDataSchema() for app_doc in iter_docs(Application.get_db(), app_build_ids): app = Application.wrap(app_doc) case_property_mapping = get_case_properties( app, [case_type], include_parent_properties=False ) case_schema = CaseExportDataSchema._generate_schema_from_case_property_mapping( case_property_mapping, app.version, ) case_history_schema = CaseExportDataSchema._generate_schema_for_case_history( case_property_mapping, app.version, ) all_case_schema = CaseExportDataSchema._merge_schemas( all_case_schema, case_schema, case_history_schema ) return all_case_schema
def setUpClass(cls): delete_all_users() create_domain(cls.domain) toggles.MOBILE_UCR.set(cls.domain, True, toggles.NAMESPACE_DOMAIN) cls.user = create_restore_user(cls.domain) cls.app1 = Application.new_app(cls.domain, "Test App 1") cls.report_config1 = get_sample_report_config() cls.report_config1.domain = cls.domain cls.report_config1.save() report_app_config = {"report_id": cls.report_config1.get_id, "uuid": "123456"} module = cls.app1.add_module(ReportModule.new_module("Reports", None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app1.save() cls.app2 = Application.new_app(cls.domain, "Test App 2") cls.report_config2 = get_sample_report_config() cls.report_config2.domain = cls.domain cls.report_config2.save() report_app_config = {"report_id": cls.report_config2.get_id, "uuid": "abcdef"} module = cls.app2.add_module(ReportModule.new_module("Reports", None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app2.save() cls.app3 = Application.new_app(cls.domain, "Test App 3") cls.app3.save()
def save(self, domain): domain.restrict_superusers = self.cleaned_data.get('restrict_superusers', False) try: secure_submissions = self.cleaned_data.get( 'secure_submissions', False) apps_to_save = [] if secure_submissions != domain.secure_submissions: for app in get_apps_in_domain(domain.name): if app.secure_submissions != secure_submissions: app.secure_submissions = secure_submissions apps_to_save.append(app) domain.secure_submissions = secure_submissions domain.save() if apps_to_save: apps = [app for app in apps_to_save if isinstance(app, Application)] remote_apps = [app for app in apps_to_save if isinstance(app, RemoteApp)] if apps: Application.bulk_save(apps) if remote_apps: RemoteApp.bulk_save(remote_apps) return True except Exception: return False
def test_edit_commcare_profile(self, mock): app2 = Application.new_app(self.project.name, "TestApp2") app2.save() self.addCleanup(lambda: Application.get_db().delete_doc(app2.id)) data = { "custom_properties": { "random": "value", "another": "value" } } response = self.client.post(reverse('edit_commcare_profile', args=[self.project.name, app2._id]), json.dumps(data), content_type='application/json') content = json.loads(response.content) custom_properties = content["changed"]["custom_properties"] self.assertEqual(custom_properties["random"], "value") self.assertEqual(custom_properties["another"], "value") data = { "custom_properties": { "random": "changed", } } response = self.client.post(reverse('edit_commcare_profile', args=[self.project.name, app2._id]), json.dumps(data), content_type='application/json') content = json.loads(response.content) custom_properties = content["changed"]["custom_properties"] self.assertEqual(custom_properties["random"], "changed")
def setUpClass(cls): super(AppAwareSyncTests, cls).setUpClass() delete_all_users() cls.domain_obj = create_domain(cls.domain) toggles.MOBILE_UCR.set(cls.domain, True, toggles.NAMESPACE_DOMAIN) cls.user = create_restore_user(cls.domain) cls.app1 = Application.new_app(cls.domain, 'Test App 1') cls.report_config1 = get_sample_report_config() cls.report_config1.domain = cls.domain cls.report_config1.save() report_app_config = { 'report_id': cls.report_config1.get_id, 'uuid': '123456' } module = cls.app1.add_module(ReportModule.new_module('Reports', None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app1.save() cls.app2 = Application.new_app(cls.domain, 'Test App 2') cls.report_config2 = get_sample_report_config() cls.report_config2.domain = cls.domain cls.report_config2.save() report_app_config = { 'report_id': cls.report_config2.get_id, 'uuid': 'abcdef' } module = cls.app2.add_module(ReportModule.new_module('Reports', None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app2.save() cls.app3 = Application.new_app(cls.domain, 'Test App 3') cls.app3.save()
def setUpClass(cls): create_domain(cls.domain) toggles.MOBILE_UCR.set(cls.domain, True, toggles.NAMESPACE_DOMAIN) cls.user = CommCareUser.create(cls.domain, 'john_doe', 's3cr3t') cls.app1 = Application.new_app(cls.domain, 'Test App 1', application_version=APP_V2) cls.report_config1 = get_sample_report_config() cls.report_config1.save() report_app_config = { 'report_id': cls.report_config1.get_id, 'uuid': '123456' } module = cls.app1.add_module(ReportModule.new_module('Reports', None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app1.save() cls.app2 = Application.new_app(cls.domain, 'Test App 2', application_version=APP_V2) cls.report_config2 = get_sample_report_config() cls.report_config2.save() report_app_config = { 'report_id': cls.report_config2.get_id, 'uuid': 'abcdef' } module = cls.app2.add_module(ReportModule.new_module('Reports', None)) module.report_configs = [ReportAppConfig.wrap(report_app_config)] cls.app2.save() cls.app3 = Application.new_app(cls.domain, 'Test App 3', application_version=APP_V2) cls.app3.save()
def get_translations(cls, lang, key=None, one=False): from corehq.apps.app_manager.models import Application if key: translations = [] r = Application.get_db().view('app_translations_by_popularity/view', startkey=[lang, key], endkey=[lang, key, {}], group=True ).all() r.sort(key=lambda x: -x['value']) for row in r: _, _, translation = row['key'] translations.append(translation) if one: return translations[0] if translations else None return translations else: translations = defaultdict(list) r = Application.get_db().view('app_translations_by_popularity/view', startkey=[lang], endkey=[lang, {}], group=True ).all() r.sort(key=lambda x: (x['key'][1], -x['value'])) for row in r: _, key, translation = row['key'] translations[key].append(translation) if one: return dict([(key, val[0]) for key, val in translations.items()]) else: return translations
def _setup_apps(cls): cls.non_wam_app = Application.new_app(cls.DOMAIN_NAME, "app 1") cls.wam_app = Application.new_app(cls.DOMAIN_NAME, "app 2") cls.wam_app.amplifies_workers = AMPLIFIES_YES cls.non_wam_app.save() cls.wam_app.save() cls.non_wam_app_id = cls.non_wam_app._id cls.wam_app_id = cls.wam_app._id
def generate_schema_from_builds(domain, case_type, force_rebuild=False): """Builds a schema from Application builds for a given identifier :param domain: The domain that the export belongs to :param unique_form_id: The unique identifier of the item being exported :returns: Returns a CaseExportDataSchema instance """ original_id, original_rev = None, None current_case_schema = get_latest_case_export_schema(domain, case_type) if current_case_schema and not force_rebuild: # Save the original id an rev so we can later save the document under the same _id original_id, original_rev = current_case_schema._id, current_case_schema._rev else: current_case_schema = CaseExportDataSchema() app_build_ids = CaseExportDataSchema._get_app_build_ids_to_process( domain, current_case_schema.last_app_versions, ) for app_doc in iter_docs(Application.get_db(), app_build_ids): app = Application.wrap(app_doc) case_property_mapping = get_case_properties( app, [case_type], include_parent_properties=False ) case_schema = CaseExportDataSchema._generate_schema_from_case_property_mapping( case_property_mapping, app.copy_of, app.version, ) case_history_schema = CaseExportDataSchema._generate_schema_for_case_history( case_property_mapping, app.copy_of, app.version, ) current_case_schema = CaseExportDataSchema._merge_schemas( current_case_schema, case_schema, case_history_schema ) current_case_schema.record_update(app.copy_of, app.version) if original_id and original_rev: current_case_schema._id = original_id current_case_schema._rev = original_rev current_case_schema.domain = domain current_case_schema.case_type = case_type current_case_schema.save() return current_case_schema
def update_analytics_indexes(): """ Mostly for testing; wait until analytics data sources are up to date so that calls to analytics functions return up-to-date """ from corehq.apps.app_manager.models import Application XFormInstance.get_db().view('couchforms/all_submissions_by_domain', limit=1).all() XFormInstance.get_db().view('all_forms/view', limit=1).all() XFormInstance.get_db().view('exports_forms_by_xform/view', limit=1).all() Application.get_db().view('exports_forms_by_app/view', limit=1).all()
def dispatch(self, request, *args, **kwargs): try: self.first_app_id = self.kwargs["first_app_id"] self.second_app_id = self.kwargs["second_app_id"] self.first_app = Application.get(self.first_app_id) self.second_app = Application.get(self.second_app_id) except (ResourceNotFound, KeyError): raise Http404() return super(AppDiffView, self).dispatch(request, *args, **kwargs)
def _get_app_by_name(domain, name): app = Application.view('app_manager/applications_brief', startkey=[domain, name, {}], endkey=[domain, name], descending=True, limit=1).one() if app: return Application.get(app['_id']) else: raise ResourceNotFound(_("Not found application by name: %s") % name)
def testBuildApp(self): # do it from a NOT-SAVED app; # regression test against case where contents gets lazy-put w/o saving app = Application.wrap(self._yesno_source) self.assertEqual(app['_id'], None) # i.e. hasn't been saved app._id = Application.get_db().server.next_uuid() copy = app.make_build() copy.save() self._check_has_build_files(copy) self._check_legacy_odk_files(copy)
def setUp(self): create_domain(self.domain) couch_user = CommCareUser.create(self.domain, self.username, self.password) userID = couch_user.user_id couch_user.first_name = self.first_name couch_user.last_name = self.last_name couch_user.save() self.sm = SuccessMessage(self.message, userID, tz=self.tz) c = Client() app = Application.new_app(self.domain, "Test App", application_version=APP_V1) app.add_module(Module.new_module("Test Module", "en")) form = app.new_form(0, "Test Form", "en") form.xmlns = self.xmlns app.success_message = {"en": self.message} app.save() # hack: prime the view once so the success message takes even though we use stale queries in submissions Application.get_db().view('exports_forms/by_xmlns', limit=1).one() def fake_form_submission(userID=userID, username=self.username, xmlns=self.xmlns, time=None): submission = submission_template % { "userID": userID, "username": username, "xmlns": xmlns } f = StringIO(submission.encode('utf-8')) f.name = "tempfile.xml" kwargs = dict(HTTP_X_SUBMIT_TIME=json_format_datetime(time)) if time else {} response = c.post("/a/{self.domain}/receiver/".format(self=self), { 'xml_submission_file': f, }, **kwargs) return response self.num_forms_today = 0 self.num_forms_this_week = 0 now = datetime.utcnow() tznow = now + self.tz week_start = tznow - timedelta(days=tznow.weekday()) week_start = datetime(week_start.year, week_start.month, week_start.day) - self.tz day_start = datetime(tznow.year, tznow.month, tznow.day) - self.tz spacing = 6 for h in xrange((24/spacing)*8): time = now-timedelta(hours=spacing*h) response = fake_form_submission(time=time) if time > week_start: self.num_forms_this_week += 1 if time > day_start: self.num_forms_today += 1 self.assertEqual( response.content, get_simple_response_xml(("Thanks {self.first_name} ({self.first_name} {self.last_name})! " "You have submitted {self.num_forms_today} forms today " "and {self.num_forms_this_week} forms since Monday.").format(self=self), nature=ResponseNature.SUBMIT_SUCCESS) )
def delete_all_apps(): results = Application.get_db().view( 'app_manager/applications', reduce=False, include_docs=False, ).all() for result in results: try: app = Application.get(result['id']) except Exception: pass else: app.delete()
def apps_modules_setup(test_case): """ Additional setUp and tearDown for get_apps_modules tests """ test_case.app.add_module(Module.new_module("Module0", "en")) test_case.app.save() test_case.other_app = Application.new_app(test_case.project.name, "OtherApp") test_case.other_app.add_module(Module.new_module("Module0", "en")) test_case.other_app.save() test_case.deleted_app = Application.new_app(test_case.project.name, "DeletedApp") test_case.deleted_app.add_module(Module.new_module("Module0", "en")) test_case.deleted_app.save() test_case.deleted_app.delete_app() test_case.deleted_app.save() # delete_app() changes doc_type. This save() saves that. test_case.linked_app = create_linked_app(test_case.project.name, test_case.app.id, test_case.project.name, 'LinkedApp') try: yield finally: Application.get_db().delete_doc(test_case.linked_app.id) Application.get_db().delete_doc(test_case.deleted_app.id) Application.get_db().delete_doc(test_case.other_app.id)
def handle(self, *args, **options): app_ids = [] try: Application.get(args[0]) app_ids = [args[0]] except ResourceNotFound: app_ids = get_app_ids_in_domain(args[0]) logger.info('migrating {} apps in domain {}'.format(len(app_ids), args[0])) for app_id in app_ids: logger.info('migrating app {}'.format(app_id)) self.migrate_app(app_id) logger.info('done with migrate_app_to_cmitfb')
def setUpClass(cls): cls.current_app = Application.wrap(cls.get_json('basic_case_application')) cls.first_build = Application.wrap(cls.get_json('basic_case_application')) cls.first_build._id = '123' cls.first_build.copy_of = cls.current_app.get_id cls.first_build.version = 3 cls.apps = [ cls.current_app, cls.first_build, ] for app in cls.apps: app.save()
def setUpClass(cls): cls.current_app = Application.wrap(cls.get_json('basic_case_application')) cls.first_build = Application.wrap(cls.get_json('basic_case_application')) cls.first_build._id = '123' cls.first_build.copy_of = cls.current_app.get_id cls.first_build.version = 3 cls.apps = [ cls.current_app, cls.first_build, ] with drop_connected_signals(app_post_save): for app in cls.apps: app.save()
def test_update_form_references_case_list_form(self): app = Application.new_app('domain', 'Foo') app.modules.append(Module(forms=[Form()])) app.modules.append(Module(forms=[Form()])) app.build_spec = BuildSpec.from_string('2.7.0/latest') app.get_module(0).get_form(0).source = BLANK_TEMPLATE.format(xmlns='xmlns-0.0') app.get_module(1).get_form(0).source = BLANK_TEMPLATE.format(xmlns='xmlns-1') original_form_id = app.get_module(1).get_form(0).unique_id app.get_module(0).case_list_form.form_id = original_form_id copy = Application.from_source(app.export_json(dump_json=False), 'domain') new_form_id = copy.get_module(1).get_form(0).unique_id self.assertNotEqual(original_form_id, new_form_id) self.assertEqual(new_form_id, copy.get_module(0).case_list_form.form_id)
def test_advanced_suite_details(self): app = Application.wrap(self.get_json('suite-advanced')) clinic_module_id = app.get_module(0).unique_id other_module_id = app.get_module(1).unique_id app.get_module(1).get_form(0).actions.load_update_cases[0].details_module = clinic_module_id app.get_module(1).get_form(1).actions.load_update_cases[0].details_module = other_module_id self.assertXmlEqual(self.get_xml('suite-advanced-details'), app.create_suite())
def test_build_from_saved_schema(self): app = self.current_app schema = FormExportDataSchema.generate_schema_from_builds( app.domain, app._id, 'my_sweet_xmlns' ) self.assertEqual(len(schema.group_schemas), 1) self.assertEqual(schema.last_app_versions[app._id], self.first_build.version) # After the first schema has been saved let's add a second app to process second_build = Application.wrap(self.get_json('basic_application')) second_build._id = '456' second_build.copy_of = app.get_id second_build.version = 6 second_build.has_submissions = True second_build.save() self.addCleanup(second_build.delete) new_schema = FormExportDataSchema.generate_schema_from_builds( app.domain, app._id, 'my_sweet_xmlns' ) self.assertEqual(new_schema._id, schema._id) self.assertEqual(new_schema.last_app_versions[app._id], second_build.version) self.assertEqual(len(new_schema.group_schemas), 1)
def testBuildApp(self): # do it from a NOT-SAVED app; # regression test against case where contents gets lazy-put w/o saving app = Application.wrap(self._yesno_source) self.assertEqual(app['_id'], None) # i.e. hasn't been saved copy = app.make_build() copy.save()
def setUp(self): self.domain = 'test-domain' create_domain(self.domain) self.app = Application.new_app(self.domain, "TestApp", application_version=APP_V1) for i in range(3): module = self.app.new_module("Module%d" % i, "en") for j in range(3): self.app.new_form(module.id, name="Form%s-%s" % (i,j), attachment=self.xform_str, lang="en") module = self.app.get_module(i) detail = module.get_detail("ref_short") detail.append_column( DetailColumn(name={"en": "test"}, model="case", field="test", format="plain", enum={}) ) detail.append_column( DetailColumn(name={"en": "age"}, model="case", field="age", format="years-ago", enum={}) ) self.app.save() self.build1 = {'version': '1.2.dev', 'build_number': 7106} self.build2 = {'version': '2.7.0', 'build_number': 20655} def add_build(version, build_number): path = os.path.join(os.path.dirname(__file__), "jadjar") jad_path = os.path.join(path, 'CommCare_%s_%s.zip' % (version, build_number)) CommCareBuild.create_from_zip(jad_path, version, build_number) add_build(**self.build1) add_build(**self.build2)
def test_advanced_suite_auto_select_user(self): app = Application.wrap(self.get_json('suite-advanced')) app.get_module(1).get_form(0).actions.load_update_cases[0].auto_select = AutoSelectCase( mode=AUTO_SELECT_USER, value_key='case_id' ) self.assertXmlEqual(self.get_xml('suite-advanced-autoselect-user'), app.create_suite())
def test_form_workflow_module(self): app = Application.wrap(self.get_json('suite-workflow')) for module in app.get_modules(): for form in module.get_forms(): form.post_form_workflow = WORKFLOW_MODULE self.assertXmlEqual(self.get_xml('suite-workflow-module'), app.create_suite())
def handle(self, path, app_id, **options): if options['deploy'] and not options['user']: raise CommandError('Deploy argument requires a user') elif options['deploy']: user = CouchUser.get_by_username(options['user']) if not user: raise CommandError( "Couldn't find user with username {}".format( options['user'])) app = Application.get(app_id) for module_dir in os.listdir(path): module_index, name = module_dir.split(' - ') module = app.get_module(int(module_index)) for form_name in os.listdir(os.path.join(path, module_dir)): form_index, name = form_name.split(' - ') form = module.get_form(int(form_index)) with open(os.path.join(path, module_dir, form_name), 'rb') as f: save_xform(app, form, f.read()) app.save() print('successfully updated {}'.format(app.name)) if options['deploy']: # make build and star it comment = options.get( 'comment', 'form changes from {0}'.format( datetime.utcnow().strftime(SERVER_DATETIME_FORMAT_NO_SEC))) copy = app.make_build( comment=comment, user_id=user._id, previous_version=app.get_latest_app(released_only=False), ) copy.is_released = True copy.save(increment_version=False) print('successfully released new version')
def test_case_references(self): app = Application.new_app('domain', 'New App') app._id = uuid.uuid4().hex app.version = 1 m0 = self._make_module(app, 0, 'household') m0f1 = m0.new_form( 'save to case', 'en', attachment=self.get_xml('standard_questions').decode('utf-8')) m0f1.case_references = CaseReferences.wrap({ 'save': { "/data/question1": { "case_type": "household", "properties": ["save_to_case_p1", "save_to_case_p2"], } } }) meta = app.get_case_metadata() self._assert_properties(meta, {'name', 'save_to_case_p1', 'save_to_case_p2'}) self.assertEqual( meta.get_type('household').get_save_properties( m0f1.unique_id, '/data/question1'), ['save_to_case_p1', 'save_to_case_p2'])
def fetch_and_build_app(self, domain, app_id): try: username = os.environ['TRAVIS_HQ_USERNAME'] password = os.environ['TRAVIS_HQ_PASSWORD'] except KeyError as err: if os.environ.get("TRAVIS") == "true": raise raise SkipTest("not travis (KeyError: {})".format(err)) url = "https://www.commcarehq.org/a/{}/apps/source/{}/".format( domain, app_id ) response = requests.get(url, auth=HTTPDigestAuth(username, password)) if response.status_code == 401 and not os.environ.get("TRAVIS_SECURE_ENV_VARS") == "true": # on travis this test fails for non-dimagi repos because encrypted variables don't work # see https://docs.travis-ci.com/user/environment-variables/#Defining-encrypted-variables-in-.travis.yml raise SkipTest("Not running TestRealBuild from external PR from {}".format( os.environ.get('TRAVIS_REPO_SLUG') )) response.raise_for_status() with mock.patch.object(Application, 'enable_practice_users', return_value=False): app = Application.wrap(response.json()) app.create_all_files()
def test_build_from_saved_schema(self): app = self.current_app schema = CaseExportDataSchema.generate_schema_from_builds( app.domain, app._id, self.case_type, ) self.assertEqual(schema.last_app_versions[app._id], self.first_build.version) # One for case, one for case history self.assertEqual(len(schema.group_schemas), 2) # After the first schema has been saved let's add a second app to process second_build = Application.wrap( self.get_json('basic_case_application')) second_build._id = '456' second_build.copy_of = app.get_id second_build.version = 6 second_build.has_submissions = True with drop_connected_signals(app_post_save): second_build.save() self.addCleanup(second_build.delete) new_schema = CaseExportDataSchema.generate_schema_from_builds( app.domain, app._id, self.case_type, ) self.assertEqual(new_schema._id, schema._id) self.assertEqual(new_schema.last_app_versions[app._id], second_build.version) # One for case, one for case history self.assertEqual(len(new_schema.group_schemas), 2)
def forms_with_empty_case_block(build): """ Forms that may have caused this bug: http://manage.dimagi.com/default.asp?158371 """ try: app = Application.wrap(build) except: return forms = set() case_types = set() for module in app.get_modules(): for form in module.get_forms(): if form.requires == "case": if form.form_type == 'module_form' and not form.actions.update_case.update: forms.add(form.xmlns) case_types.add(module.case_type) elif form.form_type == 'advanced_form': for action in form.actions.load_update_cases: if not action.case_properties: forms.add(form.xmlns) case_types.add(action.case_type) return (case_types, forms) if forms or case_types else None
def test_subcase_repeat_mixed_form(self): app = Application.new_app(None, "Untitled Application") module_0 = app.add_module(Module.new_module('parent', None)) module_0.unique_id = 'm0' module_0.case_type = 'parent' form = app.new_form( 0, "Form", None, attachment=self.get_xml('subcase_repeat_mixed_form_pre').decode( 'utf-8')) module_1 = app.add_module(Module.new_module('subcase', None)) module_1.unique_id = 'm1' module_1.case_type = 'subcase' form.actions.open_case = OpenCaseAction(name_path="/data/parent_name") form.actions.open_case.condition.type = 'always' form.actions.subcases.append( OpenSubCaseAction(case_type=module_1.case_type, case_name="/data/first_child_name", condition=FormActionCondition(type='always'))) # subcase in the middle that has a repeat context form.actions.subcases.append( OpenSubCaseAction(case_type=module_1.case_type, case_name="/data/repeat_child/repeat_child_name", repeat_context='/data/repeat_child', condition=FormActionCondition(type='always'))) form.actions.subcases.append( OpenSubCaseAction(case_type=module_1.case_type, case_name="/data/last_child_name", condition=FormActionCondition(type='always'))) self.assertXmlEqual(self.get_xml('subcase_repeat_mixed_form_post'), app.get_module(0).get_form(0).render_xform())
def test_advanced_suite_load_case_from_fixture_with_arbitrary_datum( self, *args): app = Application.wrap(self.get_json('suite-advanced')) app.get_module(1).get_form(0).actions.load_update_cases.append( LoadUpdateAction( case_tag="adherence", case_type="clinic", load_case_from_fixture=LoadCaseFromFixture( fixture_nodeset= "instance('item-list:table_tag')/calendar/year/month/day[@date > 735992 and @date < 736000]", fixture_tag="selected_date", fixture_variable="./@date", case_property="adherence_event_date", auto_select=True, arbitrary_datum_id="extra_id", arbitrary_datum_function="extra_function()", ))) suite = app.create_suite() self.assertXmlPartialEqual( self.get_xml('load_case_from_fixture_arbitrary_datum'), suite, './entry[2]/session') self.assertXmlPartialEqual( self.get_xml('load_case_from_fixture_instance'), suite, './entry[2]/instance')
def obj_get_list(self, bundle, **kwargs): application_id = bundle.request.GET.get('application_id') if not application_id: raise NotFound('application_id parameter required') domain = kwargs['domain'] couch_user = CouchUser.from_django_user(bundle.request.user) if not domain_has_privilege(domain, privileges.ZAPIER_INTEGRATION) or not couch_user.is_member_of(domain): raise ImmediateHttpResponse( HttpForbidden('You are not allowed to get list of forms for this domain') ) results = [] application = Application.get(docid=application_id) if not application: return [] forms_objects = application.get_forms(bare=False) for form_object in forms_objects: form = form_object['form'] module = form_object['module'] form_name = u'{} > {} > {}'.format(application.name, module.default_name(), form.default_name()) results.append(Form(form_xmlns=form.xmlns, form_name=form_name)) return results
def form_context(request, domain, app_id, module_id, form_id): app = Application.get(app_id) form_url = '{}{}'.format( settings.CLOUDCARE_BASE_URL or get_url_base(), reverse('download_xform', args=[domain, app_id, module_id, form_id]) ) case_id = request.GET.get('case_id') instance_id = request.GET.get('instance_id') try: form = app.get_module(module_id).get_form(form_id) except (FormNotFoundException, ModuleNotFoundException): raise Http404() form_name = list(form.name.values())[0] # make the name for the session we will use with the case and form session_name = '{app} > {form}'.format( app=app.name, form=form_name, ) if case_id: case = CaseAccessors(domain).get_case(case_id) session_name = '{0} - {1}'.format(session_name, case.name)
def setUp(self): self.all_attrs = [ 'columns', 'filter', 'sort_elements', 'custom_variables', 'custom_xml', 'case_tile_configuration', 'multi_select', 'print_template' ] self.cols_and_filter = ['columns', 'filter'] self.case_tile = ['case_tile_configuration'] self.app = Application.new_app('domain', "Untitled Application") self.src_module = self.app.add_module( Module.new_module('Src Module', lang='en')) self.src_detail = getattr(self.src_module.case_details, "short") self.header_ = getattr(self.src_detail.columns[0], 'header') self.header_['en'] = 'status' self.filter_ = setattr(self.src_detail, 'filter', 'a > b') self.custom_variables = setattr(self.src_detail, 'custom_variables', 'def') self.custom_xml = setattr(self.src_detail, 'custom_xml', 'ghi') self.multi_select = getattr(self.src_detail, 'multi_select') self.print_template = getattr(self.src_detail, 'print_template') self.print_template['name'] = 'test' self.case_tile_configuration = setattr(self.src_detail, 'persist_tile_on_forms', True)
def test_migrate_happy_path(self): apps = {} form = u'<fake xform source>\u2713</fake>' for doc_type, model_class in self.doc_type_map.items(): app = model_class() app.save() super(BlobMixin, app).put_attachment(form, "form.xml") app.doc_type = doc_type app.save() apps[doc_type] = app # add legacy attribute to make sure the migration uses doc_type.wrap() app = apps["Application"] db = app.get_db() doc = db.get(app._id, wrapper=None) doc["commtrack_enabled"] = True db.save_doc(doc) apps["Application"] = Application.get(app._id) # update _rev self.do_migration(apps.values()) for app in apps.values(): exp = type(app).get(app._id) self.assertEqual(exp.fetch_attachment("form.xml"), form)
def handle(self, **options): app_ids_by_domain = defaultdict(set) self.force = options["force"] self.dry = "DRY RUN " if options["dry_run"] else "" self.fail_hard = options["fail_hard"] self.fup_caseref = options["fix_user_props_caseref"] self.fix_user_props = options["fix_user_properties"] or self.fup_caseref self.migrate_usercase = options["usercase"] for ident in options["app_id_or_domain"]: if not (self.migrate_usercase or self.fix_user_props): try: app = Application.get(ident) app_ids_by_domain[app.domain].add(ident) continue except ResourceNotFound: pass app_ids_by_domain[ident].update(get_app_ids_in_domain(ident)) for domain, app_ids in sorted(app_ids_by_domain.items()): logger.info('migrating %s: %s apps', domain, len(app_ids)) for app_id in app_ids: try: app = get_app(domain, app_id) if app.doc_type == "Application": if self.fix_user_props: self.fix_user_properties(app) else: self.migrate_app(app) else: logger.info("Skipping %s/%s because it is a %s", domain, app_id, app.doc_type) except Exception as e: logger.exception("skipping app %s/%s", domain, app_id) if self.fail_hard: raise e logger.info('done with migrate_app_to_cmitfb %s', self.dry)
def setUp(self): self.is_usercase_in_use_patch = patch( 'corehq.apps.app_manager.models.is_usercase_in_use') self.is_usercase_in_use_mock = self.is_usercase_in_use_patch.start() self.is_usercase_in_use_mock.return_value = True self.app = Application.new_app('domain', 'New App') self.module = self.app.add_module( AdvancedModule.new_module('Fish Module', None)) self.module.case_type = 'fish' self.form = self.module.new_form( 'Form', 'en', self.get_xml('original').decode('utf-8')) self.other_module = self.app.add_module( AdvancedModule.new_module('Freshwater Module', lang='en')) self.other_module.case_type = 'freshwater' self.other_form = self.module.new_form( 'Other Form', 'en', self.get_xml('original').decode('utf-8')) self.case_index = CaseIndex( reference_id='host', relationship='extension', ) self.subcase = AdvancedOpenCaseAction( case_tag='open_freshwater_0', case_type='freshwater', case_name='Wanda', name_path='/data/question1', open_condition=FormActionCondition(type='always'), case_properties={'name': '/data/question1'}, case_indices=[self.case_index], ) self.form.actions.open_cases.append(self.subcase) self.xform = XForm(self.get_xml('original')) path = 'subcase_0/' self.subcase_block = CaseBlock(self.xform, path)
def post(self, request, domain, *args, **kwargs): data = json.loads(request.body.decode('utf-8')) subscription = get_subscription_by_url(domain, data['target_url']) if subscription: # https://zapier.com/developer/documentation/v2/rest-hooks/ # Generally, subscription URLs should be unique. # Return a 409 status code if this criteria isn't met (IE: there is a uniqueness conflict). return HttpResponse(status=409) if data['event'] == EventTypes.NEW_FORM: application = Application.get(data['application']) if not application or not application.get_forms_by_xmlns( data['form']): return HttpResponse(status=400) subscription = ZapierSubscription.objects.create( domain=domain, user_id=str(request.couch_user.get_id), event_name=data['event'], url=data['target_url'], application_id=data['application'], form_xmlns=data['form'], ) elif data['event'] in CASE_TYPE_REPEATER_CLASS_MAP: subscription = ZapierSubscription.objects.create( domain=domain, user_id=str(request.couch_user.get_id), event_name=data['event'], url=data['target_url'], case_type=data['case_type'], ) else: return HttpResponseBadRequest() # respond with the ID so that zapier can use it to unsubscribe return json_response({'id': subscription.id})
def setUp(self): super().setUp() self.client = Client() self.domain = Domain(name='fandango', is_active=True) self.domain.save() # DATA_FORWARDING is on PRO and above, # which is needed by test_add_repeater self.setup_subscription(self.domain.name, SoftwarePlanEdition.PRO) self.username = '******' self.password = '******' self.user = WebUser.create(self.domain.name, self.username, self.password, None, None, is_admin=True) self.user.eula.signed = True self.user.save() self.app = Application.new_app(domain='fandango', name="cheeto") self.app.save()
def test_tiered_select_with_advanced_module_as_parent(self): app = Application.new_app('domain', "Untitled Application", application_version=APP_V2) parent_module = app.add_module( AdvancedModule.new_module('parent', None)) parent_module.case_type = 'parent' parent_module.unique_id = 'id_parent_module' child_module = app.add_module( Module.new_module("Untitled Module", None)) child_module.case_type = 'child' child_module.parent_select.active = True # make child module point to advanced module as parent child_module.parent_select.module_id = parent_module.unique_id child_form = app.new_form(1, "Untitled Form", None) child_form.xmlns = 'http://id_m1-f0' child_form.requires = 'case' self.assertXmlPartialEqual(self.get_xml('advanced_module_parent'), app.create_suite(), "./entry[1]")
def test_case_list_lookup_w_name(self, *args): action = "callout.commcarehq.org.dummycallout.LAUNCH" image = "jr://file/commcare/image/callout" name = "ιтѕ α тяαρ ʕ •ᴥ•ʔ" app = Application.new_app('domain', 'Untitled Application') module = app.add_module(Module.new_module('Untitled Module', None)) module.case_type = 'patient' module.case_details.short.lookup_enabled = True module.case_details.short.lookup_action = action module.case_details.short.lookup_image = image module.case_details.short.lookup_name = name expected = """ <partial> <lookup name="{}" action="{}" image="{}"/> </partial> """.format(name, action, image) self.assertXmlPartialEqual( expected, app.create_suite(), "./detail/lookup" )
def test_case_detail_tabs_with_nodesets_for_sorting(self): app = Application.wrap(self.get_json("app_case_detail_tabs_with_nodesets")) app.modules[0].case_details.long.sort_nodeset_columns = True xml_partial = """ <partial> <field> <header width="0"> <text/> </header> <template width="0"> <text> <xpath function="gender"/> </text> </template> <sort direction="ascending" order="1" type="string"> <text> <xpath function="gender"/> </text> </sort> </field> </partial>""" self.assertXmlPartialEqual( xml_partial, app.create_suite(), './detail[@id="m0_case_long"]/detail/field/template/text/xpath[@function="gender"]/../../..')
def handle(self, *args, **options): # todo: would be nice if this worked off remote servers too if len(args) != 2: raise CommandError('Usage: %s\n%s' % (self.args, self.help)) app_id, path = args # setup directory if not os.path.exists(path): os.mkdir(path) app = Application.get(app_id) for module_index, module in enumerate(app.get_modules()): module_dir_name = '{index} - {name}'.format( index=module_index, name=unicode_slug(module.default_name())) module_dir = os.path.join(path, module_dir_name) if not os.path.exists(module_dir): os.mkdir(module_dir) for form_index, form in enumerate(module.get_forms()): form_name = ('{index} - {name}.xml'.format( index=form_index, name=unicode_slug(form.default_name()))) form_path = os.path.join(module_dir, form_name) with open(form_path, 'w') as f: f.write(form.source.encode('utf-8')) print 'wrote {}'.format(form_path)
def test_app_icon_permissions(self): LOGO_HOME = u'hq_logo_android_home' LOGO_LOGIN = u'hq_logo_android_login' advanced_sub = self._subscribe_to_advanced() with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-standard.json')) as f: standard_source = json.load(f) with open(os.path.join(os.path.dirname(__file__), 'data', 'app-commcare-icon-build.json')) as f: build_source = json.load(f) app_standard = Application.wrap(standard_source) app_standard.save() self.assertEqual(self.project.name, app_standard.domain) app_build = Application.wrap(build_source) app_build.save() self.assertEqual(self.project.name, app_build.domain) self.assertTrue(LOGO_HOME in app_standard.logo_refs.keys()) self.assertTrue(LOGO_LOGIN in app_standard.logo_refs.keys()) self.assertTrue(LOGO_HOME in app_build.logo_refs.keys()) self.assertTrue(LOGO_LOGIN in app_build.logo_refs.keys()) advanced_sub.cancel_subscription(web_user=self.admin_user.username) app_standard = Application.get(app_standard._id) app_build = Application.get(app_build._id) self.assertFalse(LOGO_HOME in app_standard.logo_refs.keys()) self.assertFalse(LOGO_LOGIN in app_standard.logo_refs.keys()) self.assertFalse(LOGO_HOME in app_build.logo_refs.keys()) self.assertFalse(LOGO_LOGIN in app_build.logo_refs.keys()) self._subscribe_to_advanced() app_standard = Application.get(app_standard._id) app_build = Application.get(app_build._id) self.assertTrue(LOGO_HOME in app_standard.logo_refs.keys()) self.assertTrue(LOGO_LOGIN in app_standard.logo_refs.keys()) self.assertTrue(LOGO_HOME in app_build.logo_refs.keys()) self.assertTrue(LOGO_LOGIN in app_build.logo_refs.keys())
def setUpClass(cls): super(DBAccessorsTest, cls).setUpClass() cls.project = Domain(name=cls.domain) cls.project.save() cls.first_saved_version = 2 cls.apps = [ # .wrap adds lots of stuff in, but is hard to call directly # this workaround seems to work Application.wrap( Application(domain=cls.domain, name='foo', version=1, modules=[Module()]).to_json()), RemoteApp.wrap( RemoteApp(domain=cls.domain, version=1, name='bar').to_json()), ] for app in cls.apps: app.save() cls.decoy_apps = [ # this one is a build Application( domain=cls.domain, copy_of=cls.apps[0].get_id, version=cls.first_saved_version, has_submissions=True, ), # this one is another build Application(domain=cls.domain, copy_of=cls.apps[0].get_id, version=12), # this one is another app Application(domain=cls.domain, copy_of='1234', version=12), # this one is in the wrong domain Application(domain='decoy-domain', version=5) ] for app in cls.decoy_apps: app.save()
def setUpClass(cls): super(DBAccessorsTest, cls).setUpClass() cls.project = Domain.get_or_create_with_name(cls.domain, is_active=True) cls.first_saved_version = 2 cls.normal_app = Application.wrap( Application(domain=cls.domain, name='foo', version=1, modules=[Module()]).to_json() ) cls.normal_app.save() cls.remote_app = RemoteApp.wrap(RemoteApp(domain=cls.domain, version=1, name='bar').to_json()) cls.remote_app.save() cls.linked_app = LinkedApplication.wrap( LinkedApplication(domain=cls.domain, version=1, name='linked-app', upstream_app_id='abc123').to_json() ) cls.linked_app.save() cls.decoy_apps = [ # this one is a build Application( domain=cls.domain, copy_of=cls.normal_app.get_id, version=cls.first_saved_version, has_submissions=True, ), # this one is another build Application(domain=cls.domain, copy_of=cls.normal_app.get_id, version=12), # this one is another app Application(domain=cls.domain, copy_of='1234', version=12), # this one is in the wrong domain Application(domain='decoy-domain', version=5) ] for app in cls.decoy_apps: app.save()
def setUpClass(cls): delete_all_users() cls.report_id = '7b97e8b53d00d43ca126b10093215a9d' cls.report_config_uuid = 'a98c812873986df34fd1b4ceb45e6164ae9cc664' cls.domain = 'report-filter-test-domain' cls.user = create_restore_user( domain=cls.domain, username='******', ) update_toggle_cache(MOBILE_UCR.slug, cls.domain, True, NAMESPACE_DOMAIN) report_configuration = cls.make_report_config(cls.domain, cls.report_id) cls.report_configs_by_id = {cls.report_id: report_configuration} cls.app = Application.new_app(cls.domain, "Report Filter Test App") module = cls.app.add_module( ReportModule.new_module("Report Module", 'en')) module.report_configs.append( ReportAppConfig( report_id=cls.report_id, header={}, description="", graph_configs={ '7451243209119342931': ReportGraphConfig(series_configs={'count': {}}) }, filters={ 'computed_owner_name_40cc88a0_1': MobileSelectFilter(), 'fav_fruit_abc123_1': MobileSelectFilter() }, uuid=cls.report_config_uuid, )) with mock_report_configurations(cls.report_configs_by_id): cls.suite = cls.app.create_suite() cls.data = [ { 'color_94ec39e6': 'red', 'count': 2, 'computed_owner_name_40cc88a0': 'cory', 'fav_fruit_abc123': 'c' }, { 'color_94ec39e6': 'black', 'count': 1, 'computed_owner_name_40cc88a0': 'ctsims', 'fav_fruit_abc123': 'b' }, { 'color_94ec39e6': 'red', 'count': 3, 'computed_owner_name_40cc88a0': 'daniel', 'fav_fruit_abc123': 'b' }, ] with mock_report_data(cls.data): with mock_report_configuration_get(cls.report_configs_by_id): with mock.patch( 'corehq.apps.app_manager.fixtures.mobile_ucr.get_apps_in_domain', lambda domain, include_remote: [cls.app]): with mock_sql_backend(): with mock_datasource_config(): fixture, = call_fixture_generator( report_fixture_generator, cls.user) cls.fixture = ElementTree.tostring(fixture)
def construct_form(cls): app = Application.new_app('domain', 'New App') app.add_module(Module.new_module('New Module', lang='en')) form = app.new_form(0, 'MySuperSpecialForm', lang='en') return form
def setUp(self): self.app = Application.new_app('domain', 'New App') self.app.version = 3
def setUp(self): self.app = Application.wrap(self.get_json('gps'))
def test_subcase_repeat(self): self.app = Application.wrap(self.get_json('complex-case-sharing')) self.assertXmlEqual(self.app.get_module(0).get_form(0).render_xform(), self.get_xml('complex-case-sharing'))
def test_parent_ref(self): self.app = Application.wrap(self.get_json('subcase-parent-ref')) self.assertXmlEqual(self.app.get_module(1).get_form(0).render_xform(), self.get_xml('subcase-parent-ref'))
def test_subcase_multiple_repeats(self): self.app = Application.wrap(self.get_json('multiple_subcase_repeat')) self.assertXmlEqual(self.app.get_module(0).get_form(0).render_xform(), self.get_xml('multiple_subcase_repeat'))
def test_subcase_repeat_sharing(self): self.app = Application.wrap(self.get_json('subcase-repeat')) self.app.case_sharing = True self.assertXmlEqual(self.app.get_module(0).get_form(0).render_xform(), self.get_xml('subcase-repeat-sharing'))